前面的话
前面介绍了webpack的基本配置,本文将详细介绍webpack中关于代码优化的配置
打包公共代码
CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用。这会带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件
new webpack.optimize.CommonsChunkPlugin(options)
【配置项】
{ ?name: string, // or ?names: string[], ?// common chunk 的名称
?filename: string, ?// common chunk 的文件名模板。可以包含与 `output.filename` 相同的占位符 ?minChunks: number|Infinity|function(module, count) -> boolean, ?// 在传入公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks 。 ?// 数量必须大于等于2,或者少于等于 chunks的数量 ?chunks: string[], ?// 通过 chunk name 去选择 chunks 的来源。chunk 必须是 公共chunk 的子模块。
?children: boolean, ?// 如果设置为 `true`,所有公共chunk 的子模块都会被选择 ?deepChildren: boolean, ?// If `true` all descendants of the commons chunk are selected ?async: boolean|string, ?// 如果设置为 `true`,一个异步的公共chunk 会作为 `options.name` 的子模块,和 `options.chunks` 的兄弟模块被创建。 ?minSize: number, ?// 在 公共chunk 被创建立之前,所有公共模块 (common module) 的最少大小。}【提取公共代码】
new webpack.optimize.CommonsChunkPlugin({ ?name: "commons", ?// ( 公共chunk(commnons chunk) 的名称) ?filename: "commons.js", ?// ( 公共chunk 的文件名)})【明确第三方库chunk】
entry: { ?vendor: ["jquery", "other-lib"], ?app: "./entry"},plugins: [ ?new webpack.optimize.CommonsChunkPlugin({ ???name: "vendor", ???minChunks: Infinity, ?})]【将公共模块打包进父 chunk】
new webpack.optimize.CommonsChunkPlugin({ ?children: true,})【额外的异步公共chunk】
new webpack.optimize.CommonsChunkPlugin({ ?name: "app", ?// or ?names: ["app", "subPageA"] ?children: true, ?async: true, ?minChunks: 3,})【wepack4】
webpack 4 将移除 CommonsChunkPlugin, 取而代之的是两个新的配置项 optimization.splitChunks 和 optimization.runtimeChunk
通过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项
当满足如下条件时,webpack 会自动打包 chunks:
当前模块是公共模块(多处引用)或者模块来自 node_modules当前模块大小大于 30kb如果此模块是按需加载,并行请求的最大数量小于等于 5如果此模块在初始页面加载,并行请求的最大数量小于等于 3
通过设置 optimization.runtimeChunk: true 来为每一个入口默认添加一个只包含 runtime 的 chunk
动态导入
上面介绍的CommonsChunkPlugin可以去重和分离chunk。而本节介绍的动态导入,则是通过模块的内联函数调用来分离代码
webpack 提供了两个类似的技术。对于动态导入,第一种,也是优先选择的方式是,使用符合 ECMAScript 提案 的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure
下面来使用import()语法来进行动态导入
?const path = require(‘path‘); ?const HTMLWebpackPlugin = require(‘html-webpack-plugin‘); ?module.exports = { ???entry: { ?????index: ‘./src/index.js‘ ???}, ???plugins: [ ?????new HTMLWebpackPlugin({ ???????title: ‘Code Splitting‘ ????}) ???], ???output: { ?????filename: ‘[name].bundle.js‘, ?????chunkFilename: ‘[name].bundle.js‘, ?????path: path.resolve(__dirname, ‘dist‘) ???} ?};下面来动态导入loadsh
function getComponent() {
return import(/* webpackChunkName: "lodash" */ ‘lodash‘).then(_ => { ????var element = document.createElement(‘div‘); ????element.innerHTML = _.join([‘Hello‘, ‘webpack‘], ‘ ‘); ????return element; ??}).catch(error => ‘An error occurred while loading the component‘); ?} getComponent().then(component => { ??document.body.appendChild(component); }) 在注释中使用了 webpackChunkName。这样做会导致bundle 被命名为 lodash.bundle.js ,而不是 [id].bundle.js
懒加载
懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载
上面通过动态导入的loadsh确实会在脚本运行的时候产生一个分离的代码块 lodash.bundle.js ,在技术概念上“懒加载”它。问题是加载这个包并不需要用户的交互 -- 意思是每次加载页面的时候都会请求它
下面来增加一个交互,当用户点击按钮的时候用 console 打印一些文字。但是会等到第一次交互的时候再加载那个代码块(print.js)
//print.jsconsole.log(‘The print.js module has loaded! See the network tab in dev tools...‘);export default () => { ?console.log(‘Button Clicked: Here\‘s "some text"!‘);}//index.js import _ from ‘lodash‘; function component() { ??var element = document.createElement(‘div‘); ??var button = document.createElement(‘button‘); ??var br = document.createElement(‘br‘); ??button.innerHTML = ‘Click me and look at the console!‘; ??element.innerHTML = _.join([‘Hello‘, ‘webpack‘], ‘ ‘); ??element.appendChild(br); ??element.appendChild(button); ??button.onclick = e => import(/* webpackChunkName: "print" */ ‘./print‘).then(module => { ????var print = module.default; ????print(); ??}); ???return element; ?} document.body.appendChild(component());剔除无用代码
tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import 和 export。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup
【JS】
JS的tree shaking主要通过uglifyjs插件来完成
npm install --save-dev uglifyjs-webpack-plugin
const path = require(‘path‘);const UglifyJSPlugin = require(‘uglifyjs-webpack-plugin‘);module.exports = { ?entry: ‘./src/index.js‘, ?output: { ???filename: ‘bundle.js‘, ???path: path.resolve(__dirname, ‘dist‘) }, ?plugins: [ ??new UglifyJSPlugin() ?]};【CSS】
CSS的tree shaking主要通过purify CSS来实现的
npm i -D purifycss-webpack purify-css
const path = require(‘path‘);const glob = require(‘glob‘);const ExtractTextPlugin = require(‘extract-text-webpack-plugin‘);const PurifyCSSPlugin = require(‘purifycss-webpack‘);module.exports = { ?entry: {...}, ?output: {...}, ?module: { ???rules: [ ?????{ ???????test: /\.css$/, ???????loader: ExtractTextPlugin.extract({ ?????????fallbackLoader: ‘style-loader‘, ?????????loader: ‘css-loader‘ ???????}) ?????} ???] ?}, ?plugins: [ ???new ExtractTextPlugin(‘[name].[contenthash].css‘), ???// Make sure this is after ExtractTextPlugin! ???new PurifyCSSPlugin({ ?????// Give paths to parse for rules. These should be absolute! ?????paths: glob.sync(path.join(__dirname, ‘app/*.html‘)), ???}) ?]};如果要设置多路径,则需要将glob换成glob-all
const glob = require(‘glob-all‘);
paths: glob.sync([ ?path.join(__dirname, ‘.php‘), ?path.join(__dirname, ‘partials/.php‘)])
webpack配置之代码优化
原文地址:https://www.cnblogs.com/xiaohuochai/p/8489602.html