如何将`css-modules`与普通的`sass`结合起来,最好是在`webpack`中

TLDR:如何将css-modules与普通sass结合起来,最好是在webpack中.

设置:

我正在研究电子商务网站的样式构建过程.该网站的样式目前通过gulp browserify构建过程与js一起完成.

我最近添加了一个单页应用程序,使用webpack和babel做出反应.在该应用程序内部,我利用webpack提供的css-modules将类名称范围到每个反应组件.

问题:

我想将webpack css-modules内置的样式与网站的主要样式包合并.为此,我正在考虑构建一个webpack配置来构建整个站点的样式.我遇到的问题是如何获取当前由单页webpack配置构建的样式,并将样式块注入到处理整个站点样式的全局webpack配置中.我应该提一下,我希望将这两种配置尽可能分开

问题:

>有没有一种正确的方法来解耦webpack构建,其中一个仍然可以使用另一个的块?
>如果是这样,我该怎么做才能让css-module设置保持在单页配置中,而extract-text-webpack部分以及无聊的sass构建会进入全局配置?
>如果没有,我应该如何让css-modules工作流程中的一个部分通过css-modules工作流程,并仍然将它与来自网站其余部分的捆绑包结合起来.

提前致谢.

编辑
基于@Alexandr Subbotin的回答,我更新了我的webpack,看起来像下面的代码.我必须更改名称和路径,因为代码属于我的雇主,所以可能会有轻微的错误.

var ExtractTextPlugin = require('extract-text-webpack-plugin');

const JSDIR = './build/js/';
const STYLES = './build/css/bundle.css';

module.exports = {
    entry : {
        'styles'   : './src/styles.scss',
        'app'      : './src/index.js',
        // a javascript file that includes the root of the single page app.
        'single-page' : './src/single-page/styles-entry.js', 
    },
    output : {
        path     : JSDIR,
        filename : '[name].js', // normally compiles my 
        publicPath: 'http://localhost:8080/',
    },
    module: {
        loaders: [
          {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/,
            loader : 'babel-loader',
            query : {
                presets: [
                    'react','es2015','stage-0',
                ]
            },
          },
          {
            test : /\.scss$/,
            loader: ExtractTextPlugin.extract('style?sourceMap', 'css?-url&sourceMap!sass?sourceMap'),
            exclude : /\/single-page\//,
          },
          {
            test : /\.scss$/,
            loader: ExtractTextPlugin.extract(
              'style?sourceMap',
              'css?-url&modules&importLoaders=1&localIdentName=SinglePage__[name]__[local]!sass?sourceMap'
            ),
            include : /\/single-page\//,
          }
        ]
    },
    plugins : [
      new ExtractTextPlugin(STYLES, {
          allChunks : true,
      }),
    ],
    resolve : {
        alias: {
            "eventEmitter/EventEmitter": "wolfy87-eventemitter",
      },
      extensions: ['', '.js','.jsx'],
    },
}

最佳答案 如果我理解了您的问题,您只想将css-modules应用于应用程序的一部分,并将简单的sass构建过程留在其他部分.

为此,您可以在加载器中使用exclude和include选项.即如果你的单页面应用程序在单页目录中,你的webpack配置可以是:

module: {
  entry: {
    // it is your global sass styles
    application_css: './css/application.scss',
    // it is main file of your SPA bundle. Somewhere inside you will use require('./styles.scss') that should be processed by css-modules
    spa_index: './single-page/index.js'
  },
  loaders: [
    ...,
    {
      // This loader will build all your sass that are not in `single-page` directory
      test: /\.scss$/,
      loader: ExtractTextPlugin.extract('style', 'css!sass'),
      exclude: /\/single-page\//
    },
    {
      // This loader will handle all your css module in `single-page` directory
      test: /\.scss$/,
      loader: 'style!css?modules!sass',
      include: /\/single-page\//
    },
  ],
  ...
}

因此,在这种情况下,来自单页/的所有css将使用css模块,其余的则不会.

编辑:

如果你看一下你发现的ExtractTextPlugin文档的API部分

The ExtractTextPlugin generates an output file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.

在您的示例中,您有两个带有css(样式和单页)的块,但只有一个输出./build/css/bundle.css.如果您将输出更改为./build/css/[name].css,您将拥有两个css文件:styles.css与您的全局css和single-page.css与SPA样式.

点赞