Skip to content

一、Webpack基础

webpack官网

1.前言

1.1 为什么需要打包工具?

开发时,我们会使用框架(React、Vue),ES6 模块化语法,Less/Sass 等 css 预处理器等语法进行开发。

这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法,才能运行。

所以我们需要打包工具帮我们做完这些事。

除此之外,打包工具还能压缩代码、做兼容性处理、提升代码性能等。

1.2 有哪些打包工具?

  • Grunt
  • Gulp
  • Parcel
  • Webpack
  • Rollup
  • Vite
  • ...

目前市面上最流量的是 Webpack,所以我们主要以 Webpack 来介绍使用打包工具

2.Webpack介绍

2.1 作用

Webpack 是一个静态资源打包工具。

它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。

输出的文件就是编译好的文件,就可以在浏览器段运行了。

我们将 Webpack 输出的文件叫做 bundle

2.2 功能

Webpack 本身功能是有限的:

  • 开发模式:仅能编译 JS 中的 ES Module 语法
  • 生产模式:能编译 JS 中的 ES Module 语法,还能压缩 JS 代码

2.3 创建webpack项目

2.6.1 项目目录结构

text
webpack_code # 项目根目录(所有指令必须在这个目录运行)
	└── public
	 	├── index.html # 引入dist里的main.js文件
    └── src # 项目源码目录
     	├── css # css文件目录
        ├── js # js文件目录
        │   ├── count.js
        │   └── sum.js
        └── main.js # 项目入口文件
    └── webpack.config.js 	# webpack配置文件

2.6.2 下载webpack模块

bash
yarn add webpack webpack-cli -D

2.6.3 启动webpack

开发模式

bash
npx webpack ./src/main.js --mode=development

生产模式

bash
npx webpack ./src/main.js --mode=production
  • npx webpack: 是用来运行本地安装 Webpack 包的。
  • ./src/main.js: 指定 Webpackmain.js 文件开始打包,不但会打包 main.js,还会将其依赖也一起打包进来。
  • --mode=xxx:指定模式(环境)。
  • --config:指定配置文件

2.4 五大核心概念

配置项描述作用
entry入口指示 Webpack 从哪个文件开始打包
output输出指示 Webpack 打包完的文件输出到哪里去,如何命名等
loader加载器webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析
plugins插件扩展 Webpack 的功能
mode模式分为开发模式:development,生产模式:production

2.5 Webpack 配置文件

在项目根目录下新建文件:webpack.config.js

下面是webpack.config.js基本结构

js
module.exports = {
  // 入口
  entry: "",
  // 输出
  output: {},
  // 加载器
  module: {
    rules: [],
  },
  // 插件
  plugins: [],
  // 模式
  mode: "",
};

Webpack 是基于 Node.js 运行的,所以采用 Common.js 模块化规范

下面是webpack.config.js在项目中最基本的配置,往后会有更多的配置

js
// Node.js的核心模块,专门用来处理文件路径
const path = require("path");

module.exports = {
  // 入口
  // 相对路径和绝对路径都行
  entry: "./src/main.js",
  // 输出
  output: {
    // path: 文件输出目录,必须是绝对路径
    // path.resolve()方法返回一个绝对路径
    // __dirname 当前文件的文件夹绝对路径
    path: path.resolve(__dirname, "dist"),
    // filename: 输出文件名
    filename: "main.js",
  },
  // 加载器
  module: {
    rules: [],
  },
  // 插件
  plugins: [],
  // 模式
  mode: "development", // 开发模式
};

2.6 开发模式介绍

开发模式顾名思义就是我们开发代码时使用的模式。

这个模式下我们主要做两件事:

1.编译代码,使浏览器能识别运行

  • 开发时我们有样式资源、字体图标、图片资源、html 资源等,webpack 默认都不能处理这些资源,所以我们要加载配置来编译这些资源

2.代码质量检查,树立代码规范

  • 提前检查代码的一些隐患,让代码运行时能更加健壮。

  • 提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。

3.处理样式资源

学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源

  • Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源
  • 我们找 Loader 都应该去官方文档中找到对应的 Loader,然后使用
  • 官方文档找不到的话,可以从社区 Github 中搜索查询
  • Webpack 官方 Loader 文档

3.1 处理Css资源

public/index.html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>hello webpack</h1>
    <div class="box">
      <div class="son"></div>
      <div class="son1"></div>
      <div class="son2"></div>
    </div>
    <script src="../dist/main.js"></script>
  </body>
</html>

3.1.1 下载包

