Webpack5 生产模式

生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。优化主要从两个角度出发:

  • 优化代码运行性能
  • 优化代码打包速度

一、生产模式准备

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

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.  修改开发模式的配置文件:

 开发模式启动指令:npx webpack serve --config ./config/webpack.dev.js  

const path = require('path');   //node.js核心模块,专门用来处理路径问题
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,

        //因为开发模式没有输出,不需要指定输出路径
        path: undefined,
        filename: "static/js/main.js"
    },
    // 加载器
    module: {
        rules: [
            // css-loder的配置
            {
                test: /\.css$/,   //只检测.css文件
                //执行顺序:从右到左(从下到上)
                use: [
                    "style-loader",    //将js中css通过创建style标签添加到html文件中
                    "css-loader"],     //将css资源编译成commonjs的模块到js中
            },
            // less-loder的配置
            {
                test: /\.less$/,
                // use:可以使用多个loader,  loader:只能使用一个loader
                use: [
                    // compiles Less to CSS
                    'style-loader',
                    'css-loader',
                    'less-loader',       //将js中less通过创建style标签添加到html文件中
                ],
            },
            // scss-loder的配置
            {
                test: /\.s[ac]ss$/,
                use: [
                    'style-loader',     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    'sass-loader',      // 将 Sass 编译成 CSS
                ],
            },
            // stylus-loader的配置
            {
                test: /\.styl$/,
                use: [
                    'style-loader',     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    'stylus-loader',      // 将 Sass 编译成 CSS
                ],
            },
            // 图片
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于10KB图片会转base64,  优点:减少请求数量  缺点:体积变大
                        maxSize: 15 * 1024 // 4kb
                    }
                },
                generator: {
                    // 输出图片名字
                    filename: 'static/images/[hash:10][ext][query]'   //[hash:10] 表示hash值只取10位
                }
            },
            // 图标
            {
                test: /\.(ttf|woff2?)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名字
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            // 其他资源
            {
                test: /\.(map3|map4|avi)$/,   //在这里加上就可以统一处理
                type: 'asset/resource',
                generator: {
                    // 输出名字
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            // babel
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,   //排除 node_modules 中的js文件 (这些文件不处理)
                loader: 'babel-loader',
                // options: {
                //   presets: ['@babel/preset-env']    //一般在 babel.config.js 文件写,方便修改
                // }
            }
        ]
    },
    // 插件
    plugins: [
        // plugins的配置
        new ESLintPlugin({
            // 指定检查文件的根目录
            context: path.resolve(__dirname, "../src")  //__dirname表示绝对路径
        }),
        // 以 public/index.html 为模板创建文件
        // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../public/index.html")
        })
    ],
    // 开发服务器:不会输出资源,在内存中编译打包的
    devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
    },
    // 模式
    mode: 'development'
}

3.  修改生产模式的配置文件:

生产模式启动指令:npx webpack --config ./config/webpack.prod.js       

const path = require('path');   //node.js核心模块,专门用来处理路径问题
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: [
            // css-loder的配置
            {
                test: /\.css$/,   //只检测.css文件
                //执行顺序:从右到左(从下到上)
                use: [
                    "style-loader",    //将js中css通过创建style标签添加到html文件中
                    "css-loader"],     //将css资源编译成commonjs的模块到js中
            },
            // less-loder的配置
            {
                test: /\.less$/,
                // use:可以使用多个loader,  loader:只能使用一个loader
                use: [
                    // compiles Less to CSS
                    'style-loader',
                    'css-loader',
                    'less-loader',       //将js中less通过创建style标签添加到html文件中
                ],
            },
            // scss-loder的配置
            {
                test: /\.s[ac]ss$/,
                use: [
                    'style-loader',     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    'sass-loader',      // 将 Sass 编译成 CSS
                ],
            },
            // stylus-loader的配置
            {
                test: /\.styl$/,
                use: [
                    'style-loader',     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    'stylus-loader',      // 将 Sass 编译成 CSS
                ],
            },
            // 图片
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于15KB图片会转base64,  优点:减少请求数量  缺点:体积变大
                        maxSize: 15 * 1024 // 4kb
                    }
                },
                generator: {
                    // 输出图片名字
                    filename: 'static/images/[hash:10][ext][query]'   //[hash:10] 表示hash值只取10位
                }
            },
            // 图标
            {
                test: /\.(ttf|woff2?)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名字
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            // 其他资源
            {
                test: /\.(map3|map4|avi)$/,   //在这里加上就可以统一处理
                type: 'asset/resource',
                generator: {
                    // 输出名字
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            // babel
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,   //排除 node_modules 中的js文件 (这些文件不处理)
                loader: 'babel-loader',
                // options: {
                //   presets: ['@babel/preset-env']    //一般在 babel.config.js 文件写,方便修改
                // }
            }
        ]
    },
    // 插件
    plugins: [
        // plugins的配置
        new ESLintPlugin({
            // 指定检查文件的根目录
            context: path.resolve(__dirname, "../src")  //__dirname表示绝对路径
        }),
        // 以 public/index.html 为模板创建文件
        // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../public/index.html")
        })
    ],
    // 生产模式不需要devServer
    // 模式
    mode: 'production',
}

