webpack

1. webpack的构建流程

  • 初始化流程:从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数
  • 编译构建流程:从 Entry 发出,针对每个 Module 调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理
  • 输出流程:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统

2. loader

loader 让 webpack 能够去处理那些非 JavaScript 文件webpack 自身只理解 JavaScript)loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块。loader扮演一个翻译官的角色

常见的loader如下:

  • style-loader: 将css添加到DOM的内联样式标签style里
  • css-loader :允许将css文件通过require的方式引入,并返回css代码
  • less-loader: 处理less
  • sass-loader: 处理sass
  • postcss-loader: 用postcss来处理CSS
  • autoprefixer-loader: 处理CSS3属性前缀,已被弃用,建议直接使用postcss
  • file-loader: 分发文件到output目录并返回相对路径
  • url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
  • html-minify-loader: 压缩HTML
  • babel-loader :用babel来转换ES6文件到ES5

3. plugin

plugin是插件的意思,对webpack现有功能的各种扩展.

例如打包优化、资源管理、环境变量注入等,它们会运行在 webpack 的不同阶段,贯穿了webpack整个编译周期,目的在于解决loader 无法实现的其他事.

4. loader和plugin的区别:

作用:

  • loader主要用于转换某些类型的模块为wepack能够识别的js模块,是一个加载器;
  • plugin是插件,对webpack本身进行扩展,是一个扩展器;

作用时机:plugin运行在 webpack 的不同阶段,贯穿了webpack整个编译周期,loader在模块转换阶段

5. 热更新

它可以使得代码修改之后,不用刷新浏览器就可以更新,在应用过程中替换添加删出模块,无需重新加载整个页面,是高级版的自动刷新浏览器。

6. webpack proxy

webpack提供的代理服务,基本行为就是接收客户端发送的请求后转发给其他服务器,其目的是为了便于开发者在开发模式下解决跨域问题,想要实现代理首先需要一个中间服务器,webpack中提供服务器的工具为webpack-dev-server

服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制

7. 如何借助webpack来优化前端性能

  • JS代码压缩 压缩:删除多余的代码、注释、简化代码的写法等等⽅式
  • CSS代码压缩
  • Html文件代码压缩
  • 文件大小压缩
  • 图片压缩
  • Tree Shaking 将未用到的代码进行删除
  • 代码分离
  • 内联 chunk
  • 利用CDN加速
  • 使用mode:production 自动开启代码压缩 还会自动使用Tree Shaking

8. 如何优化构建速度

npm install 过程中的优化 使用 yarn去安装npm包

具体仓库地址的选择,选择使用淘宝提供的npm仓库镜像

1、优化lodaer配置

在使用loader时,可以通过配置includeexcludetest属性来匹配文件。

  • include:包含,只处理xxx文件
  • exclude:排除,除了xxx文件以外其他文件都处理

需要注意的是includeexclude只能二选一

2、优化 resolve.alias

alias给一些常用的路径起一个别名,特别当我们的项目目录结构比较深的时候,一个文件的路径可能是./../../的形式、

1
2
3
4
5
6
7
8
module.exports = {
...
resolve:{
alias:{
"@":path.resolve(__dirname,'./src')
}
}
}

3、使用cache-loader

在一些性能开销较大的 loader之前添加 cache-loader,以将结果缓存到磁盘里,显著提升二次构建速度。

保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此loader

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
module: {
rules: [
{
test: /\.ext$/,
use: ['cache-loader', ...loaders],
include: path.resolve('src'),
},
],
},
};

4、happyPack 多进程打包

JS(Node.js/Webpack)是单线程的,因此如果开启多进程打包,可以提高构建速度(特别是多核 CPU)。

项目较大,打包较慢,开启多进程能提高速度

项目较小,打包很快,开启多进程会降低速度(进程开销)

5、开启多进程压缩(生产)

Webpack 内置了 Uglify 工具压缩 JS,但它是单进程的。开启多进程压缩会更快,和 happyPack 同理。

首先需要安装 ParallelUglifyPlugin:

1
npm install webpack-parallel-uglify-plugin --save-dev

6、开启热更新(开发)

热更新:新代码生效,网页不刷新,状态不丢失

代码配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const webpack = require('webpack')
module.exports = {
// ...
devServer: {
// 开启 HMR 特性
hot: true
// hotOnly: true
}
}

//通过上述这种配置,如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中。但是,当我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热模块。所以,HMR并不像 Webpack 的其他特性一样可以开箱即用,需要有一些额外的操作。我们需要去指定哪些模块发生更新时进行HRM,如下代码:
if(module.hot){
module.hot.accept('./util.js',()=>{
console.log("util.js更新了")
})
}

7、使用tree sharking 将未用到的代码进行删除

8、使用 DLLPlugin 插件(开发)

DLL全称是 动态链接库,是为软件在winodw种实现共享函数库的一种实现方式,而Webpack也内置了DLL的功能,为的就是可以共享,不经常改变的代码,抽成一个共享的库。这个库在之后的编译过程中,会被引入到其他项目的代码中

使用步骤分成两部分:

  • 打包一个 DLL 库
  • 引入 DLL 库

9、noParse

这是module中的一个属性,作用:不去解析属性值代表的库的依赖

9、前端为何要进行打包和构建?

1、代码层面

  • 代码体积更小(Tree-Shaking、压缩、合并),加载更快
  • 编译高级语言或语法(TS,ES6+,模块化,scss)
  • 兼容性和错误检查(Polyfill,postcss,eslint)

2、前端工程化

  • 统一、高效的开发环境
  • 统一的构建流程和产出标准
  • 集成公司构建规范(提测、上线等)

10、module chunk bundle 的区别

  • module-各个源码文件,webpack 中一切皆模块
  • chunk-多模块合并成的,如 entry import()splitChunk
  • bundle-最终的输出文件