webpack生产环境优化:缓存

发布时间 2023-08-21 00:32:54作者: 影乌

转载请注明 来源:http://www.eword.name/
Author:eword
Email:eword@eword.name

webpack生产环境优化:缓存

生产环境的缓存主要分为:babel缓存和文件资源缓存。

一、babel缓存配置

  • babel缓存
    • 目标:让第二次打包构建速度更快。
    • 在babel-loader配置中添加缓存配置:cacheDirectory: true
/*
    webpack.config.js webpack的配置文件
    路径: ./webpack.config.js
    在babel-loader配置中添加缓存配置:`cacheDirectory: true`
*/

……

/*
     js兼容性处理:babel-loader @babel/core @babel/preset-env
     1.基本js兼容性处理 @babel/preset-env
     问题:只能转换基本语法,如promise不能转换 
     2.全部js兼容性处理 --> @babel/polvfill
     问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~ 
     3. 需要做兼容性处理的就做:按需加载 --> core-js
     */
{
    test: /\.(?:js|mjs|cjs)$/,
    // 指定检查的目录,或者配置排除某些文件夹
    // include: [path.resolve(__dirname, 'src')], 
    // 注意:只检查自己写的源代码,第三方的库是不用检查的,这里排除node_modules文件夹
    loader: "babel-loader",
    exclude: /node_modules/,
    options: {
        // 预设:指示 babel 做怎么样的兼容性处理
        "presets": [
            [
                "@babel/preset-env",
                {
                    // 按需加载
                    useBuiltIns: 'usage',
                    // 制定 core-js 版本
                    corejs: {
                        version: 3
                    },
                    //指定兼容性做到哪个版本的浏览器
                    targets: {
                        chrome: '60',
                        firefox: '60',
                        ie: '9',
                        safari: '10',
                        edge: '17'
                    }
                }
            ]
        ],
        // 开启babel缓存
        //第二次构建时,会读取之前的缓存
        cacheDirectory: true
    }
},

……

核心配置

// 开启babel缓存
//第二次构建时,会读取之前的缓存
cacheDirectory: true

二、文件资源缓存

  • 文件资源缓存
    • 目标: 让代码上线运行缓存更好使用
    • 在生成的js和css文件名上添加hash值,生成的hash值有以下几种:
      • hash:每次wepack构建时会生成一个唯一的hash值。
        • 问题:因为js和css同时使用一个hash值。如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)
      • chunkhash:根据chunk生成的hash值。
        • 问题:js和css的hash值还是一样的。
        • 原因:如果打包来源于同一个chunk,那么hash值就一样。而css是在js中被引入的,所以同属于一个chunk。
      • contenthash:根据文件的内容生成hash值。不同文件hash值一定不一样。
/*
    webpack.config.js webpack的配置文件
    路径: ./webpack.config.js
*/

    ……
    
module.exports = {
    // webpack配置
    // 入口起点文件
    entry: './src/js/index.js',
    // 输出
    output: {
        // 输出文件名
        filename: 'js/built.[contenthash:10].js',
        // 输出路径
        // __dirname nodejs的变量,代表当前文件的目录绝对路径
        path: resolve(__dirname, 'build'),
    },
    // loader的配置
    module: {
        rules: [

            // 详细loader配置
            //不同文件必须配置不同loader处理
            ……
        ],
    },
    // plugins的配置
    plugins: [
        // 详细的plugins配置
        ……
        new MiniCssExtractPlugin({
            //对输出的css文件进行重命名,这里单独为生成的 css 创建一个 css 文件夹。
            filename: './css/[contenthash:10].css',
            ignoreOrder: false,
            linkType: "text/css",
        }),
        ……
    ],
    // 模式  development  开发环境,production 生产环境
    // mode: 'development',
    // 生产环境下会自动压缩js代码
    mode: 'production',

    // 开发服务器devServer:用来自动化(自动编译, 自动打开浏览器, 自动刷新浏览器)
    // 特点:只会在内存中编译打包,不会有任何输出
    // 启动devServer指令为: npx webpack-dev-server
    devServer: {
        ……
    },
};

核心配置

   ……
   // 在 output配置文件输出是添加.[contenthash:10]配置,
   // 实现在生成的文件名中加入 10位hash哈西值。
   // 如果文件内容没有变化,那么 contenthash 不会变化。
   
    output: {
        // 输出文件名
        filename: 'js/built.[contenthash:10].js',
        // 输出路径
        // __dirname nodejs的变量,代表当前文件的目录绝对路径
        path: resolve(__dirname, 'build'),
    },
    
    ……

        ……
 
// 在 plugins中的MiniCssExtractPlugin插件的filename配置中添加[contenthash:10]配置,
// 实现在生成的文件名中加入 10位hash哈西值。
// 如果文件内容没有变化,那么 contenthash 不会变化。
   
   
    // plugins的配置
    plugins: [
        // 详细的plugins配置
        ……
        new MiniCssExtractPlugin({
            //对输出的css文件进行重命名,这里单独为生成的 css 创建一个 css 文件夹。
            filename: './css/[contenthash:10].css',
            ignoreOrder: false,
            linkType: "text/css",
        }),
        
        ……
        
    ],
    
     ……
      

三、缓存测试

3.1、搭建测试服务器

使用express搭建测试服务器

// server.js 文件
// 服务器代码
// express搭建服务器
const express = require('express');
// app 中间件 use 暴露服务器
// maxAge: 1000 * 3600 有效期 1 小时
const app = express();
app.use(express.static('build', { maxAge: 1000 * 3600 }));
// 启动监听端口
app.listen(3000);
  • 启动服务器指令:
    • 方式一:使用nodemon启动,需要安装nodemon包
      • npm i nodemon -g
      • nodemon server.js
    • 方式二:使用 node ,无需额外安装包
      • node server.js
  • 访问服务器地址:http://localhost:3000/

3.2、执行测试服务器

# 先打包构建
> npx webpack
# 再启动服务器
> node server.js

服务器启动后,如果要测试代码改动,可以再启动一个终端直接重新打包构建,无需重启服务器,直接刷新浏览器即可。

3.3、查看缓存配置是否生效

浏览器访问:http://localhost:3000/

打开调试工具查看

打开调试工具查看Cache-Control信息

四、工程文件路径

.
├── build       ## 打包后的js和css文件名称后面都加上了10位hash值。
│   ├── css
│   │   ├── 1.8f2f5b58a1.css
│   │   └── 2.c6c6c3a2a2.css
│   ├── imgs
│   │   └── ae7bf15c0d.jpg
│   ├── index.html
│   ├── js
│   │   ├── 1.built.c15a5dbe89.js
│   │   ├── 1.built.c15a5dbe89.js.map
│   │   ├── 2.built.1605e46a5d.js
│   │   ├── 2.built.1605e46a5d.js.map
│   │   ├── built.f675d9b9a1.js
│   │   └── built.f675d9b9a1.js.map
│   └── media
│       └── cffec944b5. ttf
├── server.js                   ## 服务器文件
├── src
│   ├── css
│   │   ├── iconfont.css
│   │   ├── index.css
│   │   └── index.less
│   ├── imgs
│   │   ├── img.jpg
│   │   ├── img1.jpg
│   │   ├── img2.jpg
│   │   └── img3.jpg
│   ├── index.html
│   ├── js
│   │   ├── iconfont.js
│   │   └── index.js
│   └── media
│       ├── iconfont.json
│       └── iconfont.ttf
└── webpack.config.js