(a)轉換ES6語法css
(b)轉換JSXhtml
(c)CSS前綴補全/預處理器node
(d)壓縮混淆react
(e)圖片壓縮webpack
(a)stats:構建的統計信息
(b)package.json中使用statusweb
1 "scripts": { 2 "build:stats": "webpack ---env production --json > stats.json" 3 ... 4 } 正則表達式
(c)Node API中使用算法
1 const webpack = require('webpack'); 2 const config = require('./webpack.config.js')("production"); 3 4 webpack(config, (err, stats) => { 5 if (err) { 6 return console.error(err); 7 } 8 if (stats.hasErrors()) { 9 return console.error(stats.toString("errors-only")) 10 } 11 console.log(stats); 12 })
1 const speedMeasurePlugin = require("speed-measure-webpack-plugin"); 2 const smp = new SpeedMeasurePlugin(); 3 4 const webpackConfig = smp.wrap({ 5 plugins: { 6 new MyPlugin(), 7 new MyOtherPlugin() 8 } 9 }) 10 // 能夠看到每一個loader和插件執行耗時
1 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 2 module.exports = { 3 plugins: { 4 new BundleAnalyzerPlugin() 5 } 6 } 7 // 構建完成後會在8888端口展現各個打包後文件的大小
(a)使用webpack4json
(b)多進程/多實例構建redux
(c)分包
(d)緩存
(e)縮小構建目標
(a)V8帶來的優化(for of替代forEach、Map和Set替代Object、includes替代indexOf)
(b)默認使用更快的md4 hash算法
(c)webpacks AST能夠直接從loader傳遞給AST,減小解析時間
(d)使用字符串方法替代正則表達式
原理:每次webpack解析一個模塊,HappyPack會將它及它的依賴分配給worker線程中
1 exports.plugins = { 2 new HappyPack({ 3 id: 'jsx', 4 threads: 4, // 固定線程數,可是不建議 5 loaders: ['babel-loader'] 6 }), 7 new HappyPack({ 8 id: 'styles', 9 threads: 2, // 固定線程數,可是不建議 10 loaders: ['style-loader', 'css-loader', 'less-loader'] 11 }) 12 }
方法一:使用parallel-uglify-plugin插件(webpack3使用)
1 const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin'); 2 module.exports = { 3 plugins: [ 4 new ParallelUglifyPlugin({ 5 uglifyJS: { 6 output:{ 7 beautity: false, 8 comments: false, 9 }, 10 compress: { 11 warnings: false, 12 drop_console: true, 13 collapse_vars: true, 14 reduce_vars: true 15 } 16 } 17 }) 18 ] 19 }
方法二:使用uglifyjs-webpack-plugin開啓parallel參數(webpack4使用)
1 const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 2 module.exports = { 3 plugins: [ 4 new UglifyJsPlugin({ 5 uglifyOptions: { 6 warnings: false, 7 parse: {}, 8 compress: {}, 9 mangle: true, 10 output: null, 11 toplevel: false, 12 nameCache: null, 13 ie8: false, 14 keep_fnames: false 15 }, 16 parallel: true 17 }) 18 ] 19 }
思路:將react、react-dom基礎包經過cdn引入,不打入bundle中
方法:使用html-webpack-externals-plugin
1 const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin'); 2 plugins: [ 3 new HtmlWebpackExternalsPlugin({ 4 external: [ 5 { 6 module: 'react', 7 entry: '........./react-with-addons.min.js?_bid=313', 8 global: 'React' 9 }, 10 { 11 module: 'react-dom', 12 entry: '........./react-dom.min.js?_bid=313', 13 global: 'ReactDOM' 14 } 15 ] 16 }) 17 ]
思路:將react、react-dom、redux、react-redux基礎包和業務基礎包打包成一個文件。
方法:使用DLLPlugin進行分包,DllReferencePlugin對manifest.json引用
1 module.exports = { 2 plugins: [ 3 new webpack.DllPlugin({ 4 name: '[name]', 5 path: './build/library/[name].json' 6 }) 7 ] 8 }
目的:提高二次構建速度
方法:使用HardSourceWebpackPlugin或者cache-loader
比較推薦使用HardSourceWebpackPlugin,速度更快
目的:儘量的少構建模塊
好比babel-loader不解析node_modules
1 module.exports = { 2 rules: { 3 test: /\.js$/, 4 loader: 'happypack/loader', 5 exclude: 'node_modules' 6 } 7 }
(a)Scope Hoisting
(b)Tree-shaking
(c)公共資源分離
(d)圖片壓縮
(e)動態Polyfill
原理:將全部模塊的代碼按照引用順序放在一個函數做用域裏,而後適當的重命名一些變量以防止變量名衝突
對比:經過scope hoisting能夠減小函數聲明代碼
1 // 代碼示例: 2 module.exports = { 3 plugins: [ 4 new webpack.opimize.ModuleConcatenationPlugin() 5 ] 6 } 7 // 要求:必須是ES6的語法,CJS的方式不支持
概念:1個模塊可能有多個方法,只要其中的某個方法使用到了,則整個文件都會被打到bundle裏面去,Tree-shaking
就是隻把用到的方法打入bundle,沒用到的方法會在uglify階段被刪掉
使用:webpack默認支持,在.babelrc裏設置modules:false便可
要求:必須是ES6的語法,CJS的方式不支持
目的:提取多頁面公共JS chunk代碼
使用:webpack3使用CommonsChunkPlugin
webpack4使用SplitChunksPlugin
要求:基於Node庫的imagemin或者tinypng API
使用:配置image-webpack-loader