【问题标题】:How to combine `css-modules` with normal `sass`, preferably in `webpack`如何将`css-modules`与普通`sass`结合,最好在`webpack`中
【发布时间】:2017-02-23 01:10:42
【问题描述】:

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

设置:

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

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

问题:

我想将 webpack css-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'],
    },
}

【问题讨论】:

    标签: sass webpack css-modules


    【解决方案1】:

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

    为此,您可以在加载程序中使用excludeinclude 选项。 IE。如果您在 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\//
        },
      ],
      ...
    }
    

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

    编辑:

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

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

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

    【讨论】:

    • 这肯定让我更进一步,但我需要通过ExtractTextPlugin.extract 输出两个块。当我这样设置时,webpack 声称两个块都在输出 css 中,但只有第二个块在其中。
    • 输出两个块:screencast.com/t/Rn9tpQ36A。输出小于只有一个块:screencast.com/t/Vt2cbfrwv
    • 我应该提到我确实尝试使用allChunks : true,但当它不起作用时,我尝试使用两个指向相同文件名的ExtractTextPlugin 实例。两者都产生了与上述相同的结果。
    • 您有什么建议吗?
    • 你能分享你的 webpack 配置吗?我认为,如果您将ExtractTextPlugin.extract 用于全局样式,而将另一个用于单页,则在加载器部分使用include/exclude 选项,在插件部分使用new ExtractTextPlugin('bundle.css', { allChunks: true }),它应该可以工作
    猜你喜欢
    • 2017-02-18
    • 2019-08-31
    • 2016-10-16
    • 2016-06-24
    • 2014-04-15
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2020-10-11
    相关资源
    最近更新 更多