Sass 与 CSS 模块和 Webpack

Posted

技术标签:

【中文标题】Sass 与 CSS 模块和 Webpack【英文标题】:Sass with CSS Modules & Webpack 【发布时间】:2016-03-30 08:52:06 【问题描述】:

我一直在使用 Webpack、Sass 和 CSS 模块构建一个项目。通常在我的.scss 文件中,我定义了一个类:

:local(.button) 
    color: white;

在我的 React 组件中,在 render 方法中,我需要样式:

render = () => 
    const styles = require('./MyStyles.scss');
    <div className= styles.button  />

世界上一切都很好。一切都按预期工作。

今天我正在阅读CSS Modules page 并注意到没有一个选择器像我的那样被:local() 包含,而且他们正在导入如下样式:

import styles from './MyStyles.scss';

我想“哇,看起来好多了,更容易看到它是在哪里导入的,等等。我不想使用:local(),而默认情况下只有本地的东西。”所以我尝试了一下,然后立即遇到了几个问题。

1) `从'./MyStyles.scss'导入样式;

因为我在我的 React 文件上使用 ESLint,我立即收到一个错误,指出 MyStyles.scss 没有通常有意义的默认导出,但 CSS 模块页面指出:

从 JS 模块导入 CSS 模块时,它会导出一个对象,其中包含从本地名称到全局名称的所有映射。

所以我自然希望样式表的默认导出也是他们所指的对象。

2) 我试过import button from './MyStyles.scss';

这会通过 linting,但 button 记录为未定义。

3) 如果我恢复到 require 导入样式的方法,则任何未使用 :local 指定的内容都是未定义的。

作为参考,我的 webpack 加载器(我还包括 Node-Neat 和 Node-Bourbon,两个很棒的库):

 test: /.(scss|css)$/, loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap&includePaths[]=' + encodeURIComponent(require('node-bourbon').includePaths) +
'&includePaths[]=' + encodeURIComponent(require('node-neat').includePaths[1]) + '&includePaths[]=' + path.resolve(__dirname, '..', 'src/client/') 

我的问题是:

1) 在 Sass 中使用 CSS 模块时,我是否仅限于使用 :local:global

2) 既然我使用的是 webpack,那是否也意味着我只能 require 我的样式?

【问题讨论】:

我会转义加载程序的test 属性中的通配符 (.),如下所示:test: /\.(scss|css)$/ 【参考方案1】:

发布后不久,我想出了解决方案。这个问题,我认为很混乱,是在我的 Webpack 配置中。最初我的加载器看起来像:

loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap

这使我能够 1) require 我的 Sass 和 2) 将我的样式包装在 :local 中。

但是,css 加载器缺少 modules 选项,因此它看起来像:

loader: 'style!css?modules&sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap

现在我可以import 我的样式,我不必将它们包装在:local 中(尽管我认为如果我愿意我仍然可以)。

我发现所有这一切最有趣的是,没有modules 选项,人们仍然可以使用 CSS 模块式的功能,尽管有些限制。

编辑:

我注意到,对于任何查看此答案的人来说,未来的警告是,如果您使用 eslint-plugin-import 对 javascript 代码中的导入进行 lint,它会在导入样式时引发错误,例如:

import styles from './MyStyles.scss';

因为 CSS 模块导出生成的样式对象的方式。这确实意味着您需要执行require('./MyStyles.scss') 才能绕过任何警告或错误。

【讨论】:

当使用 eslint-plugin-import 时,你可以专门忽略你的 scss 文件。见:npmjs.com/package/eslint-plugin-import#importignore

以上是关于Sass 与 CSS 模块和 Webpack的主要内容,如果未能解决你的问题,请参考以下文章

将 sass/css 模块添加到 typescript react app

Sass与Compress实战:第五章

html Sass:定义健壮的CSS模块/组件#sass的方法

javascript 版本0.x的Material-UI排版(基于SASS和CSS模块)

如何在 Webpack 4 中启用 SASS 模块

Webpack:在 sass-loader、css-loader 上重复导入(模块:true)