Webpack 4:有条件地启用 PostCSS 插件
Webpack 4: Conditionally enabling PostCSS plugins
我已经将 PostCSS 集成到 Webpack 中,使用单独的 postcss.config.js
文件。
我想在进行生产构建时启用 cssnano
,而在开发构建时禁用它。我该怎么做?
这是我的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;
}
这是我的postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-url'),
require('autoprefixer'),
require('cssnano')({
preset: 'default',
})
]
}
其次,是否推荐单独postcss.config.js
?我看到一些示例,其中 PostCSS 插件在 webpack.config.js
中定义,而其他示例则全部在单独的文件中完成。
方案1.使用webpack merge
使用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
选项 2. 使用不同的配置
可以创建两个单独的文件 webpack.config.prod.js
和 webpack.config.dev.js
并使用不同的 npm 脚本调用它们。该解决方案的问题是存在重复代码。
在你的postcss.config.js
中你可以checking for the environment property:
module.exports = ({ env }) => ({
plugins: [
require('postcss-import')(),
require('postcss-url')(),
require('autoprefixer')(),
env === 'production' ? require('cssnano')({preset: 'default' })() : false,
]
})
我已经将 PostCSS 集成到 Webpack 中,使用单独的 postcss.config.js
文件。
我想在进行生产构建时启用 cssnano
,而在开发构建时禁用它。我该怎么做?
这是我的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;
}
这是我的postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-url'),
require('autoprefixer'),
require('cssnano')({
preset: 'default',
})
]
}
其次,是否推荐单独postcss.config.js
?我看到一些示例,其中 PostCSS 插件在 webpack.config.js
中定义,而其他示例则全部在单独的文件中完成。
方案1.使用webpack merge
使用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
选项 2. 使用不同的配置
可以创建两个单独的文件 webpack.config.prod.js
和 webpack.config.dev.js
并使用不同的 npm 脚本调用它们。该解决方案的问题是存在重复代码。
在你的postcss.config.js
中你可以checking for the environment property:
module.exports = ({ env }) => ({
plugins: [
require('postcss-import')(),
require('postcss-url')(),
require('autoprefixer')(),
env === 'production' ? require('cssnano')({preset: 'default' })() : false,
]
})