webpack5学习笔记

基本使用

1.资源目录:

webpack_code         #项目根目录(所有指令必须在这个目录下运行

                |____src   #项目源码目录

                           |___ js #js文件目录

                           |        |__ count.js

                           |        |__ sum.js

                           |____main.js # 项目主文件

2.创建文件 

  • count.js
export default function count(x,y) {
    return x-y;
}
  • sum.js
export default function sum(...args) {
    return args.reduce((p, c) => p + c, 0);
}
  • main.js
import count from "./js/count";
import sum from "./js/sum";

console.log(count(2,1));
console.log(sum(1, 2, 3, 4));

3.下载依赖

打开终端,来到项目根目录。运行以下指令:

  • 初始化 package.json
npm init -y

此时会生成一个基础的package.json 文件。

需要注意的是 package.json 中 name 字段不能叫做 webpack ,否则下一步会报错

  • 下载依赖
npm i webpack webpack-cli -D

4.启用webpack

  • 开发模式
npx webpack ./src/main.js --mode=development
  • 生产模式
npx webpack ./src/main.js --mode=production

npx webpack :是用来运行本地安装 Webpack 包的。

./src/main.js :指定 webpack 从 main.js 文件开始打包,不但会打包 main.js ,还会将其它依赖也一起打包进来。

--mode=xxx :指定模式(环境)

5.观察输出文件

默认 Webpack 会将文件打包输出到 dist 目录下,我们查看 dist 目录下文件情况就好了

小结


Webpack 本身功能比较少,只能处理 js 资源,一旦遇到 css 等其他资源就会报错。

所以我们学习 Webpack,就是主要学习如何处理其他资源。

基本配置

在开始使用 Webpack 之前,我们需要对 Webpack 的配置有一定的认识。

5 大核心概念


1. entry(入口)

指示 Webpack 从哪个文件开始打包

2. output (输出)

指示 Webpack 打包完的文件输出到哪里去,如何命名等

3. loader(加载器)

webpack 本身只能处理 js、json 等资源需要借助 loader,Webpack 才能解析

4. plugins (插件)

扩展 Webpack 的功能

5. mode(模式)

主要由两种模式:

  • 开发模式:development
  • 生产模式:production

准备 Webpack 配置文件


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

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 文件名
        filename: 'main.js',
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
        ]
    },
    // 插件
    plugins: [
        // plugin的配置
    ],
    // 模式
    mode: "development",
    // mode:"production",
}

开发模式介绍

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

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

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

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

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

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

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

处理样式和图片资源

学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 以及 png、jpeg 、gif 等图片资源

介绍


Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源

我们找 Loader 都应该去官方文档中找到对应的 Loader,然后使用

官方文档找不到的话,可以从社区 Github 中搜索查询

Webpack官方Loader文档

配置:

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'main.js',
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
            {
                test: /\.css$/, // 只检测 .css文件
                use: [ // 执行顺序:从右到左(从下到上)
                    "style-loader", // 将js中css通过创建style标签添加html文件中生效
                    "css-loader", // 将css资源编译成 commonjs 的模块到js中
                ],
            },
            {
                test: /\.less$/,
                // loader:'xxx', // 只能使用1个loader
                use: [ // 使用多个loader
                    // compiles Less to CSS
                    'style-loader',
                    'css-loader',
                    'less-loader', // 将less编译成css文件
                ],
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    'style-loader',
                    // 将 CSS 转化成 CommonJS 模块
                    'css-loader',
                    // 将 Sass 编译成 CSS
                    'sass-loader',
                ],
            },
            {
                test: /\.styl$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "stylus-loader", // 将 Stylus 文件编译为 CSS
                ],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
            }
            /* {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于10kb 的图片转base64
                        // 优点:减少请求数量  缺点:体积会更大
                        maxSize: 4 * 1024 // 4kb
                    }
                }
            } */
        ],
    },
    // 插件
    plugins: [
        // plugin的配置
    ],
    // 模式
    mode: "development",
    // mode:"production",
}

修改输出资源的名称和路径

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    entry: './src/main.js', // 相对路径
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    // [hash:10] 代表hash值只取前10位
                    filename: 'static/images/[hash:10][ext][query]'
                }
            }
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

自动清空上次打包资源

