[英]How to import CSS modules with Typescript, React and Webpack
How to import CSS modules in Typescript with Webpack?如何使用 Webpack 在 Typescript 中导入 CSS 模块?
Generate (or auto-generate) .d.ts
files for CSS?为 CSS 生成(或自动生成) .d.ts
文件? And use classic Typescript import
statement?并使用经典的 Typescript import
语句? With ./styles.css.d.ts
:使用./styles.css.d.ts
:
import * as styles from './styles.css'
Import using require
Webpack function?使用require
Webpack 功能导入?
let styles = require("./styles.css");
But for the last approach I must define the require
function.但对于最后一种方法,我必须定义require
函数。
What is the best approach or best option and one that can also handle IntelliSense for the CSS file definitions and classes?最好的方法或最佳选择是什么,并且还可以处理 CSS 文件定义和类的 IntelliSense?
A) As you are saying, there is one simplest (not best) option to use require : A)正如您所说,有一个最简单(不是最好)的选项可以使用require :
const css = require('./component.css')
require
as it's not standard feature in typescript.我们需要对require
进行打字,因为它不是打字稿中的标准功能。Simplest typing for this specific require may be:针对此特定要求的最简单输入可能是:
declare function require(name: string): string;
Webpack will then compile typescript and use modules properly - BUT without any IDE help and class names checks for build .然后 Webpack 将编译打字稿并正确使用模块 -但没有任何 IDE 帮助和类名检查 build 。
B) There is better solution to use standard import : B) 使用标准导入有更好的解决方案:
import * as css from './component.css'
tsc
compiler will fail需要为每个 css 文件定义类型,否则tsc
编译器将失败For proper IntelliSense, Webpack needs to generate types definition for each css file:为了正确的 IntelliSense,Webpack 需要为每个 css 文件生成类型定义:
Use webpack typings-for-css-modules-loader使用 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 will generate *.css.d.ts
files for each of css files in your codebase Loader 将为代码库中的每个 css 文件生成*.css.d.ts
文件
Mentioned typings-for-css-loader
contains a bug and because of types file generation delay, it's best to declare global *.css
type in case our *.css.d.ts
file is not generated yet.提到的typings-for-css-loader
包含一个错误,由于类型文件生成延迟,最好声明全局*.css
类型,以防我们的*.css.d.ts
文件尚未生成。
That little bug scenario:那个小错误场景:
component.css
创建 css 文件component.css
import * as css from './component.css'
将它包含在组件import * as css from './component.css'
webpack
运行webpack
component.css.d.ts
), but it's late for typescript compiler to find new typings file加载器会生成 Css 模块类型文件( component.css.d.ts
),但是打字稿编译器找到新的类型文件已经晚了webpack
again will fix build error.再次运行webpack
将修复构建错误。 Easy fix is to create global definition (eg. file called typings.d.ts
in your source root) for importing CSS Modules:简单的解决方法是为导入 CSS 模块创建全局定义(例如,在源根目录中名为typings.d.ts
文件):
declare module '*.css' {
interface IClassNames {
[className: string]: string
}
const classNames: IClassNames;
export = classNames;
}
This definition will be used if there is no css file generated (eg. you have added new css file).如果没有生成 css 文件(例如,您添加了新的 css 文件),将使用此定义。 Otherwise will be used generated specific (needs to be in same folder and named same as source file + .d.ts
extension) , eg.否则将使用生成的特定(需要在同一文件夹中并与源文件+ .d.ts
扩展名相同) ,例如。 component.css.d.ts
definition and IntelliSense will work perfectly. component.css.d.ts
定义和 IntelliSense 将完美运行。
Example of component.css.d.ts
: component.css.d.ts
示例:
export const wrapper: string;
export const button: string;
export const link: string;
And if you don't want to see generated css typings you may setup filter in IDE to hide all files with extension .css.d.ts in your sources.如果您不想看到生成的 css 类型,您可以在 IDE 中设置过滤器以隐藏源中扩展名为 .css.d.ts 的所有文件。
I have added a file named Global.d.ts
or typings.d.ts
to my ./src
folder with some type definitions:我添加了一个名为Global.d.ts
或typings.d.ts
我./src
一些类型定义文件夹:
declare module "*.module.css";
Webpack css config: Webpack css 配置:
{
test: /\.css$/,
use: [
isProductionBuild ? MiniCssExtractPlugin.loader : "style-loader",
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: "[name]_[local]_[hash:base64]",
sourceMap: true,
minimize: true
}
}
]
},
Then I simply import the module like: import styles from "./App.module.css";
然后我简单地导入模块,如: import styles from "./App.module.css";
Now in the year 2021, all you need to do is add a src/Globals.d.ts
to your project with these lines:现在是 2021 年,您需要做的就是使用以下src/Globals.d.ts
添加到您的项目中:
declare module "*.module.css";
declare module "*.module.scss";
// and so on for whatever flavor of css you're using
Then install and add然后安装并添加
{
"compilerOptions": {
"plugins": [{ "name": "typescript-plugin-css-modules" }]
}
}
to your tsconfig.到您的 tsconfig。
Example of this correctly functioning in VS code after making that simple change (root is a class defined in my stylesheet):进行简单更改后在 VS 代码中正确运行的示例(root 是我的样式表中定义的类):
Webpack and tsc also compile correctly on the command line. Webpack 和 tsc 也可以在命令行上正确编译。
In 2022, all I needed to do it to add Globals.d.ts
file under the src
folder在 2022 年,我需要做的就是在src
文件夹下添加Globals.d.ts
文件
with和
declare module "*.module.css";
declare module "*.module.scss";
Then I can import CSS modules in my typescript files as usual for css or scss files:然后我可以像往常一样为 css 或 scss 文件在我的打字稿文件中导入 CSS 模块:
import styles from "./Team.module.scss";
Or import using require webpack function或者使用 require webpack 函数导入
This is just what I used to do and still have that code in a few of my projects out there.这正是我过去所做的,并且仍然在我的一些项目中使用该代码。
Now : I wrote typestyle : http://typestyle.github.io/#/ but you don't have to use it.现在:我写了 typestyle : http ://typestyle.github.io/#/ 但你不必使用它。 Just stick with const styles = require('./styles.css')
if it makes you happy.如果它让你开心,就坚持使用const styles = require('./styles.css')
。 FWIW you can also use raw css with typestyle if you want http://typestyle.github.io/#/raw FWIW 如果你想要http://typestyle.github.io/#/raw,你也可以使用带有 typestyle 的原始 css
我认为现在打字稿可以通过简单地执行 import 'fileTobeImportedPath.css' 来导入 css 文件
This case is related to Typescript.此案例与 Typescript 相关。 You can add typings.d.ts
in your project with this content:您可以使用以下内容在项目中添加typings.d.ts
:
declare module "*.module.css";
declare module "*.module.scss";
It is good practice to use file name with *.module.*
format if you want to enable CSS Module.如果要启用 CSS 模块,最好使用带有*.module.*
格式的文件名。
css-loader
will enable CSS Module automatically for files with name that satisfy this RegEx: /\\.module\\.\\w+$/i
. css-loader
将自动为名称满足此正则表达式的文件启用 CSS 模块: /\\.module\\.\\w+$/i
。 This feature is customable by setting options.modules
property as an object.此功能可通过将options.modules
属性设置为对象来定制。
For example:例如:
import style from './App.module.css'; // CSS Module enabled
import './index.css'; // Plain CSS loaded
For recent configuration, you can add this rule to webpack.config.js
:对于最近的配置,您可以将此规则添加到webpack.config.js
:
{
test: /\.css$/,
use: [
'style-loader',
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[hash:base64]", // default
auto: true // default
},
sourceMap: true
}
},
]
},
A custom configuration example:自定义配置示例:
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]_[local]_[hash:base64]", // custom class name format
auto: /\.cmod\.\w+$/i, // custom auto enable CSS Module for "*.cmod.css" format
},
}
},
I use create-react-app
, but for some reason other solutions didn't work, something was missing;我使用create-react-app
,但由于某种原因其他解决方案不起作用,缺少了一些东西; I think it's because VS Code
uses its own TypeScript
vesrion.我认为这是因为VS Code
使用了自己的TypeScript
版本。 So here is all I did until it finally worked;所以这就是我所做的一切,直到它最终起作用; if you use create-react-app
& VS Code
it should work for you as well:如果您使用create-react-app
和VS Code
,它也应该适用于您:
npm i typescript-plugin-css-modules --save-dev
运行npm i typescript-plugin-css-modules --save-dev
styles.d.ts
(or something like this) and paste the following content:在项目的根文件夹中,创建一个名为styles.d.ts
(或类似名称)的文件并粘贴以下内容:styles.d.ts样式.d.ts
// if you use css
declare module "*.module.css" {
const classes: { [key: string]: string };
export default classes;
}
// if you use scss
declare module "*.module.scss" {
const classes: { [key: string]: string };
export default classes;
}
// if you use less
declare module "*.module.less" {
const classes: { [key: string]: string };
export default classes;
}
.vscode/settings.json .vscode/settings.json
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
So, the file might look like so:因此,该文件可能如下所示:
.vscode/settings.json .vscode/settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
let styles = require("./styles.css");
is the best approch because it is es5 version of javascript which is compatible with every feature of react.是最好的方法,因为它是 es5 版本的 javascript,与 react 的每个功能兼容。 import * as styles from './styles.css'
is es6 version of javascript. import * as styles from './styles.css'
是 es6 版本的 javascript。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.