bash
yarn add css-loader style-loader -D
  • css-loader:负责将 Css 文件编译成 Webpack 能识别的模块
  • style-loader:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容

3.1.2 配置

  • test:用来匹配以.xxx 结尾的文件
  • use:使用多个loader, 执行顺序是从右到左
  • loader:使用单个loader

webpack.config.js

js
// ...
  module: {
    rules: [
      {
        // 用来匹配 .css 结尾的文件
        test: /\.css$/,
        // use 数组里面 Loader 执行顺序是从右到左
        use: ["style-loader", "css-loader"],
      },
    ],
  },
// ...

3.1.3 添加css资源

src/css/index.css

css
.box{
    width: 500px;
    height: 500px;
    border: 1px solid #000;
}

3.1.4 导入css

src/main.js

js
import "./css/index.css";

3.1.5 运行指令

bash
npx webpack

打开public/index.html即可看到结果

3.2 处理Less资源

3.2.1 下载包

bash
yarn add less less-loader -D

3.2.2 配置

js
// ...
module: {
    rules: [
        {
            test: /\.less$/,
            use: ["style-loader", "css-loader", "less-loader"],
        },
    ],
},
// ...

3.2.3 添加Less资源

src/less/index.css

less
.box{
    .son{
        width: 50px;
        height: 50px;
        background-color: pink;
    }
}

3.2.4 导入less

src/main.js

js
import "./less/index.less";

3.2.5 运行指令

bash
npx webpack

打开public/index.html即可看到结果

3.3 处理Sass和Scss资源

3.3.1 下载包

bash
yarn add sass-loader sass -D

3.3.2 配置

js
// ...
module: {
    rules: [
        {
            test: /\.s[ac]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
        },
    ],
},
// ...

3.3.3 添加sass资源

src/scss/index.scss

scss
.box {
  .son1 {
    width: 50px;
    height: 50px;
    background-color: blue;
  }
}

3.3.4 导入

src/main.js

js
import "./scss/index.scss";

3.3.5 运行指令

bash
npx webpack

打开public/index.html即可看到结果

3.4 处理Styl资源

3.4.1 下载包

bash
yarn add stylus stylus-loader -D

3.4.2 配置

js
// ...
module: {
    rules: [
        {
            test: /\.styl$/,
            use: ["style-loader", "css-loader", "stylus-loader"],
        },
    ],
},
// ...

3.4.3 添加Styl资源

src/styl/index.styl

scss
/* 可以省略大括号、分号、冒号 */
.box 
  width 100px 
  height 100px 
  background-color pink

3.4.4 导入

src/main.js

js
import "./styl/index.styl";

3.4.5 运行指令

bash
npx webpack

打开public/index.html即可看到结果

4.处理图片资源

过去在 Webpack4 时,我们处理图片资源通过 file-loaderurl-loader 进行处理

现在 Webpack5 已经将两个 Loader 功能内置到 Webpack 里了,我们只需要简单配置即可处理图片资源

4.1 配置

js
// ...
module: {
    rules: [
        {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
                }
            }
        },
    ],
},
// ...

5.修改输出文件目录

5.1 入口文件输出位置

修改output中的filename

webpack.config.js

javascript
output: {
    path: path.resolve(__dirname, "dist"),
        filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
},

5.2 图片资源输出位置

在相应loader中添加generator配置项,修改filename

  • hash:打包后图片的文件名为一串唯一的字符串
    • 修改文件名长度[hash:8],生成字符串长度为8的文件名
  • ext:打包后的文件扩展名与打包前的扩展名一致
  • query:添加之前的query参数
javascript
// ...
module: {
    rules: [
        {
            test: /\.(png|jpe?g|gif|webp)$/,
            generator: {
                filename: "static/imgs/[hash:8][ext][query]",
            },
        }
    ],
},
// ...

6.自动删除上次打包内容

output中添加clean: true

js
output: {
    //...
    clean: true,
    //...
},

7.处理字体图标资源

用到iconfont或者其他字体时,项目中会有一些以ttf或woff结尾的字体文件

7.1 配置

js
// ...
module: {
    rules: [
        {
            test: /\.(ttf|woff2?)$/,
            type: "asset/resource",
            generator: {
                filename: "static/media/[hash:10][ext][query]",
            },
        },
    ],
},
// ...

type: "asset/resource"type: "asset"的区别:

  1. type: "asset/resource" 相当于file-loader, 将文件转化成 Webpack 能识别的资源,其他不做处理
  2. type: "asset" 相当于url-loader, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式

