Webpack-学习笔记02

loading 2023年01月13日 90次浏览

1. 缓存

我们使用 webpack 来打包我们的模块化后的应用程序,webpack 会生成一个可部署的 /dist 目录,然后把打包后的内容放置在此目录中。只要 /dist 目录中的内容部署到 server 上,client(通常是浏览器)就能够访问此 server 的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为缓存的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快

1.1 output文件名

之前的输出文件名是这样的,会导致即使修改了文件中的内容由于文件名没变

output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, './dist'),
        clean: true,
        assetModuleFilename: 'images/[contenthash][ext]'
    },

现在修改成这样,可以实现更新文件名:

    output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, './dist'),
        clean: true,
        assetModuleFilename: 'images/[contenthash][ext]'
    },

1.2 缓存第三方库

将第三方库(library)(例如 lodash )提取到单独的 vendor chunk 文件中,是比较推荐的做法,这是因为,它们很少像本地的源代码那样频繁修改。因此通过实现以上步骤,利用 client 的长效缓存机制,命中缓存来消除请求,并减少向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。

将optimization中的splitChunks修改成这样:

    optimization: {
        minimizer: [
            new CssMinimizerPlugin()
        ],

        splitChunks: {
            cacheGroups: {
                vendor: {
                    // 找到node_modules
                    test: /[\\/]node_modules[\\/]/,
                    // 起个名字
                    name: 'vendors',
                    // 对所有chunk作处理
                    chunks: 'all'
                }
            }
        }
    }

1.3 将所有js打包成一个文件夹

output中的filiename修改成这样即可:

filename: 'scripts/[name].[contenthash].js'

2. 拆分开发环境和生产环境配置

之前我们只能手工的来调整 mode 选项,实现生产环境和开发环境的切换,且很多配置在生产环境和开发环境中存在不一致的情况,比如开发环境没有必要设置缓存,生产环境还需要设置公共路径等等。

因此该章尝试实现拆分两种环境的配置。

2.1 公共路径

用于指定所有资源的基础路径,通过在output中添加一个属性实现:

    output: {
        filename: 'scripts/[name].[contenthash].js',
        path: path.resolve(__dirname, './dist'),
        clean: true,
        assetModuleFilename: 'images/[contenthash][ext]',
	// 公共路径 
        publicPath: 'http://localhost:8080/'
    }

2.2 环境变量

可以在输入命令时添加环境变量实现调控参数,比如

npx webpack --env production --env name=yoimiya

就传入了两个参数,一个production:true,一个name:yoimiya。

首先要把module.exports变成一个函数,然后在函数中返回一个对象,就可以接收到命令行的参数:

module.exports = (env) =>{
    return {

    }
}

此时我们改一下mode表达式,使它根据参数动态改变:

mode: env.production ? 'production' : 'development'

此时我们需要一个插件来压缩一下js代码,就和当时压缩css一样的:

npm install terser-webpack-plugin -D

然后加到optimization里

        optimization: {
            minimizer: [
                new CssMinimizerPlugin(),
                new TerserPlugin()
            ],
        }

2.3 拆分配置文件

实现不同配置文件对应不同开发模式的配置

我们首先创建一个config文件夹,创建三个文件,分别对应公共代码,开发环境专用代码和生产环境专用代码。

我们把两种环境的公共代码提取到common中,模式中只留下自用代码,比如dev只留下这些即可:

module.exports = {
    output: {
        filename: 'scripts/[name].js'
    },

    mode: 'development',

    devtool: 'inline-source-map',

    devServer: {
        static: './dist'
    }
}

而prod需要留下这些:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
    output: {
        filename: 'scripts/[name].[contenthash].js',
        publicPath: 'http://localhost:8080/'
    },

    mode: 'production',

    optimization: {
        minimizer: [
            new CssMinimizerPlugin(),
            new TerserPlugin()
        ]
    },

    performance: {
        hints: false
    }
}

那么如何将这几个文件合并呢?需要用到一个工具:webpack-merge

npm i webpack-merge -D

安装好后我们需要在刚刚的config文件夹下再创建一个webpack.config.js,在其中写入以下内容:

const { merge } = require('webpack-merge')

const commonConfig = require('./webpack.config.common')
const productionConfig = require('./webpack.config.prod')
const developmentConfig = require('./webpack.config.dev')

module.exports = (env) => {
    switch (true) {
        case env.development:
            return merge(commonConfig, developmentConfig)

        case env.production:
            return merge(commonConfig, productionConfig)
    }
}

然后在package.json中定义一下两种运行方式的简写即可:

	"scripts": {
		"start": "webpack serve -c ./config/webpack.config.js --env development",
		"build": "webpack -c ./config/webpack.config.js --env production"
	}