A) 就像你所说,使用 require 的最简单选项(不是最好的)有一种:
const css = require('./component.css')
- 由于TypeScript中没有标准的功能,我们需要为
require
编写类型定义。
这个特定的require
最简单的类型定义可能是:
declare function require(name: string): string;
Webpack将编译TypeScript并正确使用模块 - 但是在构建时没有任何IDE帮助和类名检查。
B) 有更好的解决方案可以使用标准import:
import * as css from './component.css'
- 启用完整的类名 IntelliSense
- 每个CSS文件都需要类型定义,否则
tsc
编译器将失败
为了正确的 IntelliSense,Webpack 需要为每个 CSS 文件生成类型定义:
使用 webpack typings-for-css-modules-loader
webpackConfig.module.loaders: [
{ test: /\.css$/, loader: 'typings-for-css-modules?modules' }
{ test: /\.scss$/, loader: 'typings-for-css-modules?modules&sass' }
];
Loader将为代码库中的每个CSS文件生成*.css.d.ts
文件。
Typescript编译器将理解CSS导入将是具有类型为字符串的属性(类名)的模块。
提到的typings-for-css-loader
包含一个错误,由于类型文件生成的延迟,最好在我们的*.css.d.ts
文件尚未生成时声明全局*.css
类型。
那种小错误场景:
- 创建CSS文件
component.css
- 在组件中包含它
import * as css from './component.css'
- 运行
webpack
- Typescript编译器将尝试编译代码(错误)
- 加载器将生成Css模块类型文件(
component.css.d.ts
),但对于Typescript编译器来说太晚了,找不到新的类型文件。
- 再次运行
webpack
将修复构建错误。
简单的解决方法是为导入CSS模块创建全局定义(例如,在源根目录中创建一个名为typings.d.ts
的文件):
declare module '*.css' {
interface IClassNames {
[className: string]: string
}
const classNames: IClassNames;
export = classNames;
}
如果没有生成CSS文件(例如,您添加了新的CSS文件),则会使用此定义。否则,将使用生成的特定(需要在同一文件夹中命名与源文件相同并以.d.ts
扩展名),例如component.css.d.ts
定义,IntelliSense将完美地工作。
component.css.d.ts
的示例:
export const wrapper: string;
export const button: string;
export const link: string;
如果你不想看到生成的 CSS 类型文件,你可以在 IDE 中设置过滤器,隐藏所有扩展名为 .css.d.ts 的源文件。
import * as styles from ...
或import styles = require(...
都是有效的。你可能需要为你的 CSS 文件声明一个模块,无论是显式的还是通用的所有 CSS 文件都可以,因为 TypeScript 编译器对此一无所知。请参见这里以获取自动生成定义的生成器。 - Meirion Hughes