Webpack: Generate multiple css files from the same

2019-04-10 14:51发布

I'm trying to generate 2 different CSS files from the same SCSS sources with webpack 2, in order to have alternate stylesheets without duplicating code. I've successfully generated both sheets separately by commenting one out, but can't figure out how to generate them at the same time. My webpack config (shortened for relevance) is:

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

const ExtractLightCss = new ExtractTextPlugin("app-light.css")
const ExtractDarkCss = new ExtractTextPlugin("app-dark.css")

module.exports = {
    ...
    module: {
        rules: [
            {
                test: /\.scss?$/,
                use: ExtractLightCss.extract({ fallback: "style-loader", use: ["css-loader", {loader: "sass-loader", options: {data: "$light: true;"}} ]})
            },
            {
                test: /\.scss$/,
                use: ExtractDarkCss.extract({ fallback: "style-loader", use: ["css-loader", {loader: "sass-loader", options: {data: "$light: false;"}} ]})
            },
           ...
        ]
    },    
    plugins: [
        ExtractLightCss,
        ExtractDarkCss
    ]
};

If I try to run webpack on this config, I get errors saying

ERROR in ./~/css-loader!./~/sass-loader?{"data":"$light: true;"}!./~/extract-text-webpack-plugin/loader.js?{"id":2,"omit":1,"remove":true}!./~/style-loader!./~/css-loader!./~/sass-loader?{"data":"$light: false;"}!./styles/[filename].scss

Which makes it look like it's running both sets of rules at the same time, rather than running one then the other.

Is there any way to do this?

1条回答
做自己的国王
2楼-- · 2019-04-10 15:39

I did further research and it appears there's no direct way to do this (I found https://survivejs.com/webpack/foreword/ to be a great resource). However I did find a work-around. I used 'composing-configuration' to create my module rules in a way that prevented duplication, then exported both configurations so webpack builds them simultaneously. A simplified example is:

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const merge = require('webpack-merge');

const deploymentSass = (light) => {
    return {
        module: {
            rules: [
                {
                    test: /\.scss?$/,
                    use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader", {
                        loader: "sass-loader",
                        options: {
                            data: light ? "$light: true;" : "$light: false;",
                        }} ]}),
                },
            ],
        },
        plugins: [
            new ExtractTextPlugin(`app-${light ? 'light' : 'dark'}.css`),
        ],
    };
};

const lightTheme = merge(qaConfig,                     
                    deploymentSass(true));

const darkTheme = merge(qaConfig, 
                    deploymentSass(false));

module.exports = [
    lightTheme,
    darkTheme,
]

This isn't a perfect solution since it involves 2 builds, but it lets me generate both stylesheets without code duplication

查看更多
登录 后发表回答