webpack学习

123 阅读5分钟

多进程打包

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),分析依赖关系,对代码进行编译。返回文件名、依赖关系、以及编译之后的代码。

遍历分析所有的模块,递归模块生成分析后的模块图谱对象。

让每个模块代码在闭包中执行