進擊webpack 4 (基礎篇一)
進擊webpack4 (基礎篇二:配置 一)
進擊webpack4 (基礎篇三:配置 二)css
noParsehtml
有一些第三方模塊,它自己不依賴於其餘模塊,好比jquery,lodash,不去編譯這些庫,會使得webpack打包更加快速
noParse是個正則或者包含正則的數組 RegExp | [RegExp]vue
module:{ noParse:/jquery/, //不去解析jquery rules:[ //... ] }, ---------------------
ignorePluginnode
以moment這個時間庫爲例, 導入moment的同時, moment會引入自身依賴的語言包,這些語言包其中有部分是咱們不須要用到的,moment內部代碼react
plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) ],
2個參數表明的意思是:jquery
當匹配到moment這個庫的時候 引入moment而且忽略moment裏面匹配到locale的庫webpack
這個時候咱們若是想要本身須要的locale 需在main.js手動引入es6
import 'moment/locale/zh-cn'
另起一個webpack.config.dll.js 專門用來生成動態連接庫web
//webpack.config.dll.js const path=require('path'); const webpack=require('webpack'); module.exports={ mode:'development', entry: { react:['react','react-dom'], jquery:['jquery'] },// 把 React 相關模塊的放到一個單獨的動態連接庫 output: { path: path.resolve(__dirname,'dist'),// 輸出的文件都放到 dist 目錄下 filename: '[name].dll.js',//輸出的動態連接庫的文件名稱,[name] 表明當前動態連接庫的名稱 library: '_dll_[name]',//存放動態連接庫的全局變量名稱,例如對應 react 來講就是 _dll_react }, plugins: [ new webpack.DllPlugin({ // 動態連接庫的全局變量名稱,須要和 output.library 中保持一致 // 該字段的值也就是輸出的 mainfest.json 文件 中 name 字段的值 // 例如 react.manifest.json 中就有 "name": "_dll_react" name: '_dll_[name]', // 描述動態連接庫的 manifest.json 文件輸出時的文件名稱 path: path.join(__dirname, 'dist', '[name].mainfest.json') }) ] }
//打包 npx webpack --config webpack.config.dll.js
這樣會在dist生成npm
而後在webpack.config.js裏
const webpack= require('webpack') plugins: [ new webpack.DllReferencePlugin({ manifest:require('./dist/react.mainfest.json') }), new webpack.DllReferencePlugin({ manifest:require('./dist/jquery.mainfest.json') }) ]
這裏它會從mainfest.json尋找name 而後根據它的標識找到相應內容, dll.js就是打包出來後的動態連接庫
而後在html模板文件裏引入
<script src="./jquery.dll.js"></script> <script src="./react.dll.js"></script>
若是你在main.jsimport React from 'react'
,他會首先找動態連接庫, 找不到纔會執行打包
注:使用react須要配置好rule
{ test:/\.js/, use:{ loader:'babel-loader', options:{ presets:[ '@babel/preset-env', '@babel/preset-react' ] } } },
npm i happypack -D
若是一個項目代碼密集,讀寫操做頻繁,happypack 就能讓Webpack把任務分解給多個子進程去併發的執行,子進程處理完後再把結果發送給主進程。
const HappyPack = require('happypack'); rules: [ { test: /\.js$/, // 把對 .js 文件的處理轉交給 id 爲 babel 的 HappyPack 實例 use: ['happypack/loader?id=babel'], exclude: path.resolve(__dirname, 'node_modules'), }, { test: /\.css$/, // 把對 .css 文件的處理轉交給 id 爲 css 的 HappyPack 實例 use: ['happypack/loader?id=css'] } ] new Happypack({ //ID是標識符的意思,ID用來代理當前的happypack是用來處理一類特定的文件的 id: 'js', use: [{ loader: 'babel-loader', //options=query都是向插件傳遞參數的 options: { presets: [["@babel/preset-env", { modules: false }], "@babel/preset-react"], plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }], ] } }] }), new Happypack({ //ID是標識符的意思,ID用來代理當前的happypack是用來處理一類特定的文件的 id: 'css', use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'], threads: 4,//你要開啓多少個子進程去處理這一類型的文件 verbose: true//是否要輸出詳細的日誌 verbose })
注意:開啓進程也須要時間, 若是一個項目並非很複雜, 斟酌使用
module.exports = { //... externals: { jquery: 'jQuery' } };
main.js 引入jquery 將不會打包 import jquery from 'jQuery'
html模板內引入jquery的cdn地址便可
webpack的tree-shaking本身能夠分析出哪些沒有使用到的代碼能夠剔除,前提是es6模塊語法
scope-hosting能夠提高做用域 好比 var a = 1; var b = a ; console.log(b) 會編譯成var b = 1; console.log(b)
作這種操做首先得是多頁面
entry:{ home:['./src/index.js'], login:['./src/login.js'] }, // 入口文件
//home.js import React from 'react' import {render }from 'react-dom' render(<h1>動態連接庫</h1>,window.root) //login.js import React from 'react' import {render }from 'react-dom' render(<h1>動態連接庫</h1>,window.root)
//webpack.config.js optimization:{ // 優化 splitChunks:{ //分割代碼 cacheGroups:{ // 緩存組 common:{ // 公共的代碼 通常是本身寫的公共代碼 chunks:'initial', minSize:0, minChunks: 2, //最少被引用2次的模塊 name: "common" }, vendor:{ // 通常是第三方公共模塊 priority:1, // 由於執行是從上往下, 因此設置優先級比上面高 否則上面抽離的話第三方模塊也被抽離了 test:/node_modules/ , //匹配node_modules下的公共代碼, chunks:'initial', minSize:0, minChunks: 2, //最少被引用2次的模塊 name: "vendor" } } } }
這裏拿vue舉例
const Login = () => import(/* webpackChunkName: "login" */,"./login"); new VueRouter({ routes: [{ path: "/login", component: Login }] })
webpackChunkName雖然是註釋, 可是webpack能識別, 編譯後這個組件生產的名字就是login
可能會須要@babel/plugin-syntax-dynamic-import 才能識別
yarn add @babel/plugin-syntax-dynamic-import -D
具體配置看此文
devServer:{ // 告訴 DevServer 要開啓模塊熱替換模式 hot: true, }
在vue中只要這樣配置就能夠了, vue本身幫咱們作了配置
其餘庫中:
import React from 'react' import {render} from 'react-dom' render(<App/>, document.getElementById('root')); if (module.hot) { // accept 函數的第一個參數指出當前文件接受哪些子模塊的替換,這裏表示只接受 ./AppComponent 這個子模塊 // 第2個參數用於在新的子模塊加載完畢後須要執行的邏輯 module.hot.accept(['./App'], () => { // 新的 AppComponent 加載成功後從新執行下組建渲染邏輯 let App=require('./App').default; render(<App/>, document.getElementById('root')); }); }