如何使用webpack提取多个主题样式表?

时间:2016-07-14 20:40:13

标签: reactjs sass webpack

我正在尝试将React应用程序设为主题。目前,主题只包含不同的Sass变量集,它们定义了不同的标题颜色等。

根据我目前的理解,ExtractTextPlugin似乎是我最好的选择,因为我不希望我的样式被内联,而是每个主题都有单独的文件。

所以我创建了两个主题:

src/scss/themes/theme-a.scss
src/scss/themes/theme-b.scss

主题导入基本布局和常用样式并覆盖相关变量。

但我设法制作webpack的唯一方法是创建单独的css文件 两个主题都是为每个主题创建不同的入口点 我的webpack.prod.config

entry: {
  app: './src/js/init.js',
  theme-a: './src/scss/themes/theme-a.scss',
  theme-b: './src/scss/themes/theme-b.scss'
},

但是为每个新添加的主题添加一个新的入口点会感觉不对,我觉得必须有更好的方法吗?

2 个答案:

答案 0 :(得分:10)

这是您的解决方案:

npm i --save-dev file-loader

loaders部分,添加以下内容:

{
    test: /themes\/.+\.scss$/,
    loader: "file-loader?name=./compiled-themes/css/[name].css!css!sass"
},

可能有更多的scss文件,如果是这样的话,必须有另一个部分像往常一样捆绑它们,但跳过主题:

{
    test: /\.scss$/,
    exclude: /themes\/.+\.scss$/,
    loader: "css!sass"
},

文件加载器按文件名,散列和扩展名写入文件,因此您可以保留名称。

请注意name=./compiled-themes/css/[name].css部分,其中[]代替。

https://github.com/webpack/file-loader

答案 1 :(得分:2)

为了避免必须手动添加主题,一种可能的解决方案是创建一个读取主题文件夹内容的函数,并以编程方式为每个* .scss文件添加一个条目。

有些事情如下:

function getThemes(themePath) {
    var themes = {};
    fs.readdirSync(themePath).forEach(function(fileName) {
        var fileNameWithPath = path.join(themePath, fileName);

        var stat = fs.lstatSync(fileNameWithPath);
        if (stat.isDirectory()) return;
        if (!/\.scss$/.test(fileName)) return;

        var nameWithoutExt = path.basename(fileName, '.scss');
        themes[nameWithoutExt] = fileNameWithPath;
    });

    return themes;
}

var themes = getThemes('./src/scss/themes');

var config= {
    entry: _.merge({ app: './src/js/init.js' }, themes),
    // rest of options
};

这将要求您在添加新的主题文件时重新启动您的开发服务器或重新运行webpack构建,但至少您不必触摸您的webpack配置。