切换主题
Webpack
篇
高级配置
- 如何配置多入口?
分别配置
entry
的chunks
、output
、plugins
,具体如下:
JavaScript
module.exports = {
entry: {
index: path.join(srcPath, 'index.js'),
other: path.join(srcPath, 'other.js')
},
ouput: {
// filename: 'bundle.[contentHash:8].js',
filename: '[name].[contentHash:8].js' // name 即多入口chunk
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
// 页面引用哪些js文件(代码分割)
chunks: ['index'] // 只引用 index.js
}),
new HtmlWebpackPlugin({
template: path.join(srcPath, 'other.html'),
filename: 'other.html',
chunks: ['other']
})
]
}
- 如何抽离压缩
CSS
文件?
分别配置
module.rules
、plugins
、optimization
,具体如下:
JavaScript
module.exports = {
// 生产环境
mode: 'production',
module: {
rules: [
{
test: /\.css$/,
loader: [
// 'style-loader', // 开发环境
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}
]
},
plugins: [
// 抽离CSS文件
new MiniCssExtractPlugin({
filename: 'css/main.[contentHash:8].css'
})
],
optimization: {
// 压缩CSS文件
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
}
}
- 如何抽离公共代码和第三方代码?
通过配置
optimization.splitChunks
和plugins
里的chunks
,具体如下:
JavaScript
module.exports = {
optimization: {
// 分割代码
splitChunks: {
// initial 入口chunk,不处理异步文件;async 异步chunk,只处理异步文件
chunks: 'all',
// 缓存分组
cacheGroups: {
// 第三方模块
vender: {
name: 'vender', // chunk名称
priority: 1, // 权限高的优先抽离,解决与其它模块冲突
test: /node_modules/,
minSize: 0, // 最小限制
minChunks: 1 // 最少复复用次数
},
// 公共模块
common: {
name: 'common',
priority: 0,
minSize: 0,
minChunks: 2
}
}
}
}
}
- 如何实现异步加载(懒加载)?
使用
import()
函数(引入动态数据)
- 如何处理
JSX
、Vue
?
使用
babel
(配置.babelrc
文件),在module.rules
里分别配置babel-loader
、vue-loader
性能优化
- 如何优化(开发环境)打包构建速度?
- 优化
babel-loader
==> 使用缓存cacheDirectory
;使用include
、exclude
;- 使用
IgnorePlugin
插件避免引入无用模块,像moment
库的语言库只用中文时,直接手动导入中文库;- 使用
noParse
配置规则避免重复打包;- 配置
happyPack
多进程打包(大项目)- 使用
ParalleUglifyPlugin
多进程代码压缩(大项目)- 热更新
- 使用
DllPlugin
将第三方库预先打包成单独的文件,减少构建时间
- 如何优化产出代码?
- 小图片使用
BASE64
编码;bundle
加hash
;- 使用
splitChunk
提取公共代码;- 使用
IgnorePlugin
;ouput
静态资源配置CDN
加速;- 开启
Scope Hosting
:代码体积更小,创建更少的作用域,更好的代码可读性
机制原理
- 热更新
HMR
(即webpack-dev-server
,以下简称WDS
)实现原理?
HMR
即在浏览器不刷新的情况下,用新变更的模块替换掉旧的模块。
实现原理:通过WDS
和浏览器之间维护了一个WebSocket
服务。当本地资源发生变化后,webpack
会先将打包生成新的模块代码放入内存中,然后WDS
向浏览器推送更新,并附带上构建时的hash
,让客户端和上一次资源进行对比,客户端对比出差异后会向WDS
发起Ajax
请求获取到更改后的内容,通过这些信息再向WDS
发起jsonp
请求获取到最新的模块代码,最后HotModulePlugin
将会对新旧模块进行对比,在更新模块的同时更新模块间的依赖引用。
Proxy
工作原理?
null
利用
http-proxy-middleware
这个http
代理中间件,实现请求转发给其他服务器。
==> 当本地浏览器Local
向服务器Server
发起请求时,由于浏览器的同源策略,存在跨域问题,Server
的响应会被浏览器拦截;
==>而代理服务器Proxy
与服务器Server
之间请求数据并不会存在跨域行为,代理服务器Proxy
传递数据给本地浏览器Local
的过程中,两者同源,也不存在跨域行为。
tree-shaking
工作原理?
基于
ES Module
的静态引入规则,在编译的时候可正确判断到底加载了那些模块,进而删除无用代码。CommonJS
和ES Module
区别?
区别 CJS
ESM
导入 可写在判断中 只能写在模块顶层 导出 单个值 可以多个值 输出 值的拷贝 值的引用 时机 运行时加载 编译时输出 this
当前模块 undefined
Loader
和Plugin
实现原理?
参考文章
Loader
和Plugin
实现原理。Loader
和Plugin
的区别?配置上:
Loader
在module.rules
下配置:值类型为数组,每⼀项都是⼀个Object
,⾥⾯描述了对于什么类型的⽂件(test
),使⽤什么加载(loader
)和使⽤的参数(options
);Plugin
在plugins
下配置:值类型也为数组,每一项是一个Plugin
的实例,参数都通过构造函数传入。功能上:
Loader
本质上是一个函数,由于webpack
只能解析原生JavaScipt
文件,所以对于其它类型的文件就需要一个转换器
,将其转换为原生JavaScipt
文件;Plugin
是一个插件,用于增强webpack
功能。
webpack
的构建流程?
null
初始化
:启动构建,读取与合并配置参数,加载Plugin
,使用配置参数实例化Compiler
;编译
:从Entry
出发,针对每个Module
串行调用对应的Loader
去翻译文件的内容,再找到该Module
依赖的 文件内容,递归地进行编译处理;输出
:将编译后的Module
组合成Chunk
,将Chunk
转换成Bundle
文件,输出到文件系统中。
module
、chunk
、bundle
的区别?
module
:各源码文件,在编译的时候会从entry
中递归寻找出所有依赖的模块;chunk
:多模块的合成,用于代码的合并和分割,在构建过程中一起被打包到一个文件中;bundle
:最终输出文件