多进程打包
happyPack
new ParalleUhlifyPlugin
开启多进程 按需开启
项目小, 打包够快,开始多进程会增加开销,降低速度
项目大, 打包越来越慢, 开启多进程提高速度
性能优化 --- 产出代码
体积更小
合理分包,不重复加载
速度更快、内存使用更少
common
-webpack-merge
development
-cheap-module-eval-source-map
--config webpack.dev.js
production
-自动开始代码压缩
-cheap-module-source-map
--config webpack.prod.js
- Vue React 等会自动删掉调试代码
-tree-shaking
--ES6 Module 才能让 tree-shaking 生效 import (只支持静态引入)
sideEffect: [""] // 其中模块tree-shaking 不对其作用
--引入的东西做打包,不引入的剔除掉
loader
递归的对模块进行处理
style-loader file-loader url-loader limit
sass-loader postcss-loader
plugin
可以在webpack运行到某一时刻做一些事情,类比:生命周期
htmlWebpackPlugin 会在打包结束后运行,自动生成一个html文件,并把打包生成的js自动引入到这个html文件中
- template
cleanWebpackPlugin 打包之前运行,帮助删除dist目录下全部内容。
sourceMap
-development cheap-module-eval-source-map
-production cheap-module-source-map
webpackDevServe (提升开发效率)
webpack --watch 监听打包文件
webpack4之后直接用,不用自定义服务器(node serve webpack-dev-middleware)
hot module replacement
devServe: {
hot: true,
hotOnly: true, // hmr出了问题自动刷新页面
}
if (module.hot) {
module.hot.accapt('', () => {})
}
babel
babel-loader
babel-core // 转换成ast 抽象语法树
@babel/preset-env // 帮助语法转换,包括翻译规则
useBuildIns usage 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加。
@babel/polyfill // 弥补低版本浏览器的内容(main 包会变大)
@babel/plugin-transform-runtime // 写类库,有效避免polyfill的问题,以闭包的形式去注入,间接的帮助组件去引入对应的内容,避免全局污染问题。
test : '/.js/'
.babel.rc
react代码打包
presets -> react
@babel/preset-react
Code Splitting
splitChunksPlugin >= webpack4 已经和webpack做了捆绑,不需要自己引入。optimization同步代码分割。
-- 缓存分组
getComponent 写异步组件载入方式,会将异步导入文件。异步代码(import)无需做任何配置,自动进行代码分割。
-- lazy loading 模块懒加载,通过import去异步加载一个模块。什么时候去执行import这个语法的时候,才会去真正的加载这个模块。ES中的一个概念。
webpack-bundle-analysis
-分析重复打包
-打包耗时
-打包优化
prefetching/preloading
-高性能前端代码 代码的使用率(code coverage)
- console -> ctrl+p -> >coverage
--多写异步代码,提升页面打包性能。同步的只能增加缓存,性能提升有限。
prefetching
-主核心业务加载完后,网络空闲时加载,利用页面上的缓存。
preloading
-主业务文件一起加载。
CSS代码分割
MiniCssExtractPlugin
webpack与浏览器缓存
contenthash 源代码改变->hash字符串改变
shimming
providePlugin
Library / 打包一个库
externals: ['xxx'] 业务代码加载这个库,不打包到库里
main: ./dist/xxx
npm publish / npm install
Progressive Web Application
PWA
页面开始能访问,后续服务挂掉,依然可以访问缓存页面。
线上环境 service worker
workbox-webpack-plugin
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
})
TypeScript打包配置
ts-loader
webpackDevServe实现请求转发
devServe: {
proxy: {
xxx
}
}
WebpackDevServer解决单页面应用路由问题
browserRouter:
historyApiFallback: true
后端在nginx Apach 做同样的配置,无论访问什么路由请求都返回html
nginx
location / { try_files $uri /index.html; }
Eslint在webpack中配置
eslint-loader
多页面打包配置
利用HtmlWebpackPlugin
template:
filename:
chunks:
fs.readdirSync
webpack打包优化
跟上技术的迭代(node, npm, yarn)
尽可能在少的模块上应用loader exclude/include
resolve: (可以让打包速度更快)
extensions [.js, .jsx] 一般配置逻辑性文件
mainfiles
alias
第三方模块只打包一次
为了提升开发效率,webpack5内置了缓存,没必要做这种配置。
addAssetHtmlWebpackPlugin
1、要实现打包分离,需涉及两个插件(DllPlugin和DllReferencePlugin),两个打包文件(webpack.dll.config.js-对应DllPlugin插件和webpack.config.js-对应DllReferencePlugin插件,文件名称自定义)。
webpack.dll.config.js文件目的:
1、分离依赖包;
2、生成manifest.json映射文件,供 DLLReferencePlugin 映射到相关的依赖上去的。
2、webpack.dll.config.js中,output.library名称需和DllPlugin插件定义的name保持一致;
3、webpack.dll.config.js中,output.libraryTarget名称一般取默认'var',如需修改,需保持和webpack.config.js文件中DllReferencePlugin插件中的sourceType保持一致。但经本人验证,output.libraryTarget值不可为commonjs2及umd,其他未验证。
4、必须在最终的html文件中插入引用。引用webpack.dll.config.js打包生成的dll文件。如果使用了插件html-webpack-plugin,则可用插件html-webpack-include-assets-plugin将依赖包打包文件引入。否则会报类似“_dll_react is not defined”之类的错误。
控制包的大小
用不到的包用treeShaking去除掉
不要引入
thread-loader ,parallel-webpack ,happypack 利用node多进程,同时利用多个cpu,多进程打包
手写一个loader
function(source)
this上有方法
loader-utils
async callback
手写一个plugins
class
apply(compiler) hooks 有多个周期 emit compile done failer
Bundler 打包工具
打包工具用node.js
首先对模块去做分析,分析入口文件,拿到文件名读出来文件内容,然后把文件中字符串转换成一个抽象语法树(ast),分析依赖关系,对代码进行编译。返回文件名、依赖关系、以及编译之后的代码。
遍历分析所有的模块,递归模块生成分析后的模块图谱对象。
让每个模块代码在闭包中执行