4

TLDR:如何css-modules与 normal结合sass,最好在webpack.

设置:

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

我最近添加了一个使用react with webpackbabel构建的单页应用程序。在该应用程序内部,我利用webpack提供的css-modules将类名限定为每个反应组件。

问题:

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

问题:

  • 有没有一种合适的方法来解耦 webpack 构建,其中一个仍然能够使用另一个块?

  • 如果是这样,我该怎么做才能使css-module设置保持在单页配置中,并且extract-text-webpack与无聊的 sass 构建一起进入全局配置的部分?

  • 如果没有,我应该如何让 sass 的一部分通过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'],
    },
}
4

1 回答 1

1

如果我理解您的问题,您只想将 css-modules 应用于应用程序的一部分,而在其他部分留下简单的 sass 构建过程。

为此,您可以在加载程序中使用exclude和选项。include即,如果您在single-page目录中有单页应用程序,您的 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\//
    },
  ],
  ...
}

所以,在这种情况下,所有的 csssingle-page/都将使用 css 模块,而其余的则不会。

编辑:

如果您查看 ExtractTextPlugin 文档的API部分,您会发现

ExtractTextPlugin 为每个条目生成一个输出文件,因此在使用多个条目时必须使用 [name]、[id] 或 [contenthash]。

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

于 2016-10-17T15:39:43.040 回答