Webpack面试题(二)
高级配置
多入口文件
(1)
common.js 修改入口
(2)
修改prod的output 设置动态属性名 后缀加上hash变量
(3)
common里的plugins实例要生成生成两个
chunks如果不写,这两个html默认就是把入口两个文件都引入 所以需要写一下
抽离CSS文件
之前所有css都通过style-loader放进了style里
但线上这样就不太好哈 还是得抽离一下
1.使用minicssextractplugin.loader加载
2.在plugins里抽离
3.在optimization里压缩
// 引入插件 const TerserJSPlugin = require('terser-webpack-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') // 增加 webpack 配置 optimization: { minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], },
抽离less同理
*抽离公共代码
在线上环境需要这么做
多个页面或者入口,如果引用了同一段代码,如上文的多页面例子中,index.js 和 other.js 都引用了 import './common.js' ,则 common.js 应该被作为公共模块打包。webpack v4 开始弃用了 commonChunkPlugin 改用 splitChunks ,可修改 build/webpack.prod.js 中的配置
同理,如果我们的代码中引用了 jquery lodash 等,也希望将第三方模块单独打包,和自己开发的业务代码分开。这样每次重新上线时,第三方模块的代码就可以借助浏览器缓存,提高用户访问网页的效率。修改配置文件,增加下面的 vendor: {...} 配置。
optimization: { // 分割代码块 splitChunks: { chunks: 'all', /** * initial 入口 chunk,对于异步导入的文件不处理 async 异步 chunk,只对异步导入的文件处理 all 全部 chunk */ // 缓存分组 cacheGroups: { // 第三方模块 vendor: { name:'vendor'//chunk名称 priority: 1, // 权限更高,优先抽离,重要!!! test: /node_modules/, chunks: 'initial', minSize: 0, // 大小限制 minChunks: 1 // 最少复用过几次 }, // 公共的模块 common: { name:'common'//chunk名称 chunks: 'initial', minSize: 0, // 公共模块的大小限制 minChunks: 2 // 公共模块最少复用过几次 } } } }对应的,可以在common里,规定各入口文件可以使用哪些模块:
chunk 就是块 在entry里生成了两个块 在splitChunks里又生成了两个块
懒加载
webpack 支持使用 import(...) 语法进行资源懒加载。安装 npm i @babel/plugin-syntax-dynamic-import -D 然后将插件配置到 .babelrc 中。
新建 src/dynamic-data.js 用于测试,内容是 export default { message: 'this is dynamic' } 。然后在 src/index.js 中加入
其他的小知识点:
新建 src/dynamic-data.js 用于测试,内容是 export default { message: 'this is dynamic' } 。然后在 src/index.js 中加入
setTimeout(() => { import('./dynamic-data.js').then(res => { console.log(res.default.message) // 注意这里的 default }) }, 1500)在异步加载的时候,也产生了一个chunk dynamic-data.js 的内容被打包一个单独的文件中。
其他的小知识点:
处理JXS
处理VUE用vue-loader

三、概念问题
module chunk bundle区别
module | 一切皆模块 不管什么文件 所有源码文件都是module |
chunk | 多模块的合成 如entry splitChunk会包含多个模块 是还没有整理的输出 |
bundle | 最终的输出文件 可以理解为chunk整理后的输出 |
性能优化
优化打包速度
1.给babel-loader开启缓存
2.忽略无用模块
比如一个模块支持好多语言,我们只想要中文
例子:
一个日期插件 非常大
可以通过 ignorePlugin 插件忽略 locale 下的语言文件,不打包进来。
plugins: [ new webpack.IgnorePlugin(/\.\/locale/, /moment/), // 忽略 moment 下的 /locale 目录之后再手动加载需要的语言包:
import moment from 'moment' import 'moment/locale/zh-cn' // 手动引入中文语言包 moment.locale('zh-cn') const r = moment().endOf('day').fromNow() console.log(r)
3.避免重复打包
两者的区别是:
4.*happyPack
JS是单线程,开启多进程打包,适合多核CPU
,小项目使用反而会变慢。只有项目较大,打包出现明显瓶颈时,才考虑使用 happypack 。
5.ParalleUglifyPlugin
开启多进程压缩
6.自动刷新(不能用在生产环境里)
一般情况下没得用
整个网页全部刷新,速度较慢,而且状态会丢失
7.热更新(不能用在生产环境里)
新代码生效,网页不刷新,状态不丢失
在devServer里配置 hot:true 但是需要自己配置
8.DllPlugin(不能用在生产环境里)
动态链接库插件
webpack已经内置了
先把vue react做一个预打包:
之后就不再重新打包,直接来使用:
***产出代码
- 小图片base64编码 就不做网络请求了
- bundle+hash 代码没有变化 hash就不会有变化 不需要重新加载
- 懒加载
- 提取公共代码splitChunks
- IngorePlugin
- 使用CDN加速
- *使用production
- *Scope Hosting
production
就是prod.js里的mode:’production‘ 就是线上环境的配置
- 自动开启压缩代码 是代码体积更小 线上速度更快
- Vue React等会自动删掉调试代码(如开发环境下的warning)
- 启动Tree-Shaking**
Tree-Shaking
可以想象成摇树 把没有用的树叶子摇下去 production会自动做这些工作
必须用es6 module才能让Tree-Shaking生效 commonjs不行
因为这是因为 require 是动态引入,无法在编译时判断哪些功能被使用。而 import 是静态引入,编译时即可判断依赖关系。
Scope Hosting
默认的打包结果,每个文件生成一个函数 体积大
使用Scope Hosting 把多个函数合成一个函数 创建的函数作用域更少:
配置方法:
引用插件 开启插件 就行了