如何将 CSS 模块的类型声明编写为 ES 模块

Posted

技术标签:

【中文标题】如何将 CSS 模块的类型声明编写为 ES 模块【英文标题】:How to write a type declaration for a CSS Module as ES Module 【发布时间】:2021-07-25 00:12:15 【问题描述】:

我正在将 Gatsby 从 v2 升级到 v3,在此更新中CSS Modules are imported as ES Modules。

网络向前发展,我们也在向前发展。 ES Modules 让我们能够更好地摇树并生成更小的文件。从现在开始,您需要将 CSS 模块导入为:import box from './mystyles.module.css'

旧方法将不再编译。

更改导入后,它可以正确编译并按预期显示。唯一的问题是,由于找不到导出,我遇到了类型错误。

我的假设是,类型声明是错误的,但我不确定如何在不将每个可能的 CSS 类命名为导出的情况下动态键入它。

我也试过import * as styles,首先不鼓励这样做(因为它可以防止摇树),但也会导致类型错误。

Foo.module.css:

.foo  color: red; 
.bar  color: blue;  

Foo.tsx:

import  foo, bar  from "./Foo.module.css"
// Module "*.module.css" has no exported member 'foo'
// Module "*.module.css" has no exported member 'bar'

css.d.ts:

declare module "*.module.css" 
    const styles:  [className: string]: string 
    export * from styles

【问题讨论】:

尝试将css.d.ts重命名为global.d.tsglobals.d.ts 感谢您的参与。声明文件被拾取得很好。如果我手动在其中输入我所有的类名,它将接受它。这很乏味,而且不是一个可行的解决方案...... 你得到的错误是告诉你出了什么问题。你需要import styles from "./Foo.module.css" 这篇文章可能会派上用场 -> skovy.dev/… 谢谢,T先生。我已经阅读了这篇文章,这确实是今天在 Gatsby V2 中的工作方式,但正如问题中的链接中所解释的那样,Gatsby V3 要求样式为作为 ES 模块导入。这意味着导入应该是import foo from './Foo.module.css'。该解决方案将无法使用旧方法进行编译。新方法完美运行,除了类型错误。我将修改问题以使这一点更清楚。 【参考方案1】:

我认为唯一的方法是使用:

import styles from "./Foo.module.css";

除非您能够从 d.ts 中的 css 文件中导出单个样式:

declare module '*.css' 
  const styles: 
    [className: string]: string;
    foo: string;
    bar: string;
  ;
  export default styles; 

顺便说一句,您的类型声明中的语法不正确,如果您在导出语句中使用 from,那么它需要一个字符串(路径或 npm 包名称)。

【讨论】:

【参考方案2】:

我遇到了同样的问题,以下似乎对我有用:

declare module "*.module.css" 
    const styles:  [className: string]: string 
    export = styles

然而,这可能是对 TypeScript 的滥用,因为根据TypeScript documentation,export = 语法应该适用于 CommonJS 和 AMD 模块,它代表这些模块系统中的 exports

【讨论】:

以上是关于如何将 CSS 模块的类型声明编写为 ES 模块的主要内容,如果未能解决你的问题,请参考以下文章

如何将用 ES6 编写的模块发布到 NPM?

微软提出CSS Modules V1 :通过import语句将CSS模块导入到组件中

模块调用端口的连接规则

ES6的模块加载器也能加载资产吗(html/css/...)

如何使用 babel 插件将 commonjs 转换为 es2015 模块?

带有 postcss 和 css 模块的 Tailwindcss