Как я могу настроить разные customProperties в postcss.config.js для разных точек входа в Webpack?

Я использую Webpack 4.

У меня есть две точки входа в мой webpack.config.js, для каждого из которых я генерирую отдельный файл CSS, используя mini-css-extract-plugin,

const webpack = require('webpack')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    mode: 'development',
    entry: {
        foo: './foo.js',
        bar: './bar.js'
    },
    output: {
        path: path.resolve(__dirname, 'src/'),
        filename: 'js/[name].js'
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].css"
        })
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    "css-loader", "postcss-loader"
                ]
            }
        ]
    }
}

Я также использую postcss-cssnext.

В моем postcss.config.js файл в моей корневой папке, я определяю ряд переменных CSS в customProperties, как это:

module.exports = {
    plugins: {
        'postcss-cssnext': {
            features: {
                customProperties: {
                    variables: {
                        color1: '#333',
                        color2: '#53565A',
                        baseFont: 'Helvetica, sans-serif'
                    }
                }
            }
        }
    }
}

Если бы я хотел, чтобы мои переменные CSS имели разные значения для каждой из двух моих точек входа, как бы я поступил так?

Например, скажем, в foo.css я хочу var(--color1) равному #333, но в bar.css я хочу, чтобы он равнялся #860000,

3 ответа

Решение

Я понял это. Вот как я это решил.

Я переключил свой файл webpack.config, чтобы иметь несколько конфигураций, по одной для каждой точки входа. Я также настроил postcss-loader для передачи точки входа в качестве контекста в postcss.config.js.

webpack.config.js

const webpack = require('webpack')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const entryPoints = ['foo', 'bar']

const config = entry => ({
  mode: 'development',
  entry: `./${entry}.js`,
  output: {
    path: path.resolve(__dirname, 'src/'),
    filename: `js/${entry}.js`
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: `css/${entry}.css`
    })
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          'css-loader', 
          {
            loader: 'postcss-loader',
            options: {
              config: {
                ctx: { entry }
              }
            }
          },
        ]
      }
    ]
  }
})

module.exports = entryPoints.map(entry => config(entry))

Мой файл postcss.config.js может быть условно настроен на основе точки входа. В этом примере я определяю встроенные стили, но они могут быть извлечены из внешнего модуля через require,

postcss.config.js

module.exports = ({ options }) => ({
  plugins: {
    'postcss-cssnext': {
      features: {
        customProperties: {
          variables: 
            options.entry === 'foo' ? 
              {
                color1: '#333',
                color2: '#53565A',
                baseFont: 'Helvetica, sans-serif'
              } :
              {
                color1: '#860000',
                color2: '#555',
                baseFont: 'Arial, sans-serif'
              }
        }
      }
    }
  }
})

Наконец, решение - это слои веб-пакета...

      const Path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = (env, options) => {
    return {
        entry : {
            desktop : { import : './desktop.js', layer : 'desktop' },
            mobile : { import : './mobile.js', layer : 'mobile' },
        },
        module : {
            rules : [
                {
                    test : /\.js$/,
                    exclude : /node_modules/,
                    loader : 'babel-loader',
                    options : {
                        presets : ['@babel/preset-env'],
                    },
                },
                {
                    test : /\.css$/,
                    oneOf : [
                        {
                            issuerLayer: 'desktop',
                            use : [
                                { loader : 'some-loader', options : { } },
                            ],
                        },
                        {
                            issuerLayer: 'mobile',
                            use : [
                                { loader : 'another-loader', options : { } },
                            ],
                        },
                    ]
                },
            ],
        },
        output : {
            path : Path.resolve(__dirname, 'public'),
            filename : '[name].js',
        },
        plugins : [
            new MiniCssExtractPlugin({ filename : '[name].css' }),
        ],
        experiments: {
            layers : true,
        },
    };
};

См. пример репо: https://github.com/nolimitdev/webpack-layer-example .

Вы также можете попробовать env.file.basename в postcss.config.js:

module.exports = (env, args) => ({
    plugins: {
        'postcss-cssnext': {
            features: {
              customProperties: {
                variables: 
                    env.file.basename === 'foo' ? 
                    {
                      color1: '#333',
                      color2: '#53565A',
                      baseFont: 'Helvetica, sans-serif'
                    } :
                    {
                      color1: '#860000',
                      color2: '#555',
                      baseFont: 'Arial, sans-serif'
                    }
                }
            }
        }
    }
})
Другие вопросы по тегам