摘要:介紹背景最近和部門老大,一起在研究團隊前端新手村的建設,目的在于幫助新人快速了解和融入公司團隊,幫助零基礎新人學習和入門前端開發并且達到公司業務開發水平。
介紹 1. 背景
最近和部門老大,一起在研究團隊【EFT - 前端新手村】的建設,目的在于:幫助新人快速了解和融入公司團隊,幫助零基礎新人學習和入門前端開發并且達到公司業務開發水平。
本文也是屬于【EFT - 前端新手村】的一部分,用來幫助新人快速入門 Webpack4,內容偏基礎,當然也可以作為復習材料~~這里分享給各位小伙伴啦!
2. 文章概要我將從最基礎的【項目初始化】開始介紹,到【處理 CSS / JS / 圖片】,到【熱更新,打包優化】等等,一一介紹和實踐。
文章共分為 18 章,關于最基礎的四個核心概念,可以到我整理的另一篇文章 《Webpack4 的四個核心概念》 中學習。
3. 教程目錄 一、 項目初始化 1. 初始化 demo新建并進入文件夾 leo:
mkdir leo cd leo
然后本地安裝 webpack 和 webpack-cli (在 Webpack 4.0以后需要多帶帶安裝):
npm install webpack webpack-cli --save-dev
初始化項目結構:
+ ├─package.json + ├─dist // 存放最終打包的文件 + │ └─index.html + ├─src // 存放入口文件等開發文件 + │ └─index.js + ├─webpack.config.js // webpack的配置文件
安裝 lodash:
npm install lodash --save-dev
--save 可以簡寫為-S, --save-dev可以簡寫為-D.
開發 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") } }2. 打包測試
開始第一次打包任務:
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,打開瀏覽器測試:
二、 webpack 處理 CSS 模塊這一部分,我們開始學著使用 webpack 去處理 css 相關的模塊。
1. 修改代碼在項目 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 中的 標簽上;
2. 安裝配置插件安裝插件:
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 代碼已經添加到 標簽上。
三、 webpack 模塊介紹和處理 sass在這一節中,我們會介紹 webpack 中的模塊,并且介紹如何去處理 sass 文件。
1. webpack 模塊介紹這里介紹的模塊(module)是指 webpack.config.js 文件中的 module 配置,它決定了如何處理項目中的不同類型模塊。
比如上一節介紹的,使用 style-loader 、 css-loader 兩個插件去處理 css 文件。
webpack 模塊支持如下語句:
ES2015 import 語句;
CommonJS require() 語句;
AMD define 和 require 語句;
css/sass/less 文件中 @import 語句;
樣式 (url(...)) 或者 HTML 文件 () 中的圖片鏈接 (image url);
這里建議使用 ES2015 的引入方法,畢竟這是標準。
更多參數介紹,可訪問中文官網的介紹:2. 常用模塊 2.1 module.noParse
《webpack 配置選項》
值的類型:RegExp | [RegExp] | function
防止 webpack 解析那些符合匹配條件的文件,忽略的文件夾中不應該含有 import、require、define的調用,或任何其他導入機制,忽略的 library 可以提高構建效率。
// webpack.config.js module: { noParse: function(content){ return /jquery|lodash/.test(content); } }2.2 module.rules
創建模塊時,匹配請求的規則數組。按照規則為對應模塊使用對應的 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") ] } ] }3. 加載 Sass 文件
需要使用到 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 可以看到背景顏色已經添加上去:
4. 添加快捷打包命令像 npx webpack 這個命令我們需要經常使用,對于這種命令,我們可以把它寫成命令,方便每次使用。
我們在 package.json 的 scripts 中添加一個命令為 build,以后打包只要執行 npm run build 即可:
"scripts": { "build": "npx webpack -c webpack.config.js" },
這里的 -c webpack.config.js 中,-c 后面跟著的是 webpack 配置文件的文件名,默認可以不寫。
四、 webpack 開啟 SourceMap 和添加 CSS3 前綴添加 SourceMap 是為了方便打包之后,我們在項目中調試樣式,定位到樣式在源文件的位置。
1. 開啟 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 的樣式,樣式已經定位到源文件上了:
這樣我們在開發過程中,調試樣式就方便很多了。
2. 為樣式添加 CSS3 前綴這里我們用到 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 屬性的前綴已經添加上去了:
五、 webpack 將 CSS 抽取成多帶帶文件在之前學習中,CSS 樣式代碼都是寫到 index.html 的 標簽中,這樣樣式代碼多了以后,很不方便。
于是我們需要將這些樣式打包成多帶帶的 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六、 webpack 壓縮 CSS 和 JS
為了縮小打包后包的體積,我們經常做優化的時候,將 CSS 和 JS 文件進行壓縮,這里需要使用到不同的插件。
1. 壓縮 CSS使用 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 已經被壓縮成一行代碼,即壓縮成功~
2. 壓縮 JS使用 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,已經被壓縮了:
七、webpack 為文件名添加 hash 值由于我們打包出來的 css、js 文件是靜態文件,就存在緩存問題,因此我們可以給文件名添加 hash 值,防止緩存。
1. 添加 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 值了:
2. 動態引用打包后的文件由于我們前面給打包的文件名添加了 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 文件了:
八、 webpack 清理目錄插件在之前,我們每次打包都會生成新的文件,并且在添加 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 目錄清空一次,再執行打包。
更多參數介紹,可訪問中文官網的介紹:九、 webpack 圖片處理和優化 1. 圖片處理
《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 名稱的文件,這就是我們打包后的圖片。
2. 圖片優化更進一步,我們可以對圖片進行壓縮和優化,這里我們用到 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》
再重新打包,我們可以看到圖片打包前后,壓縮了很大:
十、 webpack 圖片 base64 和字體處理 1. 圖片 base64 處理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 } } }, ] }] },
更多參數介紹,可訪問中文官網的介紹:2. 字體處理
《url-loader》
字體處理的方式和圖片處理方式是一樣的,只是我們在配置 rules 時的 test 值不相同:
// webpack.config.js module: { { test: /.(woff|woff2|eot|ttf|otf)$/, include: [path.resolve(__dirname, "src/")], use: [ "file-loader" ] } },十一、 webpack 配置合并和提取公共配置
在開發環境(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" },1. 調整 webpack.common.js
我們先調整 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() ], }2. 安裝 babel-loader
安裝 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...。
3. 調整 webpack.dev.js這里我們就需要用到 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)4. 調整 webpack.prod.js
同樣對于生產環境的配置,我們也需要用 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 監控自動編譯和啟用 js 的 sourceMap 1. 開啟 js 的 sourceMap
當 webpack 打包源代碼后,就很難追蹤到錯誤和警告在源代碼的位置。
如將三個源文件打包一個 bundle 中,其中一個文件的代碼報錯,那么堆棧追中就會指向 bundle。
為了能方便定位錯誤,我們使用 inline-source-map 選項,注意不要在生產環境中使用。
// webpack.dev.js let devConfig = { // ... 省略其他 + devtool: "inline-source-map" }2. 測試 sourceMap
為了測試是否成功,我們將 src/index.js 代碼中,在第 12 行上,添加一句日志打印。
// src/index.js // ... 省略其他 + console.log(111)
對比下開啟 sourceMap 前后的區別:
3. 開啟監控自動編譯如果每次我們修改完代碼,都要手動編譯,那是多累的一件事。
為此我們使用 --watch 命令,讓我們每次保存完,都會自動編譯。
為此,我們需要在 package.json 中的打包命令添加 --watch 命令:
// package.json - "build": "npx webpack --config webpack.dev.js", + "build": "npx webpack --config webpack.dev.js --watch",
這里僅對開發環境開啟,生產環境不需要使用。
十三、 webpack 熱更新上一節介紹監控自動編譯,當我們保存文件后,會自動編譯文件,但是我們還是需要手動去刷新頁面,才能看到編譯后的結果。
于是為了自動編譯之后,再自動重新加載,我們就可以使用 webpack-dev-server 來啟動一個簡單 web 服務器,實時重新加載。
1. 開啟熱更新插件安裝:
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 就可以看到頁面,并且修改文件,頁面也會同時刷新。
2. 優化命令我們可以將 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 設置代理服務器和 babel 轉換及優化 1. 設置代理服務器
接著上一節,接下來給 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。
2. babel 轉換及優化babel-loader 插件的安裝,已經提前介紹,在【十一、 webpack 配置合并和提取公共配置】中。
這里講一下 babel-loader 的優化。
babel-loader 可以配置 cacheDirectory 來提高打包效率:
cacheDirectory:默認值 false,開啟后構建時會緩存文件夾,后續從緩存中讀取,將提高打包效率。
十五、 webpack 開啟 Eslint安裝插件:
npm install eslint eslint-loader --save-dev
另外還需要安裝 eslint 解釋器、校驗規則等:
npm install babel-loader standard --save-dev2. 添加 .eslintrc.js
在項目根目錄創建 .eslintrc.js,指定 eslint 規則。
這份配置內容有點多,可以去 我的 gist 復制https://gist.github.com/pinga... 。
3. 添加 .eslintignore在項目根目錄創建 .eslintignore,指定 eslint 忽略一些文件不校驗,比如內容可以是:
/dist/ /node_modules/十六、 webpack 解析模塊拓展名和別名
在 webpack 配置中,我們使用 resolve 來配置模塊解析方式。
這是非常重要的,比如 import _ from "lodash" ,其實是加載解析了 lodash.js 文件。
該配置就是用來設置加載和解析的方式。
在解析過程中,我們可以進行配置:
1. resolve.alias當我們引入一些文件時,需要寫很長的路徑,這樣使得代碼更加復雜。
為此我們可以使用 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/") }
更多參數介紹,可訪問中文官網的介紹:2. resolve.extensions
《resolve》
resolve.extensions 用來自動解析確定的擴展,讓我們在引入模塊的時候,可以不用設置拓展名,默認值為:
extensions: [".js", ".json"]
使用配置:
// webpack.common.js import { name } from "@/leo";十七、 webpack 配置外部拓展
當我們使用 CDN 引入 jquery 時,我們并不想把它也打包到項目中,我們就可以配置 externals 外部拓展的選項,來將這些不需要打包的模塊從輸出的 bundle 中排除:
配置 externals:
// webpack.common.js module.exports = { // ... 省略其他 + externals: { + jquery: "jQuery" + }, }
通過上面配置,我們就不會把不需要打包的模塊打包進來。并且下面代碼正常運行:
import $ from "jquery"; $(".leo").show();
更多參數介紹,可訪問中文官網的介紹:十八、 webpack 打包分析報表及優化總結 1. 生成報表
《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 將幫助我們:
看清楚我們包內都包含什么模塊;
準確看出每個模塊的組成;
最后優化它!
我們經常將報表中區域最大的模塊進行優化!
2. 通過報表優化項目我們可以看出,打包后的項目中 lodash.js 占了非常大的內存,我們就針對 lodash.js 進行優化。
我們將 lodash.js 改為 CDN 引入:
// index.html
然后去設置上一節講到的 externals:
// webpack.common.js externals: { jquery: "jQuery", + lodash: "_" },
再打包以后,可以看到 lodash.js 已經不在包里面了:
并且打包后的文件,也能正常運行:
更多參數介紹,可訪問中文官網的介紹:參考資料
《webpack-bundle-analyzer》
《Webpack4 中文網》
《2019最新Webpack4.0教程4.x 成仙之路》
總結本文是根據 《2019最新Webpack4.0教程4.x 成仙之路》 學習總結下來的學習之路,適合入門,涉及范圍較多,內容比較長,需要能靜下心來學習。
內容如果有誤,歡迎留言指點,我會及時修改。
本文代碼最終托管在我的 github 上,點擊查看(https://github.com/pingan8787...。
希望自己的文章會對各位有所幫助,也歡迎各位大佬指點。
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推薦 | https://github.com/pingan8787... |
ES小冊 | js.pingan8787.com |
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106732.html
新編html網頁設計從入門到精通共分為21章,全面系統地講解了html的發展歷史及4.0版的新特性、基本概念、設計原則、文件結構、文件屬性標記、用格式標記進行頁面排版、使用圖像裝飾頁面、超鏈接的使用、使用表格組織頁面、使用多媒體美化頁面、創建多框架頁面、動態網頁的制作、使用層疊樣式表(css)美化頁面、javascript語言、數組和字符串以及表達式與程序的流程控制等內容。 本書適合作為培訓學校的...
摘要:微信小程序課程,面向所有具備前端基礎知識的同學閱讀要求讀者需要具備但不限于以下技能更佳一共四部分十五小節,適合七天的訓練營。 ?? 微信小程序課程,面向所有具備前端基礎知識的同學 ?? 閱讀要求 讀者需要具備但不限于以下技能 HTML JavaScript es6更佳 CSS 一共四部分十五小節,適合七天的訓練營。 從現在開始,我假裝你已經掌握了 html、 css以及 ES6...
摘要:微信小程序課程,面向所有具備前端基礎知識的同學閱讀要求讀者需要具備但不限于以下技能更佳一共四部分十五小節,適合七天的訓練營。 ?? 微信小程序課程,面向所有具備前端基礎知識的同學 ?? 閱讀要求 讀者需要具備但不限于以下技能 HTML JavaScript es6更佳 CSS 一共四部分十五小節,適合七天的訓練營。 從現在開始,我假裝你已經掌握了 html、 css以及 ES6...
閱讀 3295·2023-04-26 02:42
閱讀 799·2021-10-09 09:41
閱讀 3241·2021-09-06 15:02
閱讀 760·2019-08-26 10:45
閱讀 487·2019-08-23 15:53
閱讀 746·2019-08-22 18:10
閱讀 556·2019-08-22 18:01
閱讀 3522·2019-08-22 17:34