const path = require("path");

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    module: {
        rules: [
            {}
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

处理字体图标资源

1. 下载字体图标文件

2. 将相应的 css 文件和 fonts (ttf|woff等)文件夹复制到 src 文件夹下(注意:css文件里面路径要做相应修改)

3. 将相应的css文件引入到main.js文件

4. 在 html 引入字体图标,记得修改main.js引入的路径,之前修改掉了

 5. 修改配置文件

const path = require("path");

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'static/js/main.js',
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                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|svg)$/,
                type: 'asset',
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                test: /\.(ttf|woff2?)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名称
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

处理其他资源

开发中可能还存在一些其他资源,如音视频等,我们也一起处理了

1.配置

const path = require("path"); 

module.exports = {
    entry: './src/main.js', 
    output: {
        path: path.resolve(__dirname, "dist"), 
        filename: 'static/js/main.js',
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/, 
                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|svg)$/,
                type: 'asset',
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                // 有其他资源时继续往后添加,就会原封不动输出的
                test: /\.(ttf|woff2?|map3|map4|avi)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

处理 js 资源

有人可能会问,js资源 Webpack 不是已经处理了吗,为什么我们还要处理呢?

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

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

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

我们先完成 Eslint ,检测代码格式无误后,在由 Babel 做代码兼容性处理

Eslint


可组装的 JavaScript 和 JSX 检查工具。

这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能

我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查

1. 配置文件

配置文件有很多种写法:

.eslintrc.* :新建文件,位于项目根目录

  • .eslintrc
  • .eslintrc.js
  • .eslintrc.json
  • 区别在于配置格式不一样

package.jsoneslintConfig :不需要创建文件,在原文件基础上写 Eslint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可

2. 具体配置

我们以 .eslintrc.js 配置文件为例:

module.exports = {
    // 解析选项
    parserOptions: {},
    // 具体检查规则
    rules:{},
    // 继承其他规则
    extends:[],
    // ...
    // 其他规则详见:https://eslint.bootcss.com/docs/user-guide/configuring
};

1. parserOptions 解析选项

parserOptions: {
    ecmaVersion: 6, // ES 语法版本
    sourceType: "module", // ES 模块化
    ecmaFeatures:{ // ES 其他特性
        jsx: ture // 如果是 React 项目,就需要开启 jsx 语法
    }
}

2. rules 具体规则

  • "off" 0 - 关闭规则
  • "warn" 1 - 开启规则,使用警告级别的错误:warn(不会导致程序退出)
  • "error" 2 - 开启规则,使用错误级别的错误:error(当被触发的时候,程序会退出)
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 规则太费劲了,所以有更好的办法,继承现有的规则。

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

  • Eslint 官方的规则eslint:recommended
  • Vue Cli 官方的规则:plugin:vue/essential
  • React Cli 官方的规则:react-app
// 例如在React项目中,我们可以这样写配置
module.exports = {
    extends:["react-app"],
    rules:{
        // 我们的规则会覆盖掉react-app的规则
        // 所以想要修改规则直接改就是了
        eqeqeq:["warn","smart"],
},

3. 在 Webpack 中使用

1. 下载包

npm i eslint-webpack-plugin eslint -D

2. 修改 webpack.config.js 文件

  • webpack.config.js
// 把插件添加到你的 webpack 配置
const ESLintPlugin = require('eslint-webpack-plugin');

module.exports = {
  // ...
  // 插件
    plugins: [
        // plugin的配置
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "src")
        })
    ],
  // ...
};

3. 定义 Eslint 配置文件

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

4.修改 js 文件代码

  • main.js
import count from "./js/count";
import sum from "./js/sum";
// 要想 webpack 打包资源,必须引入该资源
import "./css/iconfont.css";
import "./css/index.css";
import "./less/index.less";
import "./sass/index.sass";
import "./sass/index.scss";
import "./stylus/index.styl";

const result = count(2, 1); // 不能用 var 会报错
console.log(result);
// console.log(count(2, 1));
console.log(sum(1, 2, 3, 4));

5. 添加.eslintignore 文件

由于我在VS Code里添加了Eslint语法检查的插件,而我们不需要他检查输出的js文件,也就是dist文件夹,此时我们要新添加一个配置文件.eslintignore 文件,里面写dist,这样他就会忽略dist文件夹里的js文件,从而不报红色波浪线的错误

  • .eslintignore
dist

Babel


JavaScript 编译器。

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

1. 配置文件

配置文件有很多种写法:

babel.config.* :新建文件,位于项目根目录

  • babel.config.js
  • babel.config.json

.babelrc.* :新建文件,位于项目根目录

  • .babelrc
  • .babelrc.js
  • .babelrc.json

package.json 中  babel :不需要创建文件,在原文件基础上写 Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可

2. 具体配置

我们以 babel.config.js 配置文件为例:

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

1. presets 预设

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

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

3. 在 Webpack 中使用

1. 下载包

npm i babel-loader @babel/core @babel/preset-env -D

2. 定义 Babel 配置文件

  • babel.config.js
module.export = {
    // 智能预设:能够编译ES6语法
    presets: ['@babel/preset-env'],
}

3. 配置 webpack.config.js 文件

  • webpack.config.js

在 webpack 配置对象中,需要将 babel-loader 添加到 module 列表中,就像下面这样:

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /node_modules/, // 排除node_modules中的js文件(这些文件不处理)
      /* use: {
            loader: 'babel-loader',
            options: {
                presets: ['@babel/preset-env']
            }
      } */
      /* loader: 'babel-loader',
      options: {
          presets: ['@babel/preset-env']
      } */
      loader: 'babel-loader',
      // options也可以写在外面,babel.config.js 里面 
    }
  ]
}

