简体   繁体   English

Webpack 4:有条件地启用PostCSS插件

[英]Webpack 4: Conditionally enabling PostCSS plugins

I've integrated PostCSS into Webpack, using a separate postcss.config file. 我已经使用单独的postcss.config文件将PostCSS集成到Webpack中。

I want to enable cssnano when doing production builds, and disable it for development builds. 我想在进行生产构建时启用cssnano ,并为开发构建禁用它。 How can I do this? 我怎样才能做到这一点?

Here is my webpack.config.js 这是我的webpack.config.js

const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');

const path = require('path');

module.exports = (env, argv) =>
{
    //const isProduction = (process.env.WEBPACK_MODE === 'production')
    const isProduction = argv.mode === 'production' || process.env.NODE_ENV === 'production';

    const config = {
        entry: './src/index.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].[contenthash].js',
            chunkFilename: '[name].[contenthash].js'
        },
        devtool: 'source-map',
        module: {
            rules: [
                {
                    test: /\.(sa|sc|c)ss$/,
                    use: [
                        // fallback to style-loader in development
                        //process.env.NODE_ENV !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                sourceMap: true
                            }
                        },
                        //'css-loader?-url',
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true,
                                sourceMap: true,
                                url: false
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                sourceMap: true
                            }
                        },
                        {
                            loader: 'resolve-url-loader',
                            options: {
                                sourceMap: true,
                                debug: false
                            }
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                sourceMap: true,
                                outputStyle: 'compressed',
                                sourceMapContents: false
                            }
                        }
                    ]
                }
            ]
        },

        plugins: [
            new CleanWebpackPlugin('dist', {
                watch: true
            }),
            new MiniCssExtractPlugin({
                // Options similar to the same options in webpackOptions.output
                // both options are optional
                filename: isProduction ? "live.[contenthash].css" : "live.css",
                chunkFilename: "[name].[contenthash].css"
            }),
            new ManifestPlugin()
        ]
    }

    return config;
}

Here is my postcss.config.js 这是我的postcss.config.js

module.exports = {
    plugins: [
        require('postcss-import'),
        require('postcss-url'),
        require('autoprefixer'),
        require('cssnano')({
            preset: 'default',
        })
    ]
}

Secondly, is a separate postcss.config.js recommended? 其次,是一个单独的postcss.config.js推荐? I see some examples where the PostCSS plugins are defined in webpack.config.js , and others where it's all done in the separate file. 我看到一些示例,其中PostCSS插件在webpack.config.js中定义,而其他示例则在单独的文件中完成。

Option 1. Use webpack merge 选项1.使用webpack合并

With webpack-merge , you can create conditional configurations based on the NODE_ENV and merge them in one single configuration at execution time, the advantage is that you don't create duplication of code and everything can be done in one file, the only disadvantage is using a new package. 使用webpack-merge ,您可以创建基于NODE_ENV条件配置,并在执行时将它们合并到一个配置中,优点是您不创建代码重复,一切都可以在一个文件中完成,唯一的缺点是使用新包。

const ENV = process.env.NODE_ENV

let Config = {

  //Other shared configurations by production and development

  plugins: [
    new webpack.ProgressPlugin(),
    new CopyWebpackPlugin([
      { from: 'public', to: 'public' },
    ])
  ]

}

if (ENV === 'production') {
  Config = merge(Config, {
    plugins: [
      new MiniCssExtractPlugin({
        filename: "public/styles.css"
      }),
      new OptimizeCSSAssetsPlugin({
        cssProcessor: cssnano,
        cssProcessorOptions: {
          parser: safe,
          discardComments: { removeAll: true }
        }
      })
    ],
    mode: 'production'
  })
}

if (ENV === 'development') {
  Config = merge(Config, {
    devtool: 'source-map',
    mode: 'development',
    plugins: [
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NamedModulesPlugin(),
      new StyleLintPlugin(
        {
          emitErrors: false,
          configFile: '.stylelintrc',
          context: 'src',
          files: '**/*.pcss',
        },
      ),
    ]
  })
}

const WebpackConfig = Config

Option 2. Use different configurations 选项2.使用不同的配置

Two separated files webpack.config.prod.js and webpack.config.dev.js can be created and call them with different npm scripts. 可以创建两个分离的文件webpack.config.prod.jswebpack.config.dev.js ,并使用不同的npm脚本调用它们。 The problem with this solution is that there is a duplication of code. 该解决方案的问题在于存在重复的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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