如何使用 Nuxt 正确导入 CSS 模块?

Posted

技术标签:

【中文标题】如何使用 Nuxt 正确导入 CSS 模块?【英文标题】:How to import CSS-Modules correctly with Nuxt? 【发布时间】:2019-08-08 01:04:13 【问题描述】:

我正在使用带有 Nuxt 的 CSS 模块,并且在尝试在我的 js 中导入样式表时遇到了一些问题。如果我将样式表直接导入...

<style module>
   @import './index.css';
</style>

...一切都按预期进行。在我的特殊情况下,我需要运行一个计算属性来在两个不同的样式表之间进行选择,因此我需要导入 &lt;style module&gt; 而不是通过 &lt;script&gt; 导入并实现如下样式:

<script>
import foo from './index.css'
export default 
  computed: 
    styles() 
      return foo
    
  

</script>

在 vue 上实现这一点时,一切都很好,我得到了一个样式对象返回。然而,Nuxt 返回一个空对象,并且我的样式都没有正确呈现。

我在我的 nuxt.config.js 文件中激活 CSS 模块,如下所示:

export default 
  ...
    loaders: 
      css: 
        modules: true
      
    
  ...

这是 Nuxt s-s-r 的问题吗?我一直在寻找根本原因/解决方案,但在我的搜索中运气不佳。

更新

在听取 ivandata 的建议并将此代码添加到我的构建脚本后:

export default 
  ....
  build: 
    extend (config, ctx) 

      const cssLoader = config.module.rules.find(rule => 
        return rule.test.toString() === '/\\.css$/i';
      );

      delete cssLoader.oneOf[0].resourceQuery;

      ...
    
  

CSS 模块似乎可以工作,但出现了一个新问题,即现在该项目不理解任何不是 css-modules 的 vue-component 样式。经过一番研究,我发现resourceQuery 告诉加载器将加载器选项应用于哪种类型的文件。

我尝试过深入了解 vue.cli 3 上的样式加载器,并将其与 Nuxt 进行比较。我删除了 ivandata 的 snippit,并尝试匹配 vue 和 nuxt 的加载器,但问题仍然存在。

以下是在启用和禁用 ivandata 代码之间视觉上发生的情况:

已禁用

已启用

这是我的项目中正在发生的事情的代码 sn-p:

<template>
  <section :class="style.container">
    <h1>hey</h1>
    <h2 class="test">hey</h2>
  </section>
</template>

<script>
import style from './index.css'
export default 
  computed: 
    style() 
      return style
    
  

</script>

<style>
  h1 
    font-size: 100px;
  

  .test 
    font-size: 100px;
  
</style>

所以你可以看到我在 css-loader 中是否有 resourceQuery,我的 css javascript 导入不起作用,但所有 vue-component 样式都正常工作。一旦我删除了resourceQuery,js 导入的样式表就可以工作,但是 vue-template 样式类不再工作。我不认为解决方案在于删除resourceQuery,我很好奇这是否与另一个加载程序完全有关。我已经通过 vue.cli 3 加载器进行了相当多的挖掘,但看不到任何明显突出的东西。

【问题讨论】:

【参考方案1】:

好的,这是另一种方式。留下你的旧代码。删除我的代码并添加 ?module 以导入文件路径:

<script>
  import foo from './index.css?module'
  export default 
    computed: 
      styles() 
        return foo
      
    
  
</script>

我错了。 resourceQuery 选项用于针对请求字符串的查询部分进行测试。

【讨论】:

【参考方案2】:

你不需要在 nuxt 中激活 css-modules,它们默认是激活的。 Nuxt.js 使用 vue-style-loader 加载样式。 https://vue-loader.vuejs.org/guide/css-modules.html#opt-in-usage 默认情况下,所有样式都从带有模块属性的样式标签加载,因为样式加载器在 oneOf 规则中使用resourceQuery /module/。因此,如果删除此属性,nuxt 将根据需要加载样式。

export default 
  ....
  build: 
    extend (config, ctx) 

      const cssLoader = config.module.rules.find(rule => 
        return rule.test.toString() === '/\\.css$/i';
      );

      delete cssLoader.oneOf[0].resourceQuery;

      ...
    
  

【讨论】:

非常感谢,我不得不将 cssLoader 更改为 scssLoader 但它成功了。我可以说 css-modules 已自动启用,但它没有 Vue 发生的默认行为。不能说我完全理解这有什么帮助,但也许是时候让我更深入地了解样式加载器了。 实际上我最初在我的测试项目中实现了这个并且效果很好,但是将它添加到我的主项目中断和不是 css-modules 的代码。是否可以定义哪些文件使用它? 你是什么意思?它是作用域 css 还是预处理器?无论如何,您可以通过相同的技巧更改或替换 nuxt 加载器。实际上 Webpack 使用 Nuxt.config。因此,您可以在config.module.rules 中检查所有使用过的加载器并根据需要进行更改。 所以我在导入到 nuxt 的包中使用 css-modules。 nuxt 项目样式是 scss,并且范围在它们自己的组件中。如果启用此代码,我看到的问题是任何非 css-modules 的作用域样式在构建中都会被忽略。 如果您有机会重新访问,我在上面添加了附加说明。感谢您的帮助。【参考方案3】:

nuxt 版本:2.0.0。 你只需要交换作用域到模块,例如:

<template>
  <div :class="$style.red">TEST</div>
</template>
<style module>
  .redcolor:red;
</style>

【讨论】:

以上是关于如何使用 Nuxt 正确导入 CSS 模块?的主要内容,如果未能解决你的问题,请参考以下文章

Nuxt Vue 中的 Splidejs

如何在 nuxt.js 中挑选 bootstrap-vue.js 模块?

如何在 Nuxt 的 nuxt.config.js 中导入 mdi 图标模块

从 JS 文件访问 Nuxt 存储(在模块模式下)

无法在我的 Nuxt 项目中使用“node”命令导入 ES 模块

如何将图像导入 CSS 模块?