简体   繁体   中英

Webpack build task overriding optimizations

Problem: The production build task is minifying files but then overriding those with unminified files.

Context: I'm using an environment variable to use different webpack config files. npm run dev uses webpack.config.dev.js and puts unminified files into /public. npm run dist uses webpack.config.prod.js and puts minified files into /dist. Both require webpack.config.common.js.

It seems like there's an issue with the order of when things happen for the dist task. It first adds the minified files to /dist and then removes them to replace them with unminified files. This, of course, defeats the purpose of minifying them.

Question: Is there something unintentionally running for the dist task, or do you see anything that could be causing this issue?

I'm new to webpack, and any help would be much appreciated. Thank you.

package.json scripts:

  "scripts": {
    "dev": "NODE_ENV=development webpack --config webpack.config.dev.js --mode development --watch",
    "dist": "NODE_ENV=production webpack --config webpack.config.prod.js --mode production && fractal build"
  },

webpack.config.common.js:

const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const magicImporter = require('node-sass-magic-importer');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: { main: './assets/js/main.js'},
    resolve: {
        modules: [
            path.resolve(__dirname, 'assets/js'),
            path.resolve(__dirname, 'assets'),
            path.resolve(__dirname, 'favicon.ico'),
            'node_modules'
        ],
        extensions: ['.js']
    },
    devtool: "inline-source-map",
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ['@babel/preset-env'],
                        babelrc: false
                    }
                }
            },
            {
                test: /\.(css|scss)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'resolve-url-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            importer: magicImporter(),
                            sourceMap: true
                        }
                    }
                ]
            }
    },
    plugins: [      
        new MiniCssExtractPlugin({
            filename: 'assets/css/main.css'
        }),

        new CopyWebpackPlugin([
            {
                from: 'assets/img/**/*',
                to: 'assets/img/',
                flatten: true
            },
            {
                from: 'assets/video/**/*',
                to: 'assets/video/',
                flatten: true
            },
            {
                from: 'assets/webvtt/**/*',
                to: 'assets/webvtt/',
                flatten: true
            },
            {
                from: 'favicon.ico',
                to: ''
            },
            {
                from: '*.png',
                to: ''
            }
        ])
    ]
};

webpack.config.dev.js:

const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.config.common.js');

module.exports = merge(common, {
    mode: 'development',
    output: {
        path: path.resolve(__dirname, 'public/'),
        publicPath: '/',
        filename: 'assets/js/main.js'
    }
});

webpack.config.prod.js:

const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.config.common.js');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = merge(common, {
    mode: 'production',
    output: {
        path: path.resolve(__dirname, 'dist/'),
        publicPath: '/',
        filename: 'assets/js/main.js'
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: false,
                parallel: true,
                sourceMap: false,
                uglifyOptions: {
                    warnings: false,
                    parse: {},
                    compress: {},
                    mangle: true,
                    output: null,
                    toplevel: false,
                    nameCache: null,
                    ie8: false,
                    keep_fnames: false
                },
                extractComments: {
                    condition: /^\**!|@preserve|@license|@cc_on/i,
                    filename: 'assets/js/extracted-comments.js'
                }
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    }
});

I was able to solve this by combining all my webpack configs back into webpack.config.js and using a conditional that checks the environment to push the optimizations rather than using a different config.

I think the problem was with the fractal build task being appended to the dist task. I think webpack was correctly minifying files, and then fractal was building them unminified after that. I'm not sure why combining the files solved it (my dist task still has fractal build appended), but I'm happy it's working as I intended now.

Updated package.json scripts:

  "scripts": {
    "dev": "NODE_ENV=development webpack --mode development --watch",
    "dist": "NODE_ENV=production webpack --mode production && fractal build"
  },

Updated webpack.config.js:

const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const magicImporter = require('node-sass-magic-importer');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    mode: process.env.NODE_ENV,
    entry: { main: './assets/js/main.js'},
    output: {
        path: path.resolve(__dirname, 'public/'),
        publicPath: '/',
        filename: 'assets/js/main.js'
    },
    devtool: "inline-source-map",
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ['@babel/preset-env'],
                        babelrc: false
                    }
                }
            },
            {
                test: /\.(css|scss)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'resolve-url-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            importer: magicImporter(),
                            sourceMap: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [      
        new MiniCssExtractPlugin({
            filename: 'assets/css/main.css'
        }),

        new CopyWebpackPlugin([
            {
                from: 'assets/img/**/*',
                to: 'assets/img/',
                flatten: true
            },
            {
                from: 'assets/video/**/*',
                to: 'assets/video/',
                flatten: true
            },
            {
                from: 'assets/webvtt/**/*',
                to: 'assets/webvtt/',
                flatten: true
            },
            {
                from: 'favicon.ico',
                to: ''
            },
            {
                from: '*.png',
                to: ''
            }
        ])
    ],
    optimization: {
        minimizer: []
    }
};

if (process.env.NODE_ENV === 'production') {
    module.exports.optimization.minimizer.push(
        new UglifyJsPlugin({
            cache: false,
            parallel: true,
            sourceMap: false,
            uglifyOptions: {
                warnings: false,
                parse: {},
                compress: {},
                mangle: true,
                output: null,
                toplevel: false,
                nameCache: null,
                ie8: false,
                keep_fnames: false
            },
            extractComments: {
                condition: /^\**!|@preserve|@license|@cc_on/i,
                filename: 'assets/js/extracted-comments.js'
            }
        }),
        new OptimizeCSSAssetsPlugin({})
    );
}

For reference, this line has always been in fractal.js:

fractal.web.set('builder.dest', __dirname + '/dist');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM