最近和部門老大,一塊兒在研究團隊【EFT - 前端新手村】的建設,目的在於:幫助新人快速瞭解和融入公司團隊,幫助零基礎新人學習和入門前端開發而且達到公司業務開發水平。css
本文也是屬於【EFT - 前端新手村】的一部分,用來幫助新人快速入門 Webpack4
,內容偏基礎,固然也能夠做爲複習材料~~這裏分享給各位小夥伴啦!html
我將從最基礎的【項目初始化】開始介紹,到【處理 CSS / JS / 圖片】,到【熱更新,打包優化】等等,一一介紹和實踐。前端
文章共分爲 18 章,關於最基礎的四個核心概念,能夠到我整理的另外一篇文章 《Webpack4 的四個核心概念》 中學習。node
新建並進入文件夾 leo
:jquery
mkdir leo cd leo
而後本地安裝 webpack
和 webpack-cli
(在 Webpack 4.0之後須要單獨安裝):webpack
npm install webpack webpack-cli --save-dev
初始化項目結構:git
+ ├─package.json + ├─dist // 存放最終打包的文件 + │ └─index.html + ├─src // 存放入口文件等開發文件 + │ └─index.js + ├─webpack.config.js // webpack的配置文件
安裝 lodash
:github
npm install lodash --save-dev
--save
能夠簡寫爲-S
, --save-dev
能夠簡寫爲-D
.web
開發 index.js
:正則表達式
import _ from 'lodash'; function createElement(){ let div = document.createElement('div'); div.innerHTML = _.join(['my', 'name', 'is', 'leo'], ''); return div; } document.body.appendChild(createElement());
開發 webpack.config.js
:
const path = require('path'); module.exports = { entry: './src/index.js', mode: 'development', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') } }
開始第一次打包任務:
npx webpack // 輸出: Hash: 030b37b6b9a0b4344437 Version: webpack 4.39.1Time: 308ms Built at: 2019-08-07 08:10:21 Asset Size Chunks Chunk Names main.js 552 KiB main [emitted] main Entrypoint main = main.js [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built] [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {main} [built][./src/index.js] 225 bytes {main} [built] + 1 hidden module
打包成功後,生成的文件會保存在 dist
目錄中。
如今在 dist/index.html
中引入打包後的 main.js
,打開瀏覽器測試:
<script src="./main.js"></script>
這一部分,咱們開始學着使用 webpack
去處理 css
相關的模塊。
在項目 src
目錄中,新建 style
文件夾,並新建 index.css
文件:
├─package.json ├─dist // 存放最終打包的文件 │ └─index.html ├─src // 存放入口文件等開發文件 │ ├─index.js + │ └─style + │ └─index.css ├─webpack.config.js // webpack的配置文件
接着在 index.js
的新建元素方法中,添加 class
爲 box
,這樣新建的元素就帶有 box
的 class
屬性:
// src/index.js import _ from 'lodash'; import './style/index.css';// 引入樣式文件 function createElement(){ let div = document.createElement('div'); div.innerHTML = _.join(['my', 'name', 'is', 'leo'], ''); + div.className = 'box'; return div; } document.body.appendChild(createElement());
而後在 index.css
文件爲 box
:
// src/style/index.css .box{ color: red; }
注意:
這裏使用 import './style/index.css';
引入咱們的樣式文件,是沒辦法解析使用,這時咱們須要在 webpack
中使用到第三方 loader
插件,這裏咱們使用:
css-loader
: 用於處理 css
文件,使得能在 js 文件中引入使用;style-loader
: 用於將 css
文件注入到 index.html
中的 <style>
標籤上;安裝插件:
npm install --save-dev style-loader css-loader
再到 webpack.config.js
中添加 css
解析的 loader
配置:
// webpack.config.js module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] } ] }
參數介紹:
test
:須要匹配的模塊後綴名;use
:對應處理的 loader 插件名稱(處理順序是從右往左)。
npx webpack // 輸出: Hash: 28b3965aa1b6a0047536 Version: webpack 4.39.1 Time: 482msBuilt at: 2019-08-09 07:45:25 Asset Size Chunks Chunk Names main.js 565 KiB main [emitted] main Entrypoint main = main.js [./node_modules/_css-loader@3.2.0@css-loader/dist/cjs.js!./src/style/index.css] 190 bytes {main} [built] [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built][./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {main} [built][./src/index.js] 303 bytes {main} [built] [./src/style/index.css] 447 bytes {main} [built] + 3 hidden modules
這時候能夠看見 index.html
中,文本已經變成紅色,而且 css
代碼已經添加到 <style>
標籤上。
在這一節中,咱們會介紹 webpack
中的模塊,而且介紹如何去處理 sass
文件。
這裏介紹的模塊(module)是指 webpack.config.js
文件中的 module
配置,它決定了如何處理項目中的不一樣類型模塊。
好比上一節介紹的,使用 style-loader
、 css-loader
兩個插件去處理 css
文件。
webpack
模塊支持以下語句:
import
語句;require()
語句;define
和 require
語句;css/sass/less
文件中 @import
語句;(url(...))
或者 HTML 文件 (<img src=...>)
中的圖片連接 (image url)
;這裏建議使用 ES2015
的引入方法,畢竟這是標準。
更多參數介紹,可訪問中文官網的介紹:
《webpack 配置選項》
值的類型:RegExp | [RegExp] | function
防止 webpack
解析那些符合匹配條件的文件,忽略的文件夾中不該該含有 import
、require
、define
的調用,或任何其餘導入機制,忽略的 library
能夠提升構建效率。
// webpack.config.js module: { noParse: function(content){ return /jquery|lodash/.test(content); } }
建立模塊時,匹配請求的規則數組。按照規則爲對應模塊使用對應的 loader
,或修改解析器(parser)。
// webpack.config.js module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader']} ] }
module.rules
參數有:use
:爲模塊使用指定 loader
,而且能夠傳入一個字符串數組,加載順序從右往左。
module.rules
匹配條件有:{test : Condition}
:匹配特定條件,非必傳,支持一個正則表達式或正則表達式數組; {include : Condition}
:匹配特定條件,非必傳,支持一個字符串或字符串數組; {exclude : Condition}
:排除特定條件,非必傳,支持一個字符串或字符串數組; {and : [Condition]}
:必須匹配數組中的全部條件; {or : [Condition]}
:匹配數組中任一條件; {not : [Condition]}
:必須排除這個條件;
更多參數介紹,可訪問中文官網的介紹:
《Rule》
// webpack.config.js module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'], include: [ path.resolve(__dirname, "app/style.css"), path.resolve(__dirname, "vendor/style.css") ] } ] }
須要使用到 sass-loader
的插件,這裏先安裝:
npm install sass-loader node-sass --save-dev
在 src/style
目錄下添加 leo.scss
文件,並添加內容:
// leo.scss $bg-color: #ee3; .box{ background-color: $bg-color; }
而後在 src/index.js
中引入 leo.scss
文件:
// src/index.js import './style/leo.scss';
再 npx webpack
從新打包,並打開 dist/index.html
能夠看到背景顏色已經添加上去:
像 npx webpack
這個命令咱們須要常用,對於這種命令,咱們能夠把它寫成命令,方便每次使用。
咱們在 package.json
的 scripts
中添加一個命令爲 build
,之後打包只要執行 npm run build
便可:
"scripts": { "build": "npx webpack -c webpack.config.js" },
這裏的 -c webpack.config.js
中,-c
後面跟着的是 webpack
配置文件的文件名,默承認以不寫。
添加 SourceMap
是爲了方便打包以後,咱們在項目中調試樣式,定位到樣式在源文件的位置。
在 css-loader
和 sass-loader
均可以經過設置 options
選項啓用 sourceMap
。
// webpack.config.js rules: [ { test: /\.(sc|c|sa)ss$/, use: [ "style-loader", { loader:"css-loader", options:{ sourceMap: true } }, { loader:"sass-loader", options:{ sourceMap: true } }, ] } ]
再從新打包,看下 index.html
的樣式,樣式已經定位到源文件上了:
這樣咱們在開發過程當中,調試樣式就方便不少了。
這裏咱們用到 PostCSS
這個 loader
,它是一個 CSS 預處理工具,能夠爲 CSS3 的屬性添加前綴,樣式格式校驗(stylelint
),提早使用 CSS
新特性,實現 CSS
模塊化,防止 CSS
樣式衝突。
首先安裝 PostCSS
:
npm install postcss-loader autoprefixer --save-dev
另外還有:
postcss-cssnext
可讓咱們使用 CSS4
的樣式,並能配合 autoprefixer
進行瀏覽器部分兼容的補全,還支持嵌套語法。precss
相似 scss
語法,若是咱們只須要使用嵌套,就能夠用它替換 scss
。postcss-import
讓咱們能夠在@import
CSS文件的時 webpack
能監聽並編譯。更多參數介紹,可訪問中文官網的介紹:
《postcss-loader》
開始添加 postcss-loader
並設置 autoprefixer
:
// webpack.config.js rules: [ { test: /\.(sc|c|sa)ss$/, use: [ "style-loader", { loader:"css-loader", options:{ sourceMap: true } }, { loader:"postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: loader => [ require('autoprefixer')(), // 這裏可使用更多配置,如上面提到的 postcss-cssnext 等 // require('postcss-cssnext')() ] } }, { loader:"sass-loader", options:{ sourceMap: true } }, ] } ]
還須要在 package.json
中添加判斷瀏覽器版本:
// package.json { //... "browserslist": [ "> 1%", // 全球瀏覽器使用率大於1%,最新兩個版本而且是IE8以上的瀏覽器,加前綴 "last 2 versions", "not ie <= 8" ] }
爲了作測試,咱們修改 src/style/leo.scss
中 .box
的樣式:
// src/style/leo.scss .box{ background-color: $bg-color; display: flex; }
而後從新打包,能夠看見 CSS3 屬性的前綴已經添加上去了:
在以前學習中,CSS 樣式代碼都是寫到 index.html
的 <style>
標籤中,這樣樣式代碼多了之後,很不方便。
因而咱們須要將這些樣式打包成單獨的 CSS
文件。
webpack4 開始使用 mini-css-extract-plugin
插件,而在 1-3 版本使用 extract-text-webpack-plugin
。
注意:抽取樣式之後,就不能使用
style-loader
注入到 html 中。
安裝插件:
npm install mini-css-extract-plugin --save-dev
引入插件:
// webpack.config.js const MiniCssExtractPlugin = require('mini-css-extract-plugin');
而後修改 rules
,將 style-loader
,替換成 MiniCssExtractPlugin.loader
,而後添加 plugins
配置項:
// webpack.config.js module: { rules: [ { test: /\.(sc|c|sa)ss$/, use: [ MiniCssExtractPlugin.loader, { loader:"css-loader", options:{ sourceMap: true } }, { loader:"postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: loader => [require('autoprefixer')()] } }, { loader:"sass-loader", options:{ sourceMap: true } }, ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', // 最終輸出的文件名 chunkFilename: '[id].css' }) ]
而後從新打包,這時候能夠看到咱們 dist
目錄下就多了個 main.css
文件:
由於如今已經將 CSS 都抽取成單獨文件,因此在 dist/index.html
中,咱們須要手動引入 main.css
了:
// index.html <link rel="stylesheet" href="main.css">
爲了縮小打包後包的體積,咱們常常作優化的時候,將 CSS 和 JS 文件進行壓縮,這裏須要使用到不一樣的插件。
使用 optimize-css-assets-webpack-plugin
壓縮 CSS 的插件。
安裝插件:
npm install optimize-css-assets-webpack-plugin --save-dev
使用插件:
// webpack.config.js // ... 省略 const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { // ... 省略 plugins: [ // ... 省略 new OptimizeCssAssetsPlugin({}) ], }
從新打包,能夠看到 main.css
已經被壓縮成一行代碼,即壓縮成功~
使用 uglifyjs-webpack-plugin
壓縮 JS 的插件。
安裝插件:
npm install uglifyjs-webpack-plugin --save-dev
引入插件:
// webpack.config.js const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
使用插件:
// webpack.config.js // ... 省略 module.exports = { // ... 省略 plugins: [ // ... 省略 new OptimizeCssAssetsPlugin({}), new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: true }) ], }
其中 UglifyJsPlugin
的參數:
cache
:當 JS 沒有發生變化則不壓縮; parallel
:是否啓用並行壓縮; sourceMap
:是否啓用 sourceMap;
而後從新打包,查看 main.js
,已經被壓縮了:
因爲咱們打包出來的 css
、js
文件是靜態文件,就存在緩存問題,所以咱們能夠給文件名添加 hash
值,防止緩存。
直接在 webpack.config.js
中,爲須要添加 hash 值的文件名添加 [hash]
就能夠:
// webpack.config.js module.exports = { // ... 省略其餘 output: { filename: 'main.[hash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].[hash].css', chunkFilename: '[id].[hash].css' }), ], }
配置完成後,從新打包,就能夠看到文件名中包含了 hash
值了:
因爲咱們前面給打包的文件名添加了 hash
值,會致使 index.html
引用文件錯誤,因此咱們須要讓它能動態引入打包後的文件。
這裏咱們使用 HtmlWebpackPlugin
插件,它能夠把打包後的 CSS 或者 JS 文件直接引用注入到 HTML 模版中,就不用每次手動修改。
安裝插件:
npm install html-webpack-plugin --save-dev
引入插件:
// webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin');
使用插件:
// webpack.config.js plugins: [ new HtmlWebpackPlugin({ title: "leo study!", // 生成的文件標題 filename: "main.html", // 最終生成的文件名 minify: { // 壓縮選項 collapseWhitespace: true, // 移除空格 removeComments: true, // 移除註釋 removeAttributeQuotes: true, // 移除雙引號 } }) ],
關於 html-webpack-plugin
更多介紹能夠《查看文檔》https://github.com/jantimon/h...。
接着咱們打包之後,能夠看見 dist
目錄下,多了 main.html
的文件,格式化之後,能夠看出,已經動態引入打包後的 CSS 文件和 JS 文件了:
在以前,咱們每次打包都會生成新的文件,而且在添加 hash
值之後,文件名不會出現重複的狀況,致使舊文件的冗餘。
爲了解決這個問題,咱們須要在每次打包以前,將 /dist
目錄清空,再進行打包。
這裏咱們使用 clean-webpack-plugin
插件來實現。
安裝插件:
npm install clean-webpack-plugin --save-dev
引入插件:
// webpack.config.js const CleanWebpackPlugin = require('clean-webpack-plugin');
使用插件:
// webpack.config.js plugins: [ new CleanWebpackPlugin() ],
參數 cleanOnceBeforeBuildPatterns
是表示須要清除的文件夾。
這樣咱們每次打包以前,都會先將 /dist
目錄清空一次,再執行打包。
更多參數介紹,可訪問中文官網的介紹:
《clean-webpack-plugin》
在項目中引入圖片:
// src/style/leo.scss .box{ background-color: $bg-color; display: flex; background: url('./../assets/logo.jpg') }
這時候咱們若是直接打包,會報錯。
咱們須要使用 file-loader
插件來處理文件導入的問題。
安裝插件:
npm install file-loader --save-dev
使用插件:
// webpack.config.js module: { { test: /\.(png|svg|jpg|jpeg|gif)$/, use: ["file-loader"] }] },
從新打包之後,發現 dist
目錄下多了一個如 373e5e0e214390f8aa9e7abb4c7c635c.jpg
名稱的文件,這就是咱們打包後的圖片。
更進一步,咱們能夠對圖片進行壓縮和優化,這裏咱們用到 image-webpack-loader
插件來處理。
安裝插件:
npm install image-webpack-loader --save-dev
使用插件:
// webpack.config.js module: { { test: /\.(png|svg|jpg|jpeg|gif)$/, include: [path.resolve(__dirname, 'src/')], use: ["file-loader",{ loader: "image-webpack-loader", options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false }, webp: { quality: 75 } } }, ] }] },
更多參數介紹,可訪問中文官網的介紹:
《image-webpack-loader》
再從新打包,咱們能夠看到圖片打包先後,壓縮了很大:
url-loader
功能相似於 file-loader
,能夠將 url 地址對應的文件,打包成 base64 的 DataURL,提升訪問效率。
安裝插件:
npm install url-loader --save-dev
使用插件:
注意:這裏須要將前面配置的image-webpack-loader
先刪除掉,在使用url-loader
。
// webpack.config.js module: { { test: /\.(png|svg|jpg|jpeg|gif)$/, include: [path.resolve(__dirname, 'src/')], use: [ { loader: 'url-loader', // 根據圖片大小,把圖片轉換成 base64 options: { limit: 10000 }, }, { loader: "image-webpack-loader", options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false }, webp: { quality: 75 } } }, ] }] },
更多參數介紹,可訪問中文官網的介紹:
《url-loader》
字體處理的方式和圖片處理方式是同樣的,只是咱們在配置 rules
時的 test
值不相同:
// webpack.config.js module: { { test: /\.(woff|woff2|eot|ttf|otf)$/, include: [path.resolve(__dirname, 'src/')], use: [ 'file-loader' ] } },
在開發環境(development)和生產環境(production)配置文件有不少不一樣,但也有部分相同,爲了避免每次更換環境的時候都修改配置,咱們就須要將配置文件作合併,和提取公共配置。
咱們使用 webpack-merge
工具,將兩份配置文件合併。
安裝插件:
npm install webpack-merge --save-dev
而後調整目錄結構,爲了方便,咱們將原來 webpack.config.js
文件修更名稱爲 webpack.commen.js
,並複製兩份相同的文件出來,分別修改文件名爲 webpack.prod.js
和 webpack.dev.js
。
├─package.json ├─dist ├─src - ├─webpack.config.js + ├─webpack.common.js // webpack 公共配置文件 + ├─webpack.prod.js // webpack 生產環境配置文件 + ├─webpack.dev.js // webpack 開發環境配置文件
因爲咱們文件調整了,因此在 package.json
中,打包命令也須要調整,而且配置 mode
模式。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "npx webpack -c webpack.config.js", + "build": "npx webpack -c webpack.dev.js --mode development", + "dist": "npx webpack -c webpack.prod.js --mode production" },
咱們先調整 webpack.common.js
文件,將通用的配置保留,不是通用的配置刪除,結果以下:
// webpack.common.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: './src/index.js', module: { noParse: function (content) {return /jquery|lodash/.test(content);}, rules: [ { test: /\.(png|svg|jpg|jpeg|gif)$/, include: [path.resolve(__dirname, 'src/')], use: [{ loader: 'url-loader', // 根據圖片大小,把圖片轉換成 base64 options: { limit: 10000 }, },{ loader: "image-webpack-loader", options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false }, webp: { quality: 75 } } }] },{ test: /\.(woff|woff2|eot|ttf|otf)$/, include: [path.resolve(__dirname, 'src/')], use: [ 'file-loader' ] }] }, plugins: [ new HtmlWebpackPlugin({ title: "leo study!", filename: "main.html", template: path.resolve(__dirname, 'src/index.html'), minify: { collapseWhitespace: true, removeComments: true, removeAttributeQuotes: true, } }), new CleanWebpackPlugin() ], }
安裝 babel-loader
是爲了將 ES6 及以上版本的 JS 代碼轉換成 ES5。
npm install babel-loader @babel/core @babel/preset-env --save-dev
使用插件:
// webpack.common.js rules: [ // ... 省略其餘 { test: /\.js$/, use: [{ loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } }], exclude: /(node_modules|bower_components)/, } ]
關於 babel-loader
更多介紹能夠《查看文檔》https://webpack.js.org/loader...。
這裏咱們就須要用到 merge-webpack
插件進行配置合併了:
// webpack.dev.js const path = require('path'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); let devConfig = { mode: 'development', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [{ test: /\.(sc|c|sa)ss$/, use: [ 'style-loader', { loader: "css-loader", options: { sourceMap: true } }, { loader: "postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: loader => [ require('autoprefixer')() ] } }, { loader: "sass-loader", options: { sourceMap: true } } ] }] } } module.exports = merge(common, devConfig)
一樣對於生產環境的配置,咱們也須要用 merge-webpack
插件進行配置合併:
// webpack.prod.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); let prodConfig = { mode: 'production', output: { filename: 'main.[hash].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [{ test: /\.(sc|c|sa)ss$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { sourceMap: true } }, { loader: "postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: loader => [ require('autoprefixer')() ] } }, { loader: "sass-loader", options: { sourceMap: true } } ] }] }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].[hash].css', chunkFilename: '[id].[hash].css' }), new OptimizeCssAssetsPlugin({}), new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: true }), ], } module.exports = merge(common, prodConfig)
當 webpack 打包源代碼後,就很難追蹤到錯誤和警告在源代碼的位置。
如將三個源文件打包一個 bundle
中,其中一個文件的代碼報錯,那麼堆棧追中就會指向 bundle
。
爲了能方便定位錯誤,咱們使用 inline-source-map
選項,注意不要在生產環境中使用。
// webpack.dev.js let devConfig = { // ... 省略其餘 + devtool: 'inline-source-map' }
爲了測試是否成功,咱們將 src/index.js
代碼中,在第 12 行上,添加一句日誌打印。
// src/index.js // ... 省略其餘 + console.log(111)
對比下開啓 sourceMap
先後的區別:
若是每次咱們修改完代碼,都要手動編譯,那是多累的一件事。
爲此咱們使用 --watch
命令,讓咱們每次保存完,都會自動編譯。
爲此,咱們須要在 package.json
中的打包命令添加 --watch
命令:
// package.json - "build": "npx webpack --config webpack.dev.js", + "build": "npx webpack --config webpack.dev.js --watch",
這裏僅對開發環境開啓,生產環境不須要使用。
上一節介紹監控自動編譯,當咱們保存文件後,會自動編譯文件,可是咱們仍是須要手動去刷新頁面,才能看到編譯後的結果。
因而爲了自動編譯以後,再自動從新加載,咱們就可使用 webpack-dev-server
來啓動一個簡單 web 服務器,實時從新加載。
插件安裝:
npm install webpack-dev-server --save-dev
使用插件:
// webpack.dev.js const webpack = require('webpack'); const webpack = require('webpack'); let devConfig = { // ... 省略其餘 devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, hot: true, overlay: true, open:true, publicPath: '/', host: 'localhost', port: '1200' } plugins: [ new webpack.NamedModulesPlugin(), // 更容易查看(patch)的以來 new webpack.HotModuleReplacementPlugin() // 替換插件 ] }
啓動熱更新:
npx webpack-dev-server --config webpack.dev.js
經常使用配置:
contentBase: path.join(__dirname, 'dist'), //本地服務器所加載的頁面所在的目錄 clinetLogLevel: 'warning', // 可能值有 none, error, warning 或者 info (默認值) hot:true,//啓動熱更新替換特性,須要配合 webpack.HotModuleReplacementPlugin 插件 host:'0.0.0.0', // 啓動服務器的 host port:7000, // 端口號 compress:true, // 爲全部服務啓用gzip壓縮 overlay: true, // 在瀏覽器中顯示全屏覆蓋 stats: "errors-only" ,// 只顯示包中的錯誤 open:true, // 啓用「打開」後,dev服務器將打開瀏覽器。 proxy: { // 設置代理 "/api": { target: "http://localhost:3000", pathRewrite: {"^/api" : ""} } }
這時候咱們訪問 http://localhost:1200/main.html
就能夠看到頁面,而且修改文件,頁面也會同時刷新。
咱們能夠將 npx webpack-dev-server --config webpack.dev.js
寫到 package.json
中做爲一個命令:
// package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "npx webpack --config webpack.dev.js --watch", "dist": "npx webpack --config webpack.prod.js", + "watch": "npx webpack-dev-server --config webpack.dev.js" },
接着上一節,接下來給 webpack 設置代理服務器:
// webpack.dev.js let devConfig = { // ... 省略其餘 devServer: { // ... 省略其餘 proxy: { "/api": { // 以 '/api' 開頭的請求,會跳轉到下面的 target 配置 target: "http://192.168.30.33:8080", pathRewrite: { "^api": "/mock/api" } } } }
最後當咱們請求 /api/getuser
接口,就會轉發到 http://192.168.30.33:8080/mock/api
。
babel-loader
插件的安裝,已經提早介紹,在【11、 webpack 配置合併和提取公共配置】中。
這裏講一下 babel-loader
的優化。
babel-loader
能夠配置 cacheDirectory
來提升打包效率:
cacheDirectory
:默認值 false
,開啓後構建時會緩存文件夾,後續從緩存中讀取,將提升打包效率。安裝插件:
npm install eslint eslint-loader --save-dev
另外還須要安裝 eslint 解釋器、校驗規則等:
npm install babel-loader standard --save-dev
在項目根目錄建立 .eslintrc.js
,指定 eslint 規則。
這份配置內容有點多,能夠去 個人 gist 複製https://gist.github.com/pinga... 。
在項目根目錄建立 .eslintignore
,指定 eslint 忽略一些文件不校驗,好比內容能夠是:
/dist/ /node_modules/
在 webpack 配置中,咱們使用 resolve
來配置模塊解析方式。
這是很是重要的,好比 import _ from 'lodash'
,實際上是加載解析了 lodash.js
文件。
該配置就是用來設置加載和解析的方式。
在解析過程當中,咱們能夠進行配置:
當咱們引入一些文件時,須要寫很長的路徑,這樣使得代碼更加複雜。
爲此咱們可使用 resolve.alias
,建立 import
或 require
的別名,使模塊引入更加簡單。
使用配置:
// webpack.common.js module.exports = { entry: './src/index.js', + resolve: { + alias: { + '@' : path.resolve(__dirname, 'src/') + } + } // 省略其餘 }
alias
參數的含義:
使用 @
來替代 path.resolve(__dirname, 'src/')
這個路徑,接下來咱們測試看看。
咱們在 src/
目錄下新增 leo.js
:
// leo.js export let name = 'pingan';
再到 src/index.js
中引入:
// index.js import { name } from '@/leo.js';
這樣就能正常引入。
固然,咱們也能夠根據實際狀況,爲不一樣路徑設置不一樣別名:
// webpack.common.js alias: { '@' : path.resolve(__dirname, 'src/') + 'assets' : path.resolve(__dirname, 'src/assets/') }
更多參數介紹,可訪問中文官網的介紹:
《resolve》
resolve.extensions
用來自動解析肯定的擴展,讓咱們在引入模塊的時候,能夠不用設置拓展名,默認值爲:
extensions: [".js", ".json"]
使用配置:
// webpack.common.js import { name } from '@/leo';
當咱們使用 CDN 引入 jquery
時,咱們並不想把它也打包到項目中,咱們就能夠配置 externals
外部拓展的選項,來將這些不須要打包的模塊從輸出的 bundle 中排除:
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
配置 externals
:
// webpack.common.js module.exports = { // ... 省略其餘 + externals: { + jquery: 'jQuery' + }, }
經過上面配置,咱們就不會把不須要打包的模塊打包進來。而且下面代碼正常運行:
import $ from 'jquery'; $('.leo').show();
更多參數介紹,可訪問中文官網的介紹:
《externals》
這裏咱們使用 webpack-bundle-analyzer
插件,來對打包後的文件進行數據分析,歷來找到項目優化的方向。
webpack-bundle-analyzer
使用交互式可縮放樹形圖可視化 webpack 輸出文件的大小。
安裝插件:
npm install webpack-bundle-analyzer --save-dev
這個咱們只有在開發環境中使用。
使用插件:
// webpack.dev.js const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() // ... ] }
配置完成之後,咱們執行 npm run build
打包,打包完成後,會自動打開一個數據報表分析的頁面,地址是 http://127.0.0.1:8888/
:
webpack-bundle-analyzer
將幫助咱們:
咱們常常將報表中區域最大的模塊進行優化!
咱們能夠看出,打包後的項目中 lodash.js
佔了很是大的內存,咱們就針對 lodash.js
進行優化。
咱們將 lodash.js
改成 CDN 引入:
// index.html <script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.js"></script>
而後去設置上一節講到的 externals
:
// webpack.common.js externals: { jquery: 'jQuery', + lodash: '_' },
再打包之後,能夠看到 lodash.js
已經不在包裏面了:
而且打包後的文件,也能正常運行:
更多參數介紹,可訪問中文官網的介紹:
《webpack-bundle-analyzer》
本文是根據 《2019最新Webpack4.0教程4.x 成仙之路》 學習總結下來的學習之路,適合入門,涉及範圍較多,內容比較長,須要能靜下心來學習。
內容若是有誤,歡迎留言指點,我會及時修改。
本文代碼最終託管在個人 github 上,點擊查看。
但願本身的文章會對各位有所幫助,也歡迎各位大佬指點。
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推薦 | https://github.com/pingan8787... |
ES小冊 | js.pingan8787.com |