Webpack
本系列文章是本人學習相關知識時所積累的筆記,以記錄自己的學習歷程,也為了方便回顧知識;故文章內容較為隨意簡練,抱著學習目的來的同學務必轉移他處,以免我誤人子弟~
webpack學習筆記
根據微信公眾號的這篇文章:《你配置Webpack 4的方式可能是錯的!》,我配置了一個較完整的webpack學習配置項目,代碼以供參考:Github: learnWebpack
本次學習內容來自簡書的教程,完整步驟可移步簡書原文:《入門Webpack,看這篇就夠了》
優點
- 模塊化開發
- 使用TypeScript
- Scss,less,sass等css預處理器
Webpack?
- 模塊打包機:它做的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),并將其轉換和打包為合適的格式供瀏覽器使用
開始使用
npm init
創建 package.json 文件- 項目安裝:
yarn add webpack --dev
;全局安裝:yarn add webpack
- 創建入口文件 main.js ,指定打包輸出文件 bundle.js ;使用命令行執行 webpack :
webpack app/main.js public/bundle.js
- webpack 指定唯一的入口文件
- 執行時報錯: One CLI for webpack must be installed.此時需要安裝另一個包:webpack-cli (
yarn add webpack-cli --dev
或yarn add webpack-cli
)解決參考;!!注意:webpack 和 webpack-cli 需同時全局安裝或同時項目安裝,否則報錯仍存在- package.json中dependencies和devDependencies的區別:Stack Overflow的回答
- 使用 webpack 配置文件 webpack.config.js ,命令行執行
webpack
即可 - 在 package.json 文件對 scripts 對象進行設置,自定義命令行腳本:
"scripts": {
"start": "webpack"
},
更多關于npm scripts 的信息可移步《阮一峰:npm scripts 使用指南》
- Source Maps:易于調試
- webpack-dev-server:使用webpack構建本地服務器 –
yarn add webpack-dev-server --dev
Loaders
通過使用不同的loader,webpack有能力調用外部的腳本或工具,實現對不同格式的文件的處理,比如說分析轉換scss為css,或者把下一代的JS文件(ES6,ES7)轉換為現代瀏覽器兼容的JS文件,對React的開發而言,合適的Loaders可以把React的中用到的JSX文件轉換為JS文件
- 在webpack.config.js中的modules關鍵字下進行配置
- test:一個用以匹配loaders所處理文件的拓展名的正則表達式(必須),如,
/(\.jsx|\.js)$/
- loader:loader的名稱(必須)
- include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)(可選);
- query:為loaders提供額外的設置選項(可選)
Babel
babel-core
、babel-preset-env
(解析Es6)、babel-preset-react
(解析JSX)
babel-preset-env
代替了之前的babel-preset-es2015,babel-preset-es2016
,可以實現ES6+編譯為ES5import
是 ES6 語法
style-loader
,css-loader
less-loader
less-loader 相關配置:
- 安裝:
yarn add less --dev
,yarn add less-loader --dev
- 配置:
loader: less-loader
轉化 less 文件為 css 文件
Plugins
插件(Plugins)是用來拓展Webpack功能的,它們會在整個構建過程中生效,執行相關的任務。
Loaders和Plugins常常被弄混,但是他們其實是完全不同的東西,可以這么來說,loaders是在打包構建過程中用來處理源文件的(JSX,Scss,Less…),一次處理一個,插件并不直接操作單個文件,它直接對整個構建過程其作用。
Hot Module Replacement
(略)
文章涉及參考資料
知識點
以上是根據《入門Webpack,看這篇就夠了》總結的,接下來將通過慕課網:webpack深入與實戰 和 webpack官網文檔:concepts,總結知識點
- __dirname 是 node 的全局變量,指定項目的絕對路徑
- path.resolve() 方法常用語處理路徑:可以將多個路徑解析為一個規范化的絕對路徑
關于path.resolve() 的解釋查看path.join 與 path.resolve 的區別 和 path.resolve()理解 和 小tips:path的join和resolve的使用區別
- Out of the box, webpack only understands JavaScript and JSON files: webpack 只能識別 js 文件和 json 文件,所以需要 loaders。
webpack 只打包有用代碼
兩個js文件:
// a.js
function aJs(){}
module.exports = aJs;
// b.js
function bJs(){}
module.exports = bJs;
入口文件:
// main.js
const a = require("./a.js");
const b = require("./b.js");
a();
b();
打包后的輸出文件的部分代碼:
// bundle.js
/***/ "./app/a.js":
/*!******************!*\
!*** ./app/a.js ***!
\******************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n\nfunction aJs() {}\nmodule.exports = aJs;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvYS5qcz81ZmE4Il0sIm5hbWVzIjpbImFKcyIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsR0FBVCxHQUFjLENBQUU7QUFDaEJDLE9BQU9DLE9BQVAsR0FBaUJGLEdBQWpCIiwiZmlsZSI6Ii4vYXBwL2EuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBhSnMoKXt9XHJcbm1vZHVsZS5leHBvcnRzID0gYUpzOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./app/a.js\n");
/***/ }),
/***/ "./app/b.js":
/*!******************!*\
!*** ./app/b.js ***!
\******************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n\nfunction bJs() {}\nmodule.exports = bJs;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvYi5qcz81ZTRlIl0sIm5hbWVzIjpbImJKcyIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsR0FBVCxHQUFjLENBQUU7QUFDaEJDLE9BQU9DLE9BQVAsR0FBaUJGLEdBQWpCIiwiZmlsZSI6Ii4vYXBwL2IuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBiSnMoKXt9XHJcbm1vZHVsZS5leHBvcnRzID0gYkpzOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./app/b.js\n");
/***/ }),
/***/ "./app/main.js":
/*!*********************!*\
!*** ./app/main.js ***!
\*********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n\nvar a = __webpack_require__(/*! ./a.js */ \"./app/a.js\");\nvar b = __webpack_require__(/*! ./b.js */ \"./app/b.js\");\n\na();\nb();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvbWFpbi5qcz9mMTYxIl0sIm5hbWVzIjpbImEiLCJyZXF1aXJlIiwiYiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFNQSxJQUFJQyxtQkFBT0EsQ0FBQywwQkFBUixDQUFWO0FBQ0EsSUFBTUMsSUFBSUQsbUJBQU9BLENBQUMsMEJBQVIsQ0FBVjs7QUFFQUQ7QUFDQUUiLCJmaWxlIjoiLi9hcHAvbWFpbi5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGEgPSByZXF1aXJlKFwiLi9hLmpzXCIpO1xyXG5jb25zdCBiID0gcmVxdWlyZShcIi4vYi5qc1wiKTtcclxuXHJcbmEoKTtcclxuYigpO1xyXG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./app/main.js\n");
/***/ })
/******/ });
如果去掉 main.js 對 b.js 模塊的引用:
// main.js
const a = require("./a.js");
// const b = require("./b.js");
a();
// b();
打包的文件變為:
/***/ "./app/a.js":
/*!******************!*\
!*** ./app/a.js ***!
\******************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n\nfunction aJs() {}\nmodule.exports = aJs;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvYS5qcz81ZmE4Il0sIm5hbWVzIjpbImFKcyIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsR0FBVCxHQUFjLENBQUU7QUFDaEJDLE9BQU9DLE9BQVAsR0FBaUJGLEdBQWpCIiwiZmlsZSI6Ii4vYXBwL2EuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBhSnMoKXt9XHJcbm1vZHVsZS5leHBvcnRzID0gYUpzOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./app/a.js\n");
/***/ }),
/***/ "./app/main.js":
/*!*********************!*\
!*** ./app/main.js ***!
\*********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n\nvar a = __webpack_require__(/*! ./a.js */ \"./app/a.js\");\n// const b = require(\"./b.js\");\n\na();\n// b();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvbWFpbi5qcz9mMTYxIl0sIm5hbWVzIjpbImEiLCJyZXF1aXJlIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQU1BLElBQUlDLG1CQUFPQSxDQUFDLDBCQUFSLENBQVY7QUFDQTs7QUFFQUQ7QUFDQSIsImZpbGUiOiIuL2FwcC9tYWluLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgYSA9IHJlcXVpcmUoXCIuL2EuanNcIik7XHJcbi8vIGNvbnN0IGIgPSByZXF1aXJlKFwiLi9iLmpzXCIpO1xyXG5cclxuYSgpO1xyXG4vLyBiKCk7XHJcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./app/main.js\n");
/***/ })
/******/ });
此時的bundle.js 少了 bJs 函數
- 在 webpack v4+ 已經刪除了webpack.optimize.UglifyJsPlugin() 的使用了,要想壓縮 js 代碼,可以設置 webpack 配置文件的 mode 屬性為production
Entry
entry屬性有三種設置方式:
- 字符串
- 數組
- 對象
其中字符串和數組的方式都是對象方式的縮寫罷了
entry 對象形式:
// webpack.config.js
entry: {
<key>: <value>
...
}
其中 key 是輸出的 js文件名;value 為入口文件路徑
entry: {
home: "./app/entry1.js",
about: "./app/entry2.js",
output: {
path: __dirname + "/build",
filename: "[name].js",
},
目錄結構
|-build
home.js
about.js
index.html // 主頁面,手動添加的
entry的數組形式:
// webpack.config.js
entry: ["./app/entry1.js","./app/entry2.js"]
相當于
// webpack.config.js
entry: {
main: ["./app/entry1.js","./app/entry2.js"]
}
這樣做的意義在于:
…to inject multiple dependent files together and graph their dependencies into one “chunk”.
webpack 打包項目會生成 依賴關系圖譜 ,main.js 將兩個入口文件合并,同時也將本該分開的 entry1 和 entry2 的依賴關系圖譜合并為一個依賴關系圖譜
Output
- 主要兩個屬性
filename
和path
- 多入口點
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
Mode
- mode設置不同則有不同的默認配置
Loaders
loaders 可以說是編譯器
三種方式配置 Loaders :
- configuration
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader'},
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
- inline
require('style-loader!css-loader?modules!./styles.css');
- cli
webpack --module-bind jade --module-bind 'css=style!css'
參考文章:Webpack loaders使用
無論何種方式,loaders 的引用是有順序之分的
從下到上、從右到左
- css-loader 處理css中路徑引用等問題
- style-loader 動態把樣式寫入css
- sass-loader scss編譯器
- less-loader less編譯器
- postcss-loader scss再處理
參考文章:webpack進階之loader篇
Plugins
- 引用插件(npm包)
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
- 在 plusins 屬性中實例化
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
Configuration
webpack.config.js
因為是普通的js文件,所以支持一般的js語法,最終導出config對象即可;
支持
- 簡單的config選項
- 多個config輸出
- 多種config語言
Hot Module Replacement
使用webpack-dev-server
啟動本地服務就可以快速使用HMR
智能推薦
webpack
1.初識webpack Webpack簡介 webpack是什么 webpack能干什么 2.五個核心概念 入口(entry) 出口(output) 配置(module) 插件(plugins) 模式(mode) 3.webpack 初體驗 初始化配置 初始化package.json 下載并安裝 webpack 輸入指令 編譯打包應用 1. 創建webpack.config.js文件 2. 運行指...
webpack
webpack 1、entry:入口文件,三種引入入口文件的方式 entry:path.resolve(_dirname, './src/index.js'),//單個入口文件,這種寫法相當于下面第二種寫法 entry:{main:'./src/index.js'}, entry:['./src/index.js','./src/hello.js'], //可以多個入口文件,可以分離app或者作為...
webpack
環境參數: Nodejs 10版本以上 webpack 4.26版本以上 第 1 章:webpack 簡介 1.1 webpack 是什么 webpack 是一種前端資源構建工具,一個靜態模塊打包器(module bundler)。 在 webpack 看來, 前端的所有資源文件(js/json/css/img/less/...)都會作為模塊處理。 它將根據模塊...
webpack
1.webpack是什么? 官方網站:https://webpack.js.org/ 中文網站:https://www.webpackjs.com/ 本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關系圖(dependency graph),其中包含應用程序需要的每個模塊,...
webpack
學習了一篇關于webpack的博客:入門webpack,希望可以和其他小伙伴一起學習 為什么要使用webpack? 在我們開發過程中,為了實現網頁豐富的功能,復雜的JS代碼和一大堆的依賴包隨之而來,wield簡化開發的難度,前端社區涌現了很多好的方法比如: 1.模塊化,讓我們可以把復雜的程序細分為小的文件 2.在js語言基礎上拓展的開發語言TypeScript,使我們能夠實現目前版本的JavaSc...
猜你喜歡
webpack
webpack 一. 基礎 Webpack 是一個模塊打包器。它將根據模塊的依賴關系進行靜態分析,然后將這些模塊按照指定的規則生成對應的靜態資源。 代碼拆分 Webpack 有兩種組織模塊依賴的方式,同步和異步。異步依賴作為分割點,形成一個新的塊。在優化了依賴樹后,每一個異步區塊都作為一個文件被打包。 Loader Webpack 本身只能處理原生的 JavaScript 模塊,但是 loader...
webpack
不需要配置文件打包 webpack4以上版本 webpack-cli --entry ./app.js --output build.js webpack4一下版本 webpack --entry ./app.js --output build.js 命令行直接使用webpack使用的是全局的webpack打包 package.json文件中...
webpack
1. mode 是指 webpack打包的環境: mode有幾個值:"production" | "development" | "none" 區別:如果mode是production,打包后的代碼會被壓縮成一行,不好看出都是什么 把mode設置為development 打包出來的文件就是很多行正常的情況 2. 使用loader打包靜態資...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...