处理 Html 资源

1. 下载包

npm i html-webpack-plugin -D

2. 配置

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js',
  },
  plugins: [
        new HtmlWebpackPlugin({
            // 模板:以public/index.html 文件创建新的html文件
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "public/index.html"),
        })
    ],
};

开发服务器&自动化

注意:自动化开发服务器运行后不会自动生成dist文件夹

1. 下载包

npm i webpack-dev-server -D

2. 配置

  • webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // ......
    plugins: [],
    // 开发服务器:不会输出资源,在内存中编译打包的
    devServer: {
        host:"localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
    },
    mode:"development",
}

3.运行指令

npx webpack serve

生产模式介绍

生产模式是开发完成代码后,我们需要将代码进行部署上线。

这个模式下我们主要对代码进行优化,让其运行性能更好。

优化主要从两个角度出发:

  1. 优化代码运行性能
  2. 优化代码打包速度

生产模式准备

我们分别准备两个配置文件来放不同的配置

1. 文件目录

|—— 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(包的依赖管理配置文件)

2. 修改 webpack.dev.js

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        // 所有文件的输出路径
        // 开发模式没有输出
        path: undefined,
        // ......
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            // .......
        ],
    },
    plugins: [
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        })
    ],
    devServer: {
        host: "localhost",
        port: "3000",
        open: true,
    },
    mode: "development",
}

 3. 开发模式下运行

npx webpack serve --config ./config/webpack.dev.js

4. 修改 webpack.prod.js

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "../dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            // .......
        ],
    },
    plugins: [
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        })
    ],
    mode: "production",
}

 5. 生产模式下运行

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

优化运行代码

在package.json里面的script配置

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

这样运行开发模式的代码就是:npm start

这样运行生产模式的代码就是:npm run build

Css 处理

提取Css成单独文件

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

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

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

1. 下载包

npm i mini-css-extract-plugin -D

2. 配置

webpack.prod.js

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

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
         // 指定文件输出目录
         filename: "static/css/main.css"
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
};

Css 兼容性处理

1.下载包

npm i postcss-loader postcss postcss-preset-env -D

2. 配置

webpack.prod.js

在css-loader后面,less-loader前面插入配置代码

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  [
                    'postcss-preset-env',
                    {
                      // 其他选项
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

或者使用 PostCSS 本身的 配置文件

postcss.config.js

module.exports = {
    // 你可以指定下面提到的所有选项 https://postcss.org/api/#processoptions
    // parser: 'sugarss',
    plugins: [
        // PostCSS 插件
        ['postcss-short', { prefix: 'x' }],
        'postcss-preset-env',
    ],
};

Loader 将会自动搜索配置文件。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      },
    ],
  },
};

最后,通过你喜欢的方式运行 webpack

3. 控制兼容性

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

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

想要知道更多的 browserslist 配置,查看 browserslist 文档

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

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

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

4. 合并配置

由于代码复用率较高,我们可以封装处理样式的函数

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// 用来获取处理样式的loader
function getStyleLoader(pre) {
    return [
        MiniCssExtractPlugin.loader, // 将js中css通过创建style标签添加html文件中生效
        "css-loader", // 将css资源编译成 commonjs 的模块到js中
        'postcss-loader',
        pre,
    ].filter(Boolean);

}

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "../dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
            {
                test: /\.css$/, // 只检测 .css文件
                use: getStyleLoader(),
            },
            {
                test: /\.less$/,
                // loader:'xxx', // 只能使用1个loader
                use: getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoader('stylus-loader'),
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    // [hash:10] 代表hash值只取前10位
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            /* {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于10kb 的图片转base64
                        // 优点:减少请求数量  缺点:体积会更大
                        maxSize: 4 * 1024 // 4kb
                    }
                }
            } */
            {
                test: /\.(ttf|woff2?|map3|map4|avi)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名称
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            {
                test: /\.m?js$/,
                exclude: /node_modules/, // 排除node_modules中的js文件(这些文件不处理)
                /* use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                } */
                /* loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                } */
                loader: 'babel-loader',
                // options也可以写在外面
            },
        ],
    },
    // 插件
    plugins: [
        // plugin的配置
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 模板:以public/index.html 文件创建新的html文件
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        }),
        new MiniCssExtractPlugin({
            // 指定文件输出目录
            filename: "static/css/main.css"
        }),
    ],
    // 模式
    // mode: "development",
    mode: "production",
}

 Css压缩

1. 下载包

npm i css-minimizer-webpack-plugin -D

2.  配置

  • webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
  optimization: {
    minimizer: [
      // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
      // `...`,
      new CssMinimizerPlugin(),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

html压缩

默认生产模式已经开启了:html 压缩和 js压缩

不需要额外进行配置

猜你喜欢

转载自blog.csdn.net/DIUDIUjiang/article/details/127388827