配套代碼demo: https://github.com/FinGet/web...。博客原文: https://finget.github.io/2019/07/24/webpack4-0/打包多頁面在git倉庫裏,並無單獨寫出來。javascript
初始化:css
yarn init -y
yarn add webpack webpack-cli -D
html
webpack-cli的做用就是讓咱們能在命令行中使用webpack
、npx webpakck
這些指令。
// webpack 是node寫出來,因此要按node的寫法 const path = require('path'); module.exports = { mode: 'development', // 模式 默認值:production [development] entry: './src/index.js', // 打包入口文件 output: { filename: 'bundle.[hash:8].js', // 打包後的文件名 path: path.resolve(__dirname, 'dist') // 這個路徑必須是一個絕對路徑,因此須要用path來解析一下 } }
// src/index.js console.log('hello webpack4.0');
npx webpack
命令直接打包(npm5.2以後支持的語法)。會打包出一個main.js
文件前端
默認支持js模塊化:java
// commonjs // src/a.js module.exports = 'FinGet' // src/index.js let name = require('./a.js'); console.log(name); // 'FinGet'
// ES6 module // src/a.js export default = 'FinGet' // src/index.js import name from './a.js' console.log(name); // 'FinGet'
webpack.config.js
。爲啥叫這個名字呢?// node_modules/webpack-cli/bin/config/config-yargs.js ... module.exports = function(yargs) { yargs .help("help") .alias("help", "h") .version() .alias("version", "v") .options({ config: { type: "string", describe: "Path to the config file", group: CONFIG_GROUP, defaultDescription: "webpack.config.js or webpackfile.js", // 默認名字有兩種 requiresArg: true }, ...
npx webpack --config xxxx.js
package.json
中配置腳本"script": { "build": "webpack --config webpack.config.my.js" },
運行 npm run build
node
package.json
中不設置config文件"script": { "build": "webpack" },
運行 npm run build -- --config webpack.config.my.js
--
不能少!react
(function(modules) { // webpackBootstrap // The module cache 先定義一個緩存 var installedModules = {}; // The require function 配置了一個require方法 function __webpack_require__(moduleId) { // Check if module is in cache 檢查這個模塊是否在緩存中 if (installedModules[moduleId]) { return installedModules[moduleId].exports; } // Create a new module (and put it into the cache) 建立一個新的模塊,並存入緩存 var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.l = true; // Return the exports of the module return module.exports; } // Load entry module and return exports 加載入口模塊 return __webpack_require__(__webpack_require__.s = "./src/index.js"); })({ // key-value key -> 模塊路徑 | value -> 函數 "./src/a.js": (function(module, exports) { eval("module.exports=\"FinGet\";\n\n//# sourceURL=webpack:///./src/a.js?"); }), "./src/index.js": (function(module, exports, __webpack_require__) { eval("let name = __webpack_require__(/*! ./a.js */ \"./src/a.js\");\nconsole.log('hello webpack4.0');\nconsole.log(name);\n\n//# sourceURL=webpack:///./src/index.js?"); }) });
yarn add webpack-dev-server -D
jquery
它會在內存中生成打包文件。webpack
官方文檔: https://webpack.docschina.org/configuration/dev-server/css3
// webpack.config.js // 開發服務器的配置 官方文檔: https://webpack.docschina.org/configuration/dev-server/ devServer: { contentBase: './dist', // 告訴服務器從哪一個目錄中提供內容。只有在你想要提供靜態文件時才須要。 publicPath: './dist', // 將用於肯定應該從哪裏提供 bundle,而且此選項優先。 此路徑下的打包文件可在瀏覽器中訪問。 port: 3000, // 端口 progress: true, // 打包過程 open: true, // 自動打開瀏覽器 compress: true, // 一切服務都啓用 gzip 壓縮 // host: '' , // 指定使用一個 host hot: true, // 啓用 webpack 的 模塊熱替換 功能 依賴於HotModuleReplacementPlugin } plugins: [ // 開啓webpack全局熱更新 new webpack.HotModuleReplacementPlugin() ]
devServer : { proxy: { // 代理 '/api': { target: 'http://localhost:3000', pathRewrite: {'^/api' : ''} } } }
devServer: { // 前端mock數據 不存在跨域 before(app) { app.get('/api/goods', (req, res) => { res.json({ code: 0, list: [ {id:1,name:'蘋果'}, {id:2,name:'香蕉'} ] }) }) } }
yarn add html-webpack-plugin -D
plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname,'./public/index.html'), // 模版路徑 filename: 'index.html', // 打包後的文件名 title: 'webpack4.0', // 顧名思義,設置生成的 html 文件的標題 /** 注入選項。有四個選項值 true, body, head, false true 默認值,script標籤位於html文件的 body 底部body 同 true head script 標籤位於 head 標籤內 false 不插入生成的 js 文件,只是單純的生成一個 html 文件 */ inject: true, // favicon: 'xxx.ico' // 給生成的 html 文件生成一個 favicon minify: { // 壓縮 removeAttributeQuotes: true, // 去掉屬性的雙引號 collapseWhitespace: true // 代碼壓縮成一行 }, hash: true, // hash選項的做用是 給生成的 js 文件一個獨特的 hash 值,該 hash 值是該次 webpack 編譯的 hash 值 cahe: true, // 默認值是 true。表示只有在內容變化時才生成一個新的文件 showErrors: true, // 若是 webpack 編譯出現錯誤,webpack會將錯誤信息包裹在一個 pre 標籤內,屬性的默認值爲 true /** chunks 選項的做用主要是針對多入口(entry)文件。當你有多個入口文件的時候,對應就會生成多個編譯後的 js 文件。那麼 chunks 選項就能夠決定是否都使用這些生成的 js 文件。 chunks 默認會在生成的 html 文件中引用全部的 js 文件,固然你也能夠指定引入哪些特定的文件。 **/ // chunks: ['index','index2'], }) ]
yarn add css-loader style-loader less less-loader -D
在index.js中引入css|less模塊
// src/index.js let name = require('./a.js'); require('./assets/css/index.css'); require('./assets/css/commom.less'); console.log('hello webpack4.0'); console.log(name);
module: { // 模塊 rules: [ // loader的順序 默認是從右往左,從上到下 // css-loader 解析 @import 這種語法的 // style-loader 將css引入html的head中 style標籤 // {test: /\.css$/, use: ['style-loader','css-loader']} {test: /\.(css|less)$/, use: [ { loader: 'style-loader', options: { insertAt: 'top' // 插入頂部 這樣就會被後面的樣式覆蓋 } }, 'css-loader', 'less-loader' ] } ] },
yarn add mini-css-extract-plugin -D
上面打包css會把css文件以style標籤的形式寫入index.html
,如今咱們就來把它們單獨打包成文件。
module: { // 模塊 rules: [ {test: /\.(css|less)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'assets/css/index.css' // 打包到dist/assets/css/index.css }) ]
css3 自動添加各類瀏覽器前綴:
yarn add postcss-loader autoprefixer -D
// postcss.config.js module.exports = { plugins: [require('autoprefixer')({'browsers': ['> 1%', 'last 2 versions']})] } // webpack.config.js module: { // 模塊 rules: [ {test: /\.(css|less)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader' ] } ] },
推薦用法是在package.json
中設置:
Replace Autoprefixer browsers option to Browserslist config.
Use browserslist key in package.json or .browserslistrc file.
// postcss.config.js module.exports = { plugins: [require('autoprefixer')] }
"browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ]
壓縮css:
⚠️壓縮css也要壓縮js,不如js不會壓縮。
yarn add optimize-css-assets-webpack-plugin terser-webpack-plugin -D
// webpack.config.js mode:'production', // * development不會壓縮 optimization: { minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], },
yarn add babel-loader @babel/babel-core @babel/preset-env -D
⚠️@babel/babel-core
和@babel/preset-env
與babel-core
和
babel-preset-env
不同
// webpack.config.js module: { rules: [ { test: /\.js$/, exclude: '/node_modules', include: 'src', use: { loader: 'babel-loader', options: { // 配置預設 presets: [ '@babel/preset-env' ] } } } ] }
或者:
// .babelrc { "presets": ["@babel/preset-env"] }
babel-runtime 是供編譯模塊複用工具函數,是錦上添花。
babel-polyfil是雪中送炭,是轉譯沒有的api。
// 示例 class Person{ constructor(name, age) { this.name = name; this.age = age; } } let person = new Person('FinGet',24); console.log(person.name); // 高級api console.log('FinGet'.includes('Get'));
yarn add @babel/plugin-transform-runtime -D // @babel/runtime as a production dependency (since it's for the "runtime"). yarn add @babel/runtime
使用:
// .babelrc "plugins": ["@babel/plugin-transform-runtime"]
@babel/runtime
會在打包的js中,注入一些腳本,因此要安裝production依賴
yarn add @babel/polyfill
使用:
require("@babel/polyfill"); // or import "@babel/polyfill"; // or // webpack.config.js module.exports = { entry: ["@babel/polyfill", "./app/js"], };
這樣引入會致使打包出來的js很大
按需引入:
// .babelrd { "presets": [["@babel/preset-env", { "useBuiltIns": "usage" }]], }
關鍵點是useBuiltIns
這一配置項,它的值有三種:
false
: 不對polyfills
作任何操做entry
: 根據target
中瀏覽器版本的支持,將polyfills
拆分引入,僅引入有瀏覽器不支持的polyfill
usage
(新):檢測代碼中ES6/7/8等的使用狀況,僅僅加載代碼中用到的polyfills
yarn add eslint eslint-loader -D
在根目錄下生成一個.eslint.json
來配置規則。
{ "parserOptions": { "ecmaVersion": 5, "sourceType": "script", "ecmaFeatures": {} }, "rules": { // 容許console "no-console": "off", // 容許空語句塊 "no-empty": ["error", { "allowEmptyCatch": true }], // 強制關鍵字周圍空格的一致性 (keyword-spacing) "keyword-spacing": "error", // 把 var 語句看做是在塊級做用域範圍以內 "block-scoped-var": "error", // 要求遵循大括號約定 "curly": "error", // switch 要有default分支 "default-case": "error", // no-eq-null 禁止與null進行比較 "no-eq-null": "error", // 禁止使用多個空格 "no-multi-spaces": ["error", {"exceptions": { "Property": true }}], // 禁止多行字符串 "no-multi-str": "error", // 禁止使用 new 以免產生反作用 "no-new": "error", // 數組中的空格 "array-bracket-spacing": ["error", "never"], // 禁止或強制在代碼塊中開括號前和閉括號後有空格 "block-spacing": "error", // 大括號風格要求 "brace-style": ["error", "1tbs", { "allowSingleLine": true }], // 逗號先後使用一致的空格 "comma-spacing": ["error", { "before": false, "after": true }], // 逗號風格 "comma-style": ["error", "last"], // 計算屬性不使用空格 "computed-property-spacing": ["error", "never"], // 函數標識符和其調用之間禁止空格 "func-call-spacing": ["error", "never"], // 箭頭函數函數體的位置 "implicit-arrow-linebreak": ["error", "beside"], // tab縮進 "indent": ["error", "tab", { "SwitchCase": 1 }], // 對象key-value空格 "key-spacing": ["error", { "beforeColon": false }], // 行註釋位置 "line-comment-position": ["error", { "position": "above" }], // 類成員之間須要空行 "lines-between-class-members": ["error", "always"], // 要求構造函數首字母大寫 "new-cap": "error", // 調用無參構造函數時帶括號 "new-parens": "error", // 禁止使用 Array 構造函數 "no-array-constructor": "error", // 禁止使用內聯註釋 "no-inline-comments": "error", // 禁止連續賦值 "no-multi-assign": "error", // 不容許多個空行 "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1 }], // 禁止使用 Object 構造函數 "no-new-object": "error", // 禁用行尾空白 "no-trailing-spaces": "error", // 禁止屬性前有空白 "no-whitespace-before-property": "error", // 強制在花括號內使用一致的換行符 "object-curly-newline": ["error", { "ImportDeclaration": "always", "ExportDeclaration": "always" }], // 花括號中使用一致的空格 "object-curly-spacing": ["error", "never"], // 要求在變量聲明周圍換行 "one-var-declaration-per-line": ["error", "always"], // 禁止塊內填充 "padded-blocks": ["error", "never"], // 語句間填充空行 "padding-line-between-statements": [ "error", { "blankLine": "always", "prev": ["const", "let", "var"], "next": "*"}, { "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]}, { "blankLine": "always", "prev": "directive", "next": "*" }, { "blankLine": "any", "prev": "directive", "next": "directive" } ], // 強制使用一致的反勾號、雙引號或單引號 "quotes": ["error", "single", { "allowTemplateLiterals": true }], // 對象字面量屬性名稱使用引號 "quote-props": ["error", "as-needed"], // 行尾分號 "semi": ["error", "always"], // 分號先後空格 "semi-spacing": ["error", {"before": false, "after": true}], // 分號位置 "semi-style": ["error", "last"], // 語句塊以前的空格 "space-before-blocks": "error", // function空格 "space-before-function-paren": ["error", { "anonymous": "always", "named": "never", "asyncArrow": "always" }], // 禁止圓括號內的空格 "space-in-parens": "error", // 要求中綴操做符周圍有空格 "space-infix-ops": "error", // 要求或禁止在一元操做符以前或以後存在空格 "space-unary-ops": ["error", {"words": true, "nonwords": false}], // 要求或禁止在註釋前有空白 "spaced-comment": ["error", "always"], // 強制在 switch 的冒號左右有空格 "switch-colon-spacing": "error", // 要求正則表達式被包裹起來 "wrap-regex": "error", // ES6 // 要求箭頭函數體使用大括號 "arrow-body-style": "error", // 要求箭頭函數的箭頭以前或以後有空格 "arrow-spacing": "error", // 禁止重複導入 }, "env": {} }
{ test: /\.js$/, loader: ['babel-loader', 'eslint-loader'], } // or { test: /\.js$/, use: { loader: 'eslint-loader', options: { enforce: 'pre' // 先執行 } } }
import jpg from './assets/snail.jpg' let img = new Image(); img.src = jpg document.body.appendChild(img);
body{ background-image: url(../logo.svg); }
<img src="../src/assets/snail.jpg" alt="">
yarn add file-loader -D
file-loader
會默認在內部生成生成一張圖片,到dist目錄下,把生成圖片的名字返回回來
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: 'file-loader' }
html中直接使用img標籤src加載圖片的話,由於沒有被依賴,圖片將不會被打包。
yarn add html-withimg-loader
使用:
{ test: /\.(htm|html)$/i, loader: 'html-withimg-loader' }
若是圖片較多,會發不少http請求,會下降頁面性能。這個問題能夠經過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。至關於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。固然,若是圖片較大,編碼會消耗性能。所以url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。
url-loader和file-loader是什麼關係呢?簡答地說,url-loader封裝了file-loader。url-loader不依賴於file-loader,即便用url-loader時,只須要安裝url-loader便可,不須要安裝file-loader,由於url-loader內置了file-loader。
yarn add url-loader -D
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: { loader: 'url-loader', options: { name: '[name].[ext]', // 保持名稱不變 limit: 20*1024, // 小於20k的圖片 打包成base64 outputPath: 'assets/' // 打包後的存放路徑 dist/assets } } },
此選項指定在瀏覽器中所引用的「此輸出目錄對應的公開 URL」。相對 URL(relative URL) 會被相對於 HTML 頁面(或 <base> 標籤)解析。相對於服務的 URL(Server-relative URL),相對於協議的 URL(protocol-relative URL) 或絕對 URL(absolute URL) 也但是可能用到的,或者有時必須用到,例如:當將資源託管到 CDN 時。
module.exports = { //... output: { path: path.resolve(__dirname, 'dist'), publicPath: 'https://cdn.example.com/assets/' } };
⚠️也能夠單獨給圖片的options下配一個publicPath
生產模式會壓縮代碼成一行,就無法調試了。
... ️mode:'developmen', //production 不會生成map文件 entry: './src/index.js', devtool: "source-map", // 增長映射文件 ...
... entry: entry: './src/index.js', // build 監控,變化自動打包 watch: true, watchOptions: { // 監控選項 poll: 1000, // 每秒 watch 1000次 aggregateTimeout: 500, // 防抖 ignored: '/node_modules/' //不須要監控的文件 }, ...
每次打包以前,都刪除dist目錄下的文件。
yarn add clean-webpack-plugin -D
clean-webpack-plugin: ^3.00
const {CleanWebpackPlugin} = require('clean-webpack-plugin'); plugins: [ new CleanWebpackPlugin() ]
export { CleanWebpackPlugin };//3.0.0導出方式 export default CleanWebpackPlugin;//2.0.2導出方式 因此在2.0.2版本咱們能夠直接require拿到CleanWebpackPlugin const CleanWebpackPlugin = require('clean-webpack-plugin') module.exports = CleanWebpackPlugin;//1.0.1導出方式
他會默認清空咱們output裏面設置的全部文件夾
https://github.com/johnagan/clean-webpack-plugin#options-and-defaults-optional By default, this plugin will remove all files inside webpack's output.path directory, as well as all unused webpack assets after every successful rebuild.
拷貝文件
yarn add copy-webpack-plugin -D
const CopyPlugin = require('copy-webpack-plugin'); plugins: [ new CopyPlugin([ { from: 'src/assets', to: 'assets' } ]), ]
版權聲明
plugins:[ new webpack.BannerPlugin('CopyRight by FinGet!') ] // 會在打包文件頭部加上 /*! CopyRight by FinGet! */
// 配置選項 { banner: string | function, // 其值爲字符串或函數,將做爲註釋存在 raw: boolean, // 若是值爲 true,將直出,不會被做爲註釋 entryOnly: boolean, // 若是值爲 true,將只在入口 chunks 文件中添加 test: string | RegExp | Array, include: string | RegExp | Array, exclude: string | RegExp | Array, }
module.exports = { resolve: { // 解析第三方包 alias: { // 建立 import 或 require 的別名,來確保模塊引入變得更簡單。 '@': path.resolve(__dirname, 'src') }, extensions: ['.js','.css','.json'], // 自動解析肯定的擴展 就是沒有後綴名時,按這個順序匹配 modules: [path.resolve('node_modules')] //告訴 webpack 解析模塊時應該搜索的目錄 }, }
點這裏查看更多配置項。
定義一些全局變量。
module.exports = { plugins: [ new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true), VERSION: JSON.stringify('5fa3b9'), BROWSER_SUPPORTS_HTML5: true, TWO: '1+1', 'typeof window': JSON.stringify('object'), 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }); ] }
注意,由於這個插件直接執行文本替換,給定的值必須包含字符串自己內的實際引號。一般,有兩種方式來達到這個效果,使用 '"production"', 或者使用 JSON.stringify('production')。
分別配置不一樣的環境打包文件。
yarn add webpack-merge -D
// build/webpack.base.conf.js const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: path.resolve(__dirname,'../src/index.js'), // 打包入口文件 output: { filename: 'bundle.[hash:8].js', // 打包後的文件名 path: path.resolve(__dirname, '../dist') // 這個路徑必須是一個絕對路徑,因此須要用path來解析一下 }, module: { // 模塊 rules: [ { test: /\.(css|less)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader' ] }, { test: /\.js$/, loader: 'babel-loader', }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: { loader: 'url-loader', options: { limit: 1, outputPath: 'assets/images' // 打包後的存放路徑 } } }, { test: /\.(htm|html)$/i, loader: 'html-withimg-loader' } ] }, // 配置插件 plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../public/index.html'), // 模版路徑 filename: 'index.html', // 打包後的文件名 title: 'webpack4.0', // 顧名思義,設置生成的 html 文件的標題 inject: true, hash: true, // hash選項的做用是 給生成的 js 文件一個獨特的 hash 值,該 hash 值是該次 webpack 編譯的 hash 值 cahe: true, // 默認值是 true。表示只有在內容變化時才生成一個新的文件 showErrors: true, // 若是 webpack 編譯出現錯誤,webpack會將錯誤信息包裹在一個 pre 標籤內,屬性的默認值爲 true }), new MiniCssExtractPlugin({ filename: 'assets/css/index.css' }) ] }
// build/webpack.pro.cong.js const merge = require('webpack-merge'); const base = require('./webpack.base.conf'); const TerserJSPlugin = require('terser-webpack-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); mmodule.exports = merge(base, { mode: 'production', optimization: { minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], }, plugins: [ // 文件頭部注入 new webpack.BannerPlugin('CopyRight by FinGet!') ] })
// build/webpack.dev.cong.js const merge = require('webpack-merge'); const webpack = require('webpack'); const base = require('./webpack.base.conf'); mmodule.exports = merge(base, { mode: 'development', // 開發服務器的配置 官方文檔: https://webpack.docschina.org/configuration/dev-server/ devServer: { contentBase: path.resolve(__dirname, "../dist"), // 告訴服務器從哪一個目錄中提供內容。只有在你想要提供靜態文件時才須要。 // publicPath: './dist', // 將用於肯定應該從哪裏提供 bundle,而且此選項優先。 此路徑下的打包文件可在瀏覽器中訪問。 port: 3000, // 端口 progress: true, // 打包過程 open: true, // 自動打開瀏覽器 }, devtool: 'source-map', plugins: [ new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify(process.env.NODE_ENV) } }) ], })
yarn run dev -- --config build/webpack.dev.conf.js yarn run build -- --config build/webpack.pro.conf.js
防止 webpack 解析那些任何與給定正則表達式相匹配的文件。
module.exports = { //... module: { noParse: /jquery|lodash/, } };
js、css、img均可以多線程打包,提升打包速度。
yarn add happypack -D
module.exports = { module:{ { test: /\.js$/, use: 'Happypack/loader?id=js' } } plugins:[ new Happypack({ id: 'js', // id與上面對應 use: [{ loader: 'babel-loader', options: { presets:['@babel/preset-env'] } }] }) ] }
(webpack 自帶)把沒用的代碼刪除掉。
import
在生產環境下 會自動去掉沒用的代碼。es6 模塊會把結果放到default
上。
// test.js let sum = (a,b) => { return a+b; } let minus = (a,b) => { return a-b; } export default {sum,minus}
import calc from './test.js'; console.log(calc.add(1,2)); let calc = require('./test'); console.log(calc.default.sum(1,2));
這裏沒用minus
方法,在import
方式打包中會tree-shaking
,require
則不會。
let a = 1; let b = 2; let c = 3; let d = a + b + c; console.log(d);
這個代碼很囉嗦,在打包以後,webpack會自動分析,省略代碼。
// 打包後 console.log(6);
多入口項目,多個入口,引用同一個js/css,則能夠抽離公共代碼。
module.exports = { optimization: { splitChunks: { // 分割代碼塊 cacheGroups: { // 緩存組 common: { // 公共模塊 chunks: 'initial', minSize: 0, minChunks: 2, } } } }, }
// 把第三方模塊單獨打包 好比jquery、lodash module.exports = { optimization: { splitChunks: { // 分割代碼塊 cacheGroups: { // 緩存組 common: { // 公共模塊 chunks: 'initial', minSize: 0, minChunks: 2, }, // 單獨打包第三方模塊 vendor: { priority: 1, // 優先級別 test: /[\\/]node_modules[\\/]/, chunks: 'initial', name(module, chunks, cacheGroupKey) { const moduleFileName = module.identifier().split('/').reduceRight(item => item); return `${moduleFileName}`; }, minSize: 0, minChunks: 2 } } } }, }
optimization參數介紹:
optimization: { splitChunks: { chunks: "initial", // 代碼塊類型 必須三選一: "initial"(初始化) | "all"(默認就是all) | "async"(動態加載) minSize: 0, // 最小尺寸,默認0 minChunks: 1, // 最小 chunk ,默認1 maxAsyncRequests: 1, // 最大異步請求數, 默認1 maxInitialRequests: 1, // 最大初始化請求書,默認1 name: () => {}, // 名稱,此選項課接收 function cacheGroups: { // 緩存組會繼承splitChunks的配置,可是test、priorty和reuseExistingChunk只能用於配置緩存組。 priority: "0", // 緩存組優先級 false | object | vendor: { // key 爲entry中定義的 入口名稱 chunks: "initial", // 必須三選一: "initial"(初始化) | "all" | "async"(默認就是異步) test: /react|lodash/, // 正則規則驗證,若是符合就提取 chunk name: "vendor", // 要緩存的 分隔出來的 chunk 名稱 minSize: 0, minChunks: 1, enforce: true, reuseExistingChunk: true // 可設置是否重用已用chunk 再也不建立新的chunk } } } }
點擊這裏查看更多配置。
在用戶觸發一個點擊操做才加載須要的文件。
// lazy.js export default '懶加載';
// test.js function handleClick() { import('./lazy.js').then(module => { console.log(module.default); }) }
建立了一個前端學習交流羣,感興趣的朋友,一塊兒來嗨呀!