webpack 中文官网

简介

作用

  • 模块打包.可以将不同模块的文件打包整合在一起,并且保证它们之间的引用正确,执行有序.该功能可以使项目模块化,让项目结构更加清晰,大大提高了项目和代码的可读性.
  • 编译兼容webpack提供了loader机制,该机制不仅可以对代码做polyfill,还可以编译转换诸如.less .sass .jsx这类浏览器无法识别的文件,使得开发过程中可以使用新特性和新语法(babel)进行开发,提高开发效率.
  • 能力扩展webpack提供了plugin机制,该机制可以在实现模块化打包和编译兼容的基础上,提供额外的功能,例如按需加载,代码压缩等等.帮助我们进一步提高自动化程度和工程效率等等.

打包流程

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const path = require("path");

function resolve(dir) {
return path.resolve(__dirname, dir);
}

module.exports = {
mode: "development",
entry: "./src/index.js", // 解析入口
output: {
// 打包出口
path: resolve("./dist"),
filename: "[name].js",
},
resolveLoader: {
modules: ["node_modules", "./loader"], // 从左向右依次去找loader
},
module: {
rules: [
// 配置loader
{
test: /\.js$/,
use: ["css-loader", "style-loader", "less-loader"], // 从右向左解析
},
],
},
resolve: {
extensions: [".js", ".ts"], // 配置后,引入文件时可以不带后缀
alias: {
// 给目录配置别名
"@": resolve("./src"),
},
},
plugins: [], // 添加插件
};

Tree-Shaking

Loader

loader 的作用就是对指定文件(.less .jsx .ts 等)的内容进行编译,将代码转换成浏览器可以识别的代码

实现一个 loader

  • loader 的本质就是一个函数,函数接受几个参数
    • 第一个参数是代码字符串
    • 第二个参数是sourceMap 结果,格式为JSON对象
  • loader 返回一个处理过后的代码字符串,必须要有返回值
  • loader 共有两种,分别是同步 loader 和异步 loader,官网推荐使用异步 loader,如果计算量不大也可以使用同步 loader

同步 loader

1
2
3
module.exports = function (source) {
return source;
};

异步 loader

1
2
3
4
5
6
7
module.exports = function (source, map, meta) {
const asyncFunc = this.async(); // 返回一个callback函数
setTimeout(() => {
asyncFunc(null, content, map);
});
return undefined; // 异步loader返回undefined
};

常用 loader

Plugin

plugin 的作用就是在webpack原有功能的基础上,添加一些额外的扩展功能,来提高整个工程的效率

实现一个 plugin

  • plugin 是一个函数或者是一个具有apply方法的对象(一般使用后者)
  • 在配置文件的plugins字段中对插件进行实例化即可
1
2
3
4
module.exports = class MyPlugin {
constructor() {}
apply(compiler) {}
};

常用 plugin

打包优化

Proxy

webpack 内置的一个接口代理服务

作用

  • 通常用来解决前端本地开发时,请求服务端接口跨域的问题
  • 该功能只在本地开发时有效

原理

  • 使用了 http-proxy-middleware

  • 首先需要了解跨域只在浏览器中存在,在服务器中不存在

  • 那么就可以在本地启动一个 server 服务用来做一层转发,浏览器发出的 xhr 请求先经过本地 server 服务(不会跨域,因为同源),然后本地 server 服务再向服务端接口发起请求(不会跨域,因为是服务器),最后在一层层将服务端接口的 response 进行返回。

使用

1
2
3
4
5
6
7
8
9
export default {
dev: {
"/apm-cms": {
target: "https://sandbox-howl.cms.intl.miui.com/",
changeOrigin: true,
pathRewrite: { "^": "" },
},
},
};