zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

webpack生产、开发公共配置拆分

配置webpack开发 生产 拆分 公共
2023-06-13 09:14:09 时间

代码已上传至github github代码地址:https://github.com/Miofly/mio.git

webpack.common.js

以下是公共配置,生产与开发环境打包时都会经过下面的配置

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const merge = require('webpack-merge')
const devConfig = require('./webpack.dev')
const prodConfig = require('./webpack.prod')

function resolve(dir) {
    return path.join(__dirname, '../../../../', dir)
}

const commonConfig = { // 配置好后 npx webpack
    entry: { // 上面是简写
        // lodash: './src/lodash.js',
        // myVue: './src/index.js',
        sub: './src/main.js'
    },
    output: { // 输出到bundle/bundle.js
        // publicPath: 'http://192.168.3.99:8888/mio/src/html/', // 类似base_url
        filename: '[name].js', // 打包文件的文件名 这样entry可以配置两个入口js 入口文件走这里
        chunkFilename: '[name].chunk.js', // index.js里又引入的js走这里
        // path: path.resolve(__dirname, './dist') //  __dirname指webpack.config.js文件的当前路径
    },
    resolve: {
        // extensions: ['.js', '.vue', '.json'], // 可以导入的时候忽略的拓展名范围
        extensions: ['.js', '.json', '.vue', '.scss', '.css'], // 省略文件名后缀
        alias: {
            '@': resolve('src'),
            zj: resolve('src/components'),
            mioJs: resolve('src/common/js'),
            json: resolve('src/static/mockJson'),
        }
    },
    module: { // loader的顺序从下到上,从右到左
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/, // 排除在外
                loader: 'babel-loader', // 使用babel-loader把es6语法转成es5语法
                options: {
                    presets: [['@babel/preset-env', {
                        // targets: {
                        //     chrome: '67' // 此版本中的浏览器不需要转es5语法
                        // },
                        // 弥补低版本浏览器不支持转es5语法
                        // 使用下面这个属性,不需要 import '@babel/polyfill'
                        // 他会根据使用es6的情况只代码使用到的es6语法
                        // useBuiltIns: 'usage',
                        // corejs: 3
                    }]]
                }
            },
            {
                test: /\.(jpg|png|gif)$/,
                use: { // 把图片变成base64,适合小图片
                    loader: 'url-loader', // npm install url-loader -D
                    options: {
                        // placeholder 占位符 [ext]后缀
                        name: '[name]_[hash].[ext]', // 使打包出的图片文件名+后缀和以前一样
                        outputPath: 'images/', // 图片打包到images/文件夹
                        limit: 2048 // <2kb生成base64 >2kb会在images/生成文件
                    }
                }
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({ // 打包后自动生成一个HTML文件,并把打包生成的js自动引入到这个html文件中
            template: './src/index.html' // 以index.html为模板打包
        }),
        new CleanWebpackPlugin(), // 清除之前打包的文件
    ],
    optimization: { // treeshaking在开发环境下未使用的js仍然存在,但提示只使用了某一个
        usedExports: true,
        // runtimeChunk: { // 老版本的webpack会由于manifest造成因为没改代码
        //     // 也会让contenthash改变, 配置上runtimeChunk会把manifest造成的
        //     // 不同js代码单独抽离出来(抽离的文件runtime.js)
        //     name: 'runtime'
        // },
        // // production下不需要 // 在mode: 'development'配置Tree Shaking
        // splitChunks: { // 默认配置即可 代码分割
        //     chunks: 'all',
        //     cacheGroups: { // 缓存组
        //         vendors: { // 如果代码是node_modules里的则打包成vendors.js
        //             test: /[\\/]node_modules[\\/]/,
        //             priority: -10, // 优先级
        //             // filename: 'vendor11s.js'
        //             name: 'vendor'
        //         },
        //     }
        // }
        /* splitChunks: { // 默认配置
            chunks: "all", // 只对异步代码生效 all同步异步都分割 initial同步(配合cacheGroups使用)
            minSize: 30000, // >30kb就做代码分割
            minChunks: 1, // 当一个模块用了多少次才进行代码分割
            maxAsyncRequests: 5, // 同时加载的模块数
            maxInitialRequests: 3, // 入口文件的代码分割个数
            automaticNameDelimiter: '~', // 组合文件连接的连接符
            name: true, // 让cacheGroups里的名字有效
            cacheGroups: { // 缓存组
                vendors: { // 如果代码是node_modules里的则打包成vendors.js
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10, // 优先级
                    fileName: 'vendors.js'
                },
                default: {
                    // minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true, // 如果一个模块被打包过直接复用
                    fileName: 'common.js'
                }
            }
        }*/
    },
    performance: false // 不提示性能上的问题
}

