webpack基础知识学习(十)--区分打包环境

203 阅读2分钟

通过前面的学习,我们的打包模式一直是在development环境下进行的,接下来我们就要区分开发生产环境的webpack配置了。

1.新建文件夹config。再创建3个文件webpack.common.jswebpack.dev.jswebpack.prod.js

创建公共方法来获取路径。

// config/paths.js

const path = require('path')

const appDir = process.cwd();

const resolvePath = (src) => {
    return path.resolve(appDir, src);
}

module.exports = resolvePath;

webpack.common.js是存放公共配置的。

// config/wenpack.common.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { DefinePlugin } = require('webpack');
const resolvePath = require('./paths');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { merge } = require('webpack-merge')
const prodConfig = require('./webpack.prod')
const devConfig = require('./webpack.dev')

const conmonConfig = {
    entry: './src/index.js',
    output: {
        filename: 'js/boundle.js',
        path: resolvePath('./build')
    },
    resolve: {
        //  按顺序自动解析文件类型,我们可以在import文件后不加文件的后缀名
        extensions: ['.js', '.json', '.ts', '.jsx', '.vue'],
        //  相对路径查找起来麻烦,可以设置别名来简化路径
        alias: {
            '@': resolvePath('./src')
        }
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1,
                            esModule: false
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('postcss-preset-env')
                                ]
                            }
                        }
                    }
                ]
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.(png|svg|gif|jpe?g)$/,
                type: 'asset',
                generator: {
                    filename: 'images/[name].[hash:8].[ext]'
                },
                parser: {
                    dataUrlCondition: {
                        maxSize: 150 * 1024
                    }
                }
            },
            {
                test: /\.(ttf|woff2?|eot)$/,
                type: 'asset',
                generator: {
                    filename: 'font/[name].[hash:8].[ext]'
                }
            },
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.ts$/,
                use: ['babel-loader']
            },
            // {
            //     test: /\.(png|svg|gif|jpe?g)$/,
            //     type: 'asset/inline',
            // }
            // {
            //     test: /\.(png|svg|gif|jpe?g)$/,
            //     type: 'asset/resource',
            //     generator: {
            //         filename: 'images/[name].[hash:8].[ext]'
            //     }

            // }
            // {
            //     test: /\.(png|svg|gif|jpe?g)$/,
            //     use: [
            //         {
            //             loader: 'url-loader',
            //             options: {
            //                 name: 'images/[name].[hash:6].[ext]',
            //                 limit: 25 * 1024
            //             }
            //         }
            //     ]
            // }
            // {
            //     test: /\.(png|svg|gif|jpe?g)$/,
            //     use: [
            //         {
            //             loader: 'file-loader',
            //             options: {
            //                 name: 'images/[name].[hash:6].[ext]'
            //             }
            //         }
            //     ]
            // }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'wenpack基础知识学习',
            template: './public/index.html'
        }),
        new DefinePlugin({
            BASE_NAME: '"我是全局变量"',
            BASE_URL: '"./"'
        }),
        new VueLoaderPlugin()
    ]
}

module.exports = (env) => {
    const isProduction = env.production;
    process.env.NODE_ENV = isProduction ? 'production' : 'development';
    const config = merge(conmonConfig, isProduction ? prodConfig : devConfig);
    return config
}

webpack.prod.js是存放生产环境配置的。

// config/webpack.prod.js

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
    mode: "production",
    plugins: [
        new CleanWebpackPlugin(),
        new CopyWebpackPlugin({
            patterns: [
                {
                    from: 'public',
                    globOptions: {
                        ignore: ['**/index.html']
                    }
                }
            ],
        })
    ]
}

webpack.dev.js是存放开发环境配置的。

// config/webpack.div.js

const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin')

module.exports = {
    mode: "development",
    devtool: 'cheap-module-source-map',
    target: 'web',
    devServer: {
        port: 3000,
        hot: true,
        compress: true,
        proxy: {
            '/api': {
                target: 'http://47.96.132.165:5000/',
                pathRewrite: {'^/api': ''},
                changeOrigin: true
            }
        }
    },
    plugins: [
        new ReactRefreshPlugin(),
    ]
}

2.yarn add webpack-merge --dev。生产和开发的配置需要用到webpack-merge插件,将配置与公共的配置合并在一起。

3.修改babel.config.js。因为babelreact热更新用到了插件,这只在开发环境中应用,所以这里也要区分环境。这里的process.dev.NODE_ENVwebpack.common.js中设置了,如果不设置在babel中是无法拿到环境变量的。

// babel.config.js

const presets = [
    [
        '@babel/preset-env',
        { 
            /**
             * false  不对项目的js做polyfill的处理
             * usage  依据代码中所使用的带的语法进行填充
             * entry  依据所要兼容的平台进行填充
             */
            useBuiltIns: 'usage',
            corejs: 3
        }
    ],
    ['@babel/preset-react'],
    ['@babel/preset-typescript']
];

const plugins = [];
if(process.env.NODE_ENV === 'development') {
    plugins.push(['react-refresh/babel'])
}
console.log(process.env.NODE_ENV, '_________________')
module.exports = {
    presets,
    plugins
}

3.新建短命令重新执行打包

// package.json

"scripts": {
    "serve2": "webpack server --config ./config/webpack.common.js --env development",
    "build2": "webpack --config ./config/webpack.common.js --env production"
},

我们区分环境就完成啦!