【问题标题】:How to import CSS modules with Typescript, React and Webpack如何使用 Typescript、React 和 Webpack 导入 CSS 模块
【发布时间】:2017-05-11 05:59:44
【问题描述】:

如何使用 Webpack 在 Typescript 中导入 CSS 模块?

  1. 为 CSS 生成(或自动生成).d.ts 文件?并使用经典的 Typescript import 语句?与./styles.css.d.ts

    import * as styles from './styles.css'
    
  2. 使用requireWebpack函数导入?

    let styles = require("./styles.css");
    

但对于最后一种方法,我必须定义 require 函数。

什么是最好的方法或最佳选项,并且还可以为 CSS 文件定义和类处理 IntelliSense?

【问题讨论】:

标签: reactjs typescript webpack typescript-typings css-modules


【解决方案1】:

现在是 2021 年,您只需在项目中添加 src/Globals.d.ts 即可:

declare module "*.module.css";
declare module "*.module.scss";
// and so on for whatever flavor of css you're using

然后安装添加

{
  "compilerOptions": {
    "plugins": [{ "name": "typescript-plugin-css-modules" }]
  }
}

到您的 tsconfig。

进行简单更改后在 VS 代码中正确运行的示例(根是我的样式表中定义的类):

Webpack 和 tsc 也可以在命令行上正确编译。

【讨论】:

  • src/Globals.d.ts 不是src/Gobals.d.ts,是吗?
  • 这很好用,谢谢!另外,感谢@Dom,Globals NOT Gobals,哈哈!
【解决方案2】:

这个案例与Typescript有关。你可以在你的项目中添加typings.d.ts这个内容:

declare module "*.module.css";
declare module "*.module.scss";

如果要启用 CSS 模块,最好使用 *.module.* 格式的文件名。

css-loader 将为名称满足此 RegEx 的文件自动启用 CSS 模块:/\.module\.\w+$/i。此功能可通过将options.modules 属性设置为对象来自定义。

例如:

import style from './App.module.css'; // CSS Module enabled
import './index.css'; // Plain CSS loaded

对于最近的配置,您可以将此规则添加到webpack.config.js

{
  test: /\.css$/,
  use: [
    'style-loader',
    {
      loader: "css-loader",
      options: {
        modules: {
          localIdentName: "[hash:base64]", // default
          auto: true // default
        },
        sourceMap: true
      }
    },
  ]
},

自定义配置示例:

{
  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
    },
  }
},

完整的文档是HERE

【讨论】:

    【解决方案3】:

    我认为现在 typescript 可以通过简单地导入 css 文件 导入'fileTobeImportedPath.css'

    【讨论】:

      【解决方案4】:

      我已将一个名为 Global.d.tstypings.d.ts 的文件添加到我的 ./src 文件夹中,其中包含一些类型定义:

      declare module "*.module.css";
      

      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
            }
          }
        ]
      },
      

      然后我只需像这样导入模块:import styles from "./App.module.css";

      【讨论】:

      • 补充一点——如果你使用带有 --typescript 标志的 create-react-app,他们的 webpack 配置期望 CSS 模块被命名为 *.module.css。因此,要使“从 b 导入 a”语法起作用,您需要做的就是将所有 .css 文件重命名为 File.module.css 并像 import styles from "./File.module.css" 一样导入它们。
      • 最干净的解决方案 imo
      【解决方案5】:

      或者使用 require webpack 函数导入

      这正是我使用所做的,并且在我的一些项目中仍然有该代码。


      现在:我写了 typestyle :http://typestyle.github.io/#/ 但你不必使用它。如果它让您开心,请坚持使用const styles = require('./styles.css')。 FWIW,如果你想http://typestyle.github.io/#/raw

      ,你也可以使用带有 typestyle 的原始 css

      【讨论】:

      • 看起来有点像情感
      【解决方案6】:

      A) 正如您所说,有一个最简单(不是最好)的选项可以使用 require

      const css = require('./component.css')
      
      • 我们需要输入 require,因为它不是 typescript 的标准功能。
      • 这个特定要求的最简单的输入可能是:

        declare function require(name: string): string;
        
      • 然后,Webpack 将编译 typescript 并正确使用模块 - 但没有任何 IDE 帮助和构建类名检查

      B) 使用标准 import 有更好的解决方案:

      import * as css from './component.css'
      
      • 启用完整的类名 IntelliSense
      • 需要为每个css文件定义类型,否则tsc编译器会失败

      为了正确的 IntelliSense,Webpack 需要为每个 css 文件生成类型定义:

      1. 使用 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' }
        ];
        
      2. Loader 将为代码库中的每个 css 文件生成 *.css.d.ts 文件

      3. Typescript 编译器将理解 css 导入将是具有字符串类型属性(类名)的模块。

      提到typings-for-css-loader 包含a bug 并且由于类型文件生成延迟,最好声明全局*.css 类型以防我们的*.css.d.ts 文件尚未生成。

      那个little bug场景:

      1. 创建css文件component.css
      2. 将其包含在组件import * as css from './component.css'
      3. 运行webpack
      4. Typescript 编译器将尝试编译代码(错误)
      5. Lo​​ader 会生成 Css 模块类型文件 (component.css.d.ts),但是 typescript 编译器发现新类型文件已经很晚了
      6. 再次运行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 的文件。

      【讨论】:

        【解决方案7】:

        let styles = require("./styles.css"); 是最好的方法,因为它是 es5 版本的 javascript,兼容 react 的所有功能。import * as styles from './styles.css' 是 es6 版本的 javascript。

        【讨论】:

        • 它既不是 es5 也不是 es6,它是打字稿,因此会被转译。
        • 我同意@Meirion Hughes 的观点。感谢大家的回复!
        猜你喜欢
        • 2019-10-01
        • 2021-03-08
        • 2021-04-15
        • 2021-06-28
        • 2021-10-30
        • 2018-10-17
        • 1970-01-01
        • 2020-05-21
        • 2015-08-07
        相关资源
        最近更新 更多