切换主题
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区别?
区别 CJSESM导入 可写在判断中 只能写在模块顶层 导出 单个值 可以多个值 输出 值的拷贝 值的引用 时机 运行时加载 编译时输出 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:最终输出文件