7.2 其他资源

除了字体,项目中可能还会有音频、视频等资源,也属于asset/resource类型,只需将上面代码添加部分内容

js
// ...
module: {
    rules: [
        {
            test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
            type: "asset/resource",
            generator: {
                filename: "static/media/[hash:10][ext][query]",
            },
        },
    ],
},
// ...

8.处理js资源

Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。

其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。

  • 针对 js 兼容性处理,我们使用 Babel 来完成
  • 针对代码格式,我们使用 Eslint 来完成

8.1 Eslint

可组装的 JavaScript 和 JSX 检查工具。用来检测 js 和 jsx 语法的工具,可以配置各项功能

8.1.1 配置文件

Eslint配置文件分为以下几种方式

  • .eslintrc.*:位于项目根目录,区别在于配置格式不一样
    • .eslintrc
    • .eslintrc.js
    • .eslintrc.json
  • package.jsoneslintConfig:不需要创建文件,在原有文件基础上写

8.1.2 具体配置

.eslintrc.js 配置文件为例:

parserOptionsrulesextends三个配置项

js
module.exports = {
  // 解析选项
  parserOptions: {},
  // 具体检查规则
  rules: {},
  // 继承其他规则
  extends: [],
  // ...
  // 其他规则详见:https://eslint.bootcss.com/docs/user-guide/configuring
};
1.parserOptions
javascript
parserOptions: {
  ecmaVersion: 6, // ES 语法版本
  sourceType: "module", // ES 模块化
  ecmaFeatures: { // ES 其他特性
    jsx: true // 如果是 React 项目,就需要开启 jsx 语法
  }
}
2.rules 具体规则
  • "off"0 - 关闭规则
  • "warn"1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error"2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
javascript
rules: {
  semi: "error", // 禁止使用分号
  'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告
  'default-case': [
    'warn', // 要求 switch 语句中有 default 分支,否则警告
    { commentPattern: '^no default$' } // 允许在最后注释 no default, 就不会有警告了
  ],
  eqeqeq: [
    'warn', // 强制使用 === 和 !==,否则警告
    'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
  ],
}

更多规则详见:规则文档

3.extends 继承

开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。

现有以下较为有名的规则:

例如在React项目中,我们可以这样写配置

javascript

module.exports = {
  extends: ["react-app"],
  rules: {
    // 我们的规则会覆盖掉react-app的规则
    // 所以想要修改规则直接改就是了
    eqeqeq: ["warn", "smart"],
  },
};

8.1.3 在Webpack中使用

1.下载包

bash
yarn add eslint-webpack-plugin eslint -D

2.定义Eslint配置文件

.eslintrc.js

js
module.exports = {
  // 继承 Eslint 规则
  extends: ["eslint:recommended"],
  env: {
    node: true, // 启用node中全局变量
    browser: true, // 启用浏览器中全局变量
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: "module",
  },
  rules: {
    "no-var": 2, // 不能使用 var 定义变量
  },
};

3.配置

webpack.config.js

javascript
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");

module.exports = {
    // ...
    plugins: [
        new ESLintWebpackPlugin({
            // 指定检查文件的根目录
            context: path.resolve(__dirname, "src"),
        }),
    ],
    // ...
};

8.1.4 VSCode Eslint 插件

下载此插件不用编译,vscode会自动显示错误

Eslint 忽略文件解决

.eslintignore

js
# 忽略dist目录下所有文件
dist

8.2 Balel

主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

8.2.1 配置文件

配置文件由很多种写法:

  • babel.config.*:新建文件,位于项目根目录
    • babel.config.js
    • babel.config.json
  • .babelrc.*:新建文件,位于项目根目录
    • .babelrc
    • .babelrc.js
    • .babelrc.json
  • package.jsonbabel:不需要创建文件,在原有文件基础上写

Babel 会查找和自动读取它们,以上配置文件只需要存在一个即可

8.2.2 具体配置

babel.config.js 配置文件为例:

babel.config.js

javascript
module.exports = {
  // 预设
  presets: [],
};

presets 预设

简单理解:就是一组 Babel 插件, 扩展 Babel 功能

  • @babel/preset-env: 一个智能预设,允许您使用最新的 JavaScript。
  • @babel/preset-react:一个用来编译 React jsx 语法的预设
  • @babel/preset-typescript:一个用来编译 TypeScript 语法的预设8

8.2.3 在Webpack中使用

1.下载包

text
yarn add babel-loader @babel/core @babel/preset-env -D

2.定义 Babel 配置文件

babel.config.js