module.exports = (env) => {
    if (env && env.production) { // 线上环境
        return merge(commonConfig, prodConfig)
    } else { // 开发环境
        return merge(commonConfig, devConfig)
    }
}

webpack.dev.js

开发环境的配置

const path = require('path')
const webpack = require('webpack')

// function resolve(dir) {
//     return path.join(__dirname, '../../../../', dir)
// }

const devConfig = { // 配置好后 npx webpack
    mode: 'development',
    // sourceMap 是一个映射关系,便于快捷定位文件错误位置
    devtool: 'cheap-module-eval-source-map', // development 开发环境最优配置
    devServer: { // 可以开启一个web服务器, 不生成dist目录,放到内存中
        contentBase: './dist',
        open: true, // 自动打开浏览器
        port: 9999,
        // historyApiFallback: false,
        // hot: true,
        // hotOnly: true, // 浏览器不刷新
        proxy: { // 跨域代理
            '/api': 'http://localhost:3030'
        }
    },
    module: {
        rules: [
            { // css-loader合并所有的css文件
                test: /\.css$/,
                use: ['style-loader', 'css-loader', {
                    loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
                    options: {
                        config: {
                            path: path.resolve(__dirname, '../postcss.config.js'),
                        }
                    }
                }]
            },
            { // loader 执行的时候有先后顺序,由下到上,postcss-sass-css-style
                test: /\.scss$/,
                use: [
                    'style-loader', // 用于挂载到html的head
                    {
                        loader: 'css-loader', // 用于把 css 文件合并成一个 css 文件
                        options: {
                            // 加上这个保证 index.scss里引入的scss也经过下面的loader处理
                            importLoaders: 2,
                            modules: false // css模块化
                        }
                    },
                    {
                        loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
                        options: {
                            config: {
                                path: path.resolve(__dirname, '../postcss.config.js'),
                            }
                        }
                    },
                    'sass-loader',
                ]
            },
            { // 支持vue文件的处理
                test: /\.vue$/,
                use: {
                    loader: 'vue-loader' // npm install vue-loader -D
                }
            },
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin() // 使用这个进行浏览器自动刷新和hot hotOnly有冲突
    ],
    output: {
        filename: '[name].js', // 打包文件的文件名
        chunkFilename: '[name].js',
    }
}

module.exports = devConfig

webpack.prod.js

生产环境的配置

const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 不支持热更新,在线上环境使用
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 压缩css生成的代码
const PurgecssPlugin = require('purgecss-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

const prodConfig = { // 配置好后 npx webpack
    mode: 'production', // development  production
    devtool: 'cheap-module-source-map', // production 生成环境
    module: {
        rules: [
            { // css-loader合并所有的css文件
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
                        options: {
                            config: {
                                path: path.resolve(__dirname, '../postcss.config.js'),
                            }
                        }
                    }
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            // 加上这个保证 index.scss里引入的scss也经过下面的loader处理
                            importLoaders: 2,
                            modules: false // css模块化
                        }
                    },
                    {
                        loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
                        options: {
                            config: {
                                path: path.resolve(__dirname, '../postcss.config.js'),
                            }
                        }
                    },
                    'sass-loader'
                ]
            },
            { // 支持vue文件的处理
                test: /\.vue$/,
                use: {
                    loader: 'vue-loader' // npm install vue-loader -D
                }
            },
        ]
    },
    optimization: {
        minimizer: [new OptimizeCssAssetsWebpackPlugin({ // 压缩css生成的代码

        })]
    },
    plugins: [
        new VueLoaderPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[name].chunk.css'
        }),
        // new PurgecssPlugin({ // 去除没用到的css
        //     paths: glob.sync(path.join(__dirname, '../src/index.html')) // src下所有的html
        // }),
    ],
    output: { // 为了防止浏览器缓存加入[contenthash],
        // 代码改变[contenthash]才会改变,否则不会改变
        filename: '[name].[contenthash].js', // 打包文件的文件名
        chunkFilename: '[name].[contenthash].chunk.js',
    }
}

module.exports = prodConfig