1.为什么要使用webpack
webpack是一种模块打包工具,提供丰富的选项和插件配置,进行自动化代码打包优化,减少维护成本;同时也能缩小打包文件;
2.常见配置
entry:入口。配置入口文件,
output:输出。配置输出文件名filename,路径path
mode打包模式:mode:'development/production'
module loader:rules:test文件类型,后缀;use:使用的loader
plugins:-cleanwebpackplugin(plugin:[new cleanwebpackplugin()]),
- htmlwebpackplugin(plugins:[ new HTMLWebpackPlugin({})]filename:, template:, title),
-MiniCssExtractPlugin(new MiniCssExtractPlugin({filename:}))
devtool
配置项中
cheap
表示只具体到某一行不具体到某一列,且不检测loader
的错误,有助于加快编译速度;module
检测loader
的错误,因此错误更全,方便快速查找错误 ;eval
表示soucemap
的映射代码放到打包后的js
文件中,而不是生成source.map.js
文件;souce-map
指将错误映射到具体源文件上
sourcemap定位代码:
配置:在webpack.config.js 末端添加devtool
原理:生成.map文件,是打包文件与源文件的行列映射。浏览器支持了这样一种特性,只要在 eval 代码的最后加上 //# sourceURL=xxx,那就会以 xxx 为名字把这段代码加到 sources 里,在浏览器source形成目录,把content内容填充形成目录。
3.model chunk bundel 怎么理解
bundel:webpack打包后的一个文件;对chunk编译
chunk:代码块,用于合并分割代码;由多个module组成
model:资源模块,包括js/css/img
4.webpack构建流程
初始化参数--开始编译--确认入口--进行编译--完成编译--输出资源--写入文件,完成输出
初始化参数:解析webpack配置参数,合并shell传入和webpack.config.js文件配置的参数,形成最后的配置结果。
开始编译:参数初始化compiler对象,注册所有配置的插件,插件监听webpack构建生命周期的事件节点,做出相应的反应,执行对象的 run 方法开始执行编译。
确定入口:从配置的entry入口,找到所有入口文件,开始解析文件构建AST语法树,找出依赖,递归下去。
编译模块:递归中根据文件类型和loader配置,调用所有配置的loader对文件进行转换,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
完成模块编译: Loader 编译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
输出资源:根据⼊⼝和模块之间的依赖关系,组装成⼀个个包含多个模块的 Chunk,再把每个 Chunk 转换成⼀个单独的⽂件加⼊到输出列表,这步是可以修改输出内容的最后机会;
输出完成:在确定好输出内容后,根据配置确定输出的路径和⽂件名,把⽂件内容写⼊到⽂件系统。
5.webpack热更新机制
HMR-hot module replacement,客户端从服务端拉取更新文件,chunk需要更新的部分,(webpack dev sever)WDS向浏览器推送更新,带上构建的hash,客户端镜像资源对比,有差异即WDS发起Ajax请求获取更改内容,客户端拿到chunk进行增量更新,进行页面渲染
6.loader plugin
loader:翻译,预处理。其他资源转换成js
plugin:插件。扩展webpack功能,灵活性
7.提高webpack打包速度
(1)使用高版本webpack和node.js;
(2)压缩代码uglify-js,ParallelUglifyPlugin;压缩css:css nano ;optimizeCssAssetsWebpackPlugin
(3)Happypack多线程构建,module
var happyThreadPool = HappyPack.ThreadPool({ size: 5 });
(4)压缩图片
(5)缩小打包作用域
(6)提取公共资源,基础包分离,,通过CDN引入,不打包进budel,html-webpack-externals-plugin;分离第三库split chunk plugin
(7)缓存
(8)tree shaking;只打包用到的方法,配置:.babelrc
里设置 modules
: false;
optimize-minimize ;optimization:{ //启动tree-shaking usedExports:true }
(9)Scope hoisting;将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当的重命名一些变量以防止变量名冲突。通过对比,使用 scope hoisting
可以减少函数声明代码和内存开销。
(10)代码分割;实现:配置多入口,多出口
- 抽离相同代码到一个共享块
- 脚本懒加载,使得初始下载的代码更小
- 有利于运行时的持久化文件缓存
缩小打包体积:压缩代码;CDN(内容分发网络)加速,静态资源上传SDN,配置资源路径;tree shaking;分离第三库split chunk plugin;代码分割;
8.有哪些loader
-1、file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件。
-2、url-loader:和 file-loader 类似,但是能在⽂件很⼩的情况下以 base64 的⽅式把⽂件内容注⼊到代码中去。
-3、source-map-loader:加载额外的 Source Map ⽂件,以⽅便断点调试。
-4、image-loader:载并且压缩图⽚⽂件。
-5、babel-loader:将ES6转化为ES5 ,代码兼容。
-6、css-loader:加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性。
-7、style-loader:把 CSS 代码注⼊到 JavaScript 中,通过 DOM 操作去加载 CSS。
-8、eslint-loader:通过 ESLint 检查 JavaScript 代码。
-9.thread-loader:多进程打包,每次webpack解析一个模块,thread-loader会将它及它的依赖分配给worker进程中
loader实现
9.常见的plugin
- html-webpack-plugin:生成HTML的模板
- uglifyjs-webpack-plugin
- mini-css-extract-plugin:将css提取到一个独立的css文件中
- optimize-css-assets-webpack-plugin
- hot module replacementplugin
- cleanwebpackplugin
- compression-webpack-plugin:实现了HTTP压缩的第一步操作
- DllPlugin :加速打包插件,用于打包出一个个单独的动态链接库文件和索引的任务列表
plugin实现
10.hash, chunk hash 和content hash(打包文件指纹:输出的文件名和后缀)
hash项目hash,项目文件改变就改变
chunk文件改变,hash改变。如果进行基础包分离,代码分割打包成多个chunk,改动只会改变对应的chunk hash
文件内容改变,content hash改变
11.tree shaking
打包时将引用的方法打包进入chunk,未引用的剔除
webpack4 的 treeshaking 是关注 import 了某个库的什么模块,那么我就打包什么;webpack5 更精细化,作用域分析,直接分析到哪些变量有效地用到了,那么我就打包哪些变量。
三个步骤
- Make 阶段,收集模块导出变量并记录到模块依赖关系图 ModuleGraph 变量中
- Seal 阶段,遍历 ModuleGraph 标记模块导出变量有没有被使用
- 生成产物时,若变量没有被其它模块使用则删除对应的导出语句
12.babel原理
babel是js转换器,包括
- 语法插件:作用于 @babel/parser,负责将代码解析为抽象语法树(AST)(官方的语法插件以 babel-plugin-syntax 开头);
- 转换插件:作用于 @babel/core,负责转换 AST 的形态。绝大多数情况下我们都是在编写转换插件。
parse:解析,把代码变成AST(抽象语法树(Abstract Syntax Tree))
traverse:转换,遍历AST,遇到对应类型的节点,visitor 就会做出相应的修改处理;
generate:生成,把AST变成代码
13.提取公共模块
---01.html-webpack-externals-plugin
const HtmlWebpackExternalsPlugin = require("html-webpack-externals-plugin");
module.exports = {
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [
{
module: "react",
entry: "https://unpkg.com/react@16/umd/react.production.min.js",
global: "React"
},
{
module: "react-dom",
entry:
"https://unpkg.com/react-dom@16/umd/react-dom.production.min.js",
global: "ReactDOM"
}
]
}),
],
};
---02webpack自带SplitChunksPlugin,进行配置
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /(react|react-dom)/,
name: "vendors",
chunks: "all"
}
}
}
}
};
14.manifest
打包,压缩之后的chunk管理
webpack.DllReferencePlugin 的选项中:
- context 需要跟之前保持一致,这个用来指导 Webpack 匹配 manifest.json 中库的路径;
- manifest 用来引入刚才输出的 manifest.json 文件
15.webpack5新特性
启动命令:webpack-dev-server-->webpack server
持久化缓存:默认开启,缓存默认在内存中,可以对cache进行设置
资源模块
URIs:支持在请求中处理协议;支持data支持Base64或原始编码
moduleIds &chunkIds优化:deterministic新增模式,在生产环境的默认模式,根据文件名生成短hash
更智能的tree shaking
移除node.js中polyfll
模块联邦:每个应用块是一个独立构建,这些构建都将编译成容器,可以被其他应用或容器使用,引用者是host,被引用是remote
16.多页面打包
每个页面对应一个entry,一个html-webpack-plugin
缺点:每次新增挥着删除页面都需要更改webpack配置
17.打包构建错误信息
webpack生命函数钩子中进行错误输出上报:
done: 编译完成后
beforeRun: 在编译器执行前
run: 在编译器开始读取记录前执行
emit: 文件提交到dist目录前
afterEmit: 文件提交到dist目录前
compilation: 创建compilation后
beforeCompile: 在编译前
compile: 创建compilation前
make:编译完成前
18.资源代理
---1.http代理插件http-proxy-middleware
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
pathRewrite: {
"^/api": "/api"
},
})
);
};
---2.引入craco
//craco.config.js
const path = require('path')
module.exports = {
//配置代理解决跨域
devServer: {
port: 3009,
proxy: {
'/api': {
target: 'http://114.215.183.171:5002',
changeOrigin: true,
pathRewrite: {
"^/api": "/api"
}
},
}
}
19.长缓存优化
webpack5新特性,持久化缓存,选择内存或文件系统,配置了之后,会将缓存存放在cacheDirectory中,第二次编译的时候会去读取缓存。同时追踪每个模块的依赖,并创建了文件系统快照。此快照会与真实文件系统进行比较,当检测到差异时,将触发对应模块的重新构建
20.动态导入,按需加载
ES6的import()语法实现,动态的加载模块,而不是编译时将模块打包到一个文件中,可以减少文件大小,提高程序性能
babel插件:@babel/plugin:syntax-dynamic-import
21.文件监听
方式:---启动webpack 命令时,带上--watch 参数
---在配置webpack.config.js 中设置watch: true
原文件变化,会构建生成。
轮询判断文件编辑时间是否变化,缓存,统一执行
22.less loader转化成css原理
接受less代码作为入参,调用less库提供的方法转成css代码,输出给css loader