javascript
module.exports = {
  presets: ["@babel/preset-env"],
};

3.配置

webpack.config.js

javascript
module.exports = {
    module: {
        rules: [
            // ...
            {
                test: /\.js$/,
                exclude: /node_modules/, // 排除node_modules代码不编译
                loader: "babel-loader",
            },
            // ...
        ],
    },
};
  1. 运行指令
text
npx webpack

打开打包后的 dist/static/js/main.js 文件查看,会发现箭头函数等 ES6 语法已经转换了

9.处理Html资源

9.1 下载

text
yarn add html-webpack-plugin -D

9.2 配置

webpack.config.js

js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
    // ...
    plugins: [
        new HtmlWebpackPlugin({
            // 以 public/index.html 为模板创建文件
            // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
            template: path.resolve(__dirname, "public/index.html"),
        }),
    ],
    // ...
}

之后再打包,dist会有一个index.html文件,和项目中的html结构一致,并且自动引入main.js

10.开发服务器&自动化

devServer会在webpack中搭建一个服务器,默认端口为localhost:3000,自动监视src下的文件,若发现有文件发生变化,会自动打包。这样就不用每次修改完文件手动打包了

10.1 下载

bash
yarn add webpack-dev-server -D

10.2 配置

devServer是和entry等同级的配置项

webpack.config.js

javascript
module.exports = {
  // 开发服务器
  devServer: {
    host: "localhost", // 启动服务器域名
    port: "3000", // 启动服务器端口号
    open: true, // 是否自动打开浏览器
  },

};

11.生产环境介绍

11.1 项目目录

  • 主要是在根目录下创建一个config文件夹,将有原来的webpack.config.js放进去,并改名为webpack.dev.js
  • 再复制一份改名为webpack.prod.js
text
├── webpack-test (项目根目录)
    ├── config (Webpack配置文件目录)
    │    ├── webpack.dev.js(开发模式配置文件)
    │    └── webpack.prod.js(生产模式配置文件)
    ├── node_modules (下载包存放目录)
    ├── src (项目源码目录,除了html其他都在src里面)
    │    └── 略
    ├── public (项目html文件)
    │    └── index.html
    ├── .eslintrc.js(Eslint配置文件)
    ├── babel.config.js(Babel配置文件)
    └── package.json (包的依赖管理配置文件)

11.2 修改 webpack.dev.js

javascript
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: "./src/main.js",
    output: {
        path: undefined, // 开发模式没有输出,不需要指定输出目录
        filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
        // clean: true, // 开发模式没有输出,不需要清空输出结果
    },
    module: {
        rules: [
            {
                // 用来匹配 .css 结尾的文件
                test: /\.css$/,
                // use 数组里面 Loader 执行顺序是从右到左
                use: ["style-loader", "css-loader"],
            },
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"],
            },
            {
                test: /\.s[ac]ss$/,
                use: ["style-loader", "css-loader", "sass-loader"],
            },
            {
                test: /\.styl$/,
                use: ["style-loader", "css-loader", "stylus-loader"],
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset",
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
                    },
                },
                generator: {
                    // 将图片文件输出到 static/imgs 目录中
                    // 将图片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件扩展名
                    // [query]: 添加之前的query参数
                    filename: "static/imgs/[hash:8][ext][query]",
                },
            },
            {
                test: /\.(ttf|woff2?)$/,
                type: "asset/resource",
                generator: {
                    filename: "static/media/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js$/,
                exclude: /node_modules/, // 排除node_modules代码不编译
                loader: "babel-loader",
            },
        ],
    },
    plugins: [
        new ESLintWebpackPlugin({
            // 指定检查文件的根目录
            context: path.resolve(__dirname, "../src"),
        }),
        new HtmlWebpackPlugin({
            // 以 public/index.html 为模板创建文件
            // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
            template: path.resolve(__dirname, "../public/index.html"),
        }),
    ],
    // 其他省略
    devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
    },
    mode: "development",
};

运行开发模式的指令:

  • server:开启devServer
  • --config:指定配置文件
bash
npx webpack serve --config ./config/webpack.dev.js

11.3 修改 webpack.prod.js

