將多個入口重複加載的公共資源提取出來css
基礎配置html
optimization: {
splitChunks: {
// 默認打包node_modules到venders.js
chunks: 'all'
},
// 將webpack運行時生成代碼打包到runtime.js
runtimeChunk: true
},
複製代碼
webpack.base.config.js提取配置vue
optimization: {
// runtimeChunk: {
// name: "manifest"
// },
splitChunks: {
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0
},
vendor: { // 將第三方模塊提取出來
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10, // 優先
enforce: true
}
}
}
}
複製代碼
optimization參數介紹:node
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
}
}
}
}
複製代碼
在知足下述全部條件時,那些從相同代碼塊和緩存組來的模塊,會造成一個新的代碼塊(譯註:好比,在知足條件下,一個vendoer可能會被分割成兩個,以充分利用並行請求性能)。react
有四個選項能夠用於配置這些條件:webpack
是一種很好的優化網頁或應用的方式。這種方式其實是先把你的代碼在一些邏輯斷點處分離開,而後在一些代碼塊中完成某些操做後,當即引用或即將引用另一些新的代碼塊。這樣加快了應用的初始加載速度,減輕了它的整體體積,由於某些代碼塊可能永遠不會被加載。git
lazy.jsgithub
export default 'lazy loader';
複製代碼
main.js 當點擊按鈕時 再加載lazy.js 輸出裏面內容web
let output = () => {
import('./lazy').then(module => {
console.log(module.default);
});
};
ReactDOM.render(
<div>
<button onClick={output}>點擊</button>
</div>,
document.querySelector('#root')
)
複製代碼
const Login = () => import(/* webpackChunkName: "login" */'./login')
new VueRouter({
routes: [
{ path: '/login', component: Login }
]
})
複製代碼
babel-plugin-syntax-dynamic-import plugin. This is a syntax-only plugin, meaning Babel won’t do any additional transformations. The plugin simply allows Babel to parse dynamic imports so webpack can bundle them as a code split. Your .babelrc should look something like this:{
"presets": [
"react"
],
"plugins": [
"syntax-dynamic-import"
]
}
react-loadable is a higher-order component for loading components with dynamic imports. It handles all sorts of edge cases automatically and makes code splitting simple! Here’s an example of how to use react-loadable:import Loadable from 'react-loadable';
import Loading from './Loading';
const LoadableComponent = Loadable({
loader: () => import('./Dashboard'),
loading: Loading,
})
export default class LoadableDashboard extends React.Component {
render() {
return <LoadableComponent />;
}
}
複製代碼
在webpack4中當mode爲production時默認開啓了Scope Hoisting 可讓webpack打包出來的代碼文件更小、運行更快,它又譯做「做用域提高」。緩存
好處: • 代碼體積更小,由於函數申明語句會產生大量代碼; • 代碼在運行時由於建立的函數做用域更少了,內存開銷也隨之變小
scope.js
export default 'scope hoisting'
複製代碼
main1.js
import scope from './scope';
console.log(scope);
複製代碼
webpack3 配置scope Hoisting
new webpack.optimize.ModuleConcatenationPlugin()
複製代碼
開啓scope hoisting後的代碼
// CONCATENATED MODULE: ./src/scope.js
/* harmony default export */ var scope = ('scope hoisting');
// CONCATENATED MODULE: ./src/main1.js
console.log(scope);
複製代碼
ES6的靜態模塊分析,分析出模塊之間的依賴關係,儘量地把模塊放到同一個函數中。
同時,考慮到 Scope Hoisting 依賴源碼需採用 ES6 模塊化語法,還須要配置 mainFields。由於大部分 Npm 中的第三方庫採用了 CommonJS 語法,但部分庫會同時提供 ES6 模塊化的代碼,爲了充分發揮 Scope Hoisting 的做用,須要增長如下配置
mainFields用於配置第三方模塊使用那個入口文件
module.exports = {
resolve: {
// 針對 Npm 中的第三方模塊優先採用 jsnext:main 中指向的 ES6 模塊化語法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
};
複製代碼
對於採用了非 ES6 模塊化語法的代碼,Webpack 會降級處理不使用 Scope Hoisting 優化