由于运行指令比较长,为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面:

  "scripts": {
    "start":"npm run dev",
    "dev": "webpack serve --config ./config/webpack.dev.js",
    "build":"webpack --config ./config/webpack.prod.js"
  },
  • 生产模式运行指令: npm run build
  • 开发模式运行指令:npm start

二、生产模式配置 

1. Css处理

Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式,这样对于网站来说,会出现闪屏现象,用户体验不好,我们应该是单独的 Css 文件,通过 link 标签加载性能才好

1.下载包:npm install --save-dev mini-css-extract-plugin

 2. 生产模式下配置文件 webpack.pros.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成单独的文件
            "css-loader"
        ],
      },
    ],
  },
};

 2. Css 兼容性处理

1. 下载:npm i postcss-loader postcss postcss-preset-env -D

2. 生产模式配置文件  webpack.prod.js

 在css-loader后面,less-loader、sass-loader、stylus-loader前面加上 postcss-loader

module.exports = {   
    module: {
        rules: [
            // css-loder的配置
            {
                test: /\.css$/,   //只检测.css文件
                //执行顺序:从右到左(从下到上)
                use: [
                    MiniCssExtractPlugin.loader,    //提取css成单独的文件
                    "css-loader",    //将css资源编译成commonjs的模块到js中
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                ],
            },
            // less-loder的配置
            {
                test: /\.less$/,
                // use:可以使用多个loader,  loader:只能使用一个loader
                use: [
                    // compiles Less to CSS
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    'less-loader',       //将js中less通过创建style标签添加到html文件中
                ],
            },
            // scss-loder的配置
            {
                test: /\.s[ac]ss$/,
                use: [
                    MiniCssExtractPlugin.loader,     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    'sass-loader',      // 将 Sass 编译成 CSS
                ],
            },
            // stylus-loader的配置
            {
                test: /\.styl$/,
                use: [
                    MiniCssExtractPlugin.loader,     // 将 JS 字符串生成为 style 节点
                    'css-loader',       // 将 CSS 转化成 CommonJS 模块
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    "postcss-preset-env", // 能解决大多数样式兼容性问题
                                ],
                            },
                        },
                    },
                    'stylus-loader',      // 将 Sass 编译成 CSS
                ],
            },
        ]
    }
}

3. 控制兼容性

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

//例如:兼容浏览器 ie8 以上
"browserslist" : [
    "ie >= 8"
  ]

browserslist 文档:https://github.com/browserslist/browserslist

 实际开发中可以这样设置:

  "browserslist" : [
    "last 2 version",   // 所有浏览器适配最近两个版本
    "> 1%",            // 覆盖99%的浏览器
    "not dead"         //不要已经死了的浏览器
  ]

3. 合并配置

// 用来获取处理样式的loader
function getStyleLoader(pre) {   //不同的loader通过传参
    return [
        MiniCssExtractPlugin.loader,    //提取css成单独的文件
        "css-loader",    //将css资源编译成commonjs的模块到js中
        {
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        "postcss-preset-env", // 智能预设,能解决大多数样式兼容性问题
                    ],
                },
            },
        },
        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: [
            // css-loder的配置
            {
                test: /\.css$/,   //只检测.css文件
                //执行顺序:从右到左(从下到上)
                use: getStyleLoader()
            },
            // less-loder的配置
            {
                test: /\.less$/,
                // use:可以使用多个loader,  loader:只能使用一个loader
                use: getStyleLoader('less-loader')
            },
            // scss-loder的配置
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoader('sass-loader')
            },
            // stylus-loader的配置
            {
                test: /\.styl$/,
                use: getStyleLoader('stylus-loader')
            },    
    ]
}

4. css压缩

 1. 安装插件: npm install css-minimizer-webpack-plugin --save-dev

 2. 配置文件 webpack.prod.js

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值