javascript
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
    filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
    clean: true,
  },
  module: {
    rules: [
      {
        // 用来匹配 .css 结尾的文件
        test: /\.css$/,
        // use 数组里面 Loader 执行顺序是从右到左
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.s[ac]ss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
      {
        test: /\.styl$/,
        use: ["style-loader", "css-loader", "stylus-loader"],
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
          },
        },
        generator: {
          // 将图片文件输出到 static/imgs 目录中
          // 将图片文件命名 [hash:8][ext][query]
          // [hash:8]: hash值取8位
          // [ext]: 使用之前的文件扩展名
          // [query]: 添加之前的query参数
          filename: "static/imgs/[hash:8][ext][query]",
        },
      },
      {
        test: /\.(ttf|woff2?)$/,
        type: "asset/resource",
        generator: {
          filename: "static/media/[hash:8][ext][query]",
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules代码不编译
        loader: "babel-loader",
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
    }),
    new HtmlWebpackPlugin({
      // 以 public/index.html 为模板创建文件
      // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
      template: path.resolve(__dirname, "../public/index.html"),
    }),
  ],
  // devServer: {
  //   host: "localhost", // 启动服务器域名
  //   port: "3000", // 启动服务器端口号
  //   open: true, // 是否自动打开浏览器
  // },
  mode: "production",
};

运行生产模式的指令:

bash
npx webpack --config ./config/webpack.prod.js

11.4 配置运行指令

package.json

json
{
  // ...
  "scripts": {
    "start": "npm run dev",
    "dev": "webpack serve --config ./config/webpack.dev.js",
    "build": "webpack --config ./config/webpack.prod.js"
  }
  // ...
}

12.Css处理

12.1 提取Css成单独文件

Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式

这样对于网站来说,会出现闪屏现象,用户体验不好

我们应该是单独的 Css 文件,通过 link 标签加载性能才好

12.1.1 下载包

bash
yarn add mini-css-extract-plugin -D

12.1.2 配置

将之前所有style-loader换成MiniCssExtractPlugin.loader,并注册插件

webpack.prod.js

javascript
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, "css-loader"],
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
            },
            {
                test: /\.s[ac]ss$/,
                use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
            },
            {
                test: /\.styl$/,
                use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"],
            },
        ],
    },
    plugins: [
        // 提取css成单独文件
        new MiniCssExtractPlugin({
            // 定义输出文件名和目录
            filename: "static/css/main.css",
        }),
        // ...
    ],
    mode: "production",
};

12.2 Css兼容性处理

12.2.1 下载包

bash
yarn add postcss-loader postcss postcss-preset-env -D

12.2.2 配置

webpack.prod.js

js
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                ],
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    "less-loader",
                ],
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    "sass-loader",
                ],
            },
            {
                test: /\.styl$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    "stylus-loader",
                ],
            },
        ],
    },
	// ...
};

12.2.3 控制兼容性

可以在 package.json 文件中添加 browserslist 来控制样式的兼容性做到什么程度。

json
{
  // 其他省略
  "browserslist": ["ie >= 8"]
}

想要知道更多的 browserslist 配置,查看browserslist 文档open in new window

以上为了测试兼容性所以设置兼容浏览器 ie8 以上。

实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:

json
{
  // 其他省略
  "browserslist": ["last 2 version", "> 1%", "not dead"]
}

12.2.4 合并配置

将之前的兼容loader封装床函数,减少代码冗余

webpack.prod.js

javascript
    const path = require("path");
    const ESLintWebpackPlugin = require("eslint-webpack-plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");

    // 获取处理样式的Loaders
    const getStyleLoaders = (preProcessor) => {
      return [
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [
                "postcss-preset-env", // 能解决大多数样式兼容性问题
              ],
            },
          },
        },
        preProcessor,
      ].filter(Boolean);
    };

    module.exports = {
      entry: "./src/main.js",
      output: {
        path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
        filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
        clean: true,
      },
      module: {
          // ...
        rules: [
          {
            // 用来匹配 .css 结尾的文件
            test: /\.css$/,
            // use 数组里面 Loader 执行顺序是从右到左
            use: getStyleLoaders(),
          },
          {
            test: /\.less$/,
            use: getStyleLoaders("less-loader"),
          },
          {
            test: /\.s[ac]ss$/,
            use: getStyleLoaders("sass-loader"),
          },
          {
            test: /\.styl$/,
            use: getStyleLoaders("stylus-loader"),
          },
        // ...
        ],
      },
        // ...
      mode: "production",
    };

12.3 css压缩

默认生成模式html、js已经开始压缩

12.3.1 下载包

bash
yarn add css-minimizer-webpack-plugin -D

12.3.2 配置

webpack.prod.js

js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
    // ...
    plugins: [
        // css压缩
        new CssMinimizerPlugin(),
        // ...
    ],

    mode: "production",
};

上次更新时间:

MIT Licensed