繁体   English   中英

无法导入 CSS/SCSS 模块。 TypeScript 说“找不到模块”

[英]Can't import CSS/SCSS modules. TypeScript says "Cannot Find Module"

我正在尝试从 CSS 模块导入主题,但 TypeScript 给我一个“找不到模块”错误,并且主题未在运行时应用。 我认为我的 Webpack 配置有问题,但我不确定问题出在哪里。

我正在使用以下工具:

"typescript": "^2.0.3"
"webpack": "2.1.0-beta.25"
"webpack-dev-server": "^2.1.0-beta.9"
"react": "^15.4.0-rc.4"
"react-toolbox": "^1.2.3"
"node-sass": "^3.10.1"
"style-loader": "^0.13.1"
"css-loader": "^0.25.0"
"sass-loader": "^4.0.2"
"sass-lint": "^1.9.1"
"sasslint-webpack-plugin": "^1.0.4"

这是我的webpack.config.js

var path = require('path');
var webpack = require('webpack');
var sassLintPlugin = require('sasslint-webpack-plugin');

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
    './src/index.tsx',
  ],
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'http://localhost:8080/',
    filename: 'dist/bundle.js',
  },
  devtool: 'source-map',
  resolve: {
    extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'source-map-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loader: 'tslint-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loaders: [
        'react-hot-loader/webpack',
        'awesome-typescript-loader',
      ],
      exclude: /node_modules/,
    }, {
      test: /\.scss$/,
      loaders: ['style', 'css', 'sass']
    }, {
      test: /\.css$/,
      loaders: ['style', 'css']
    }],
  },
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  },
  plugins: [
    new sassLintPlugin({
      glob: 'src/**/*.s?(a|c)ss',
      ignoreFiles: ['src/normalize.scss'],
      failOnWarning: false, // Do it.
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    contentBase: './'
  },
};

和我尝试导入的App.tsx

import * as React from 'react';

import { AppBar } from 'react-toolbox';
import appBarTheme from 'react-toolbox/components/app_bar/theme.scss'
// local ./theme.scss stylesheets aren't found either 

interface IAppStateProps {
  // No props yet
}

interface IAppDispatchProps {
  // No state yet
}

class App extends React.Component<IAppStateProps & IAppDispatchProps, any> {

  constructor(props: IAppStateProps & IAppDispatchProps) {
    super(props);
  }

  public render() {
    return (

        <div className='wrapper'>
          <AppBar title='My App Bar' theme={appBarTheme}>
          </AppBar>
        </div>

    );
  }
}

export default App;

启用类型安全样式表模块导入还需要什么?

TypeScript 不知道除了.ts.tsx之外还有其他文件,因此如果导入的文件后缀未知,它将抛出错误。

如果你有一个允许你导入其他类型文件的 webpack 配置,你必须告诉 TypeScript 编译器这些文件存在。 为此,添加一个声明文件,您可以在其中声明具有合适名称的模块。

要声明的模块的内容取决于用于文件类型的 webpack 加载器。 在通过sass-loadercss-loaderstyle-loader管道传输*.scss文件的 webpack 配置中,导入的模块中将没有内容,正确的模块声明如下所示:

// declaration.d.ts
declare module '*.scss';

如果加载器是为 css-modules 配置的,只需像这样扩展声明:

// declaration.d.ts
declare module '*.scss' {
    const content: Record<string, string>;
    export default content;
}

这是一个对我有用的完整配置(我只是花了一个小时的痛苦试验和错误 - 以防有人遇到相同的问题):

TypeScript + WebPack + Sass

webpack.config.js

module.exports = {
  //mode: "production", 
    mode: "development", devtool: "inline-source-map",

    entry: [ "./src/app.tsx"/*main*/ ], 
    output: {
        filename: "./bundle.js"  // in /dist
    },
    resolve: {
        // Add `.ts` and `.tsx` as a resolvable extension.
        extensions: [".ts", ".tsx", ".js", ".css", ".scss"]
    },
    module: {
        rules: [

            { test: /\.tsx?$/, loader: "ts-loader" }, 

            { test: /\.scss$/, use: [ 
                { loader: "style-loader" },  // to inject the result into the DOM as a style block
                { loader: "css-modules-typescript-loader"},  // to generate a .d.ts module next to the .scss file (also requires a declaration.d.ts with "declare modules '*.scss';" in it to tell TypeScript that "import styles from './styles.scss';" means to load the module "./styles.scss.d.td")
                { loader: "css-loader", options: { modules: true } },  // to convert the resulting CSS to Javascript to be bundled (modules:true to rename CSS classes in output to cryptic identifiers, except if wrapped in a :global(...) pseudo class)
                { loader: "sass-loader" },  // to convert SASS to CSS
                // NOTE: The first build after adding/removing/renaming CSS classes fails, since the newly generated .d.ts typescript module is picked up only later
            ] }, 

        ]
    }
}; 

还要在您的项目中放置一个declarations.d.ts

// We need to tell TypeScript that when we write "import styles from './styles.scss' we mean to load a module (to look for a './styles.scss.d.ts'). 
declare module '*.scss'; 

您将在package.json的 dev-dependencies 中需要所有这些:

  "devDependencies": {
    "@types/node-sass": "^4.11.0",
    "node-sass": "^4.12.0",
    "css-loader": "^1.0.0",
    "css-modules-typescript-loader": "^2.0.1",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "ts-loader": "^5.3.3",
    "typescript": "^3.4.4",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"
  }

然后,你应该得到一个mystyle.d.ts旁边的mystyle.scss包含您定义的CSS类,你可以导入为打字稿模块和使用这样的:

import * as styles from './mystyles.scss'; 

const foo = <div className={styles.myClass}>FOO</div>; 

CSS 将自动加载(作为style元素注入 DOM)并包含神秘标识符而不是 .scss 中的 CSS 类,以隔离页面中的样式(除非您使用:global(.a-global-class) { ... } )。

请注意,无论何时添加 CSS 类或删除它们或重命名它们,第一次编译都会失败,因为导入的 mystyles.d.ts 是旧版本,而不是编译期间刚刚生成的新版本。 再编译就行了。

享受。

我正在使用typescript-plugin-css-modules

npm install -D typescript-plugin-css-modules

配置文件

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

如果您使用 tsconfig.json 路径设置,请注意

请注意,如果您将这些解决方案与 tsconfig 路径结合使用以缩短导入,您将需要额外的配置。

如果您碰巧使用这样的路径 tsconfig:

{
  "compilerOptions": {
    "paths": {
      "style/*": [ "src/style/*" ],
    }
  }
}

所以你可以这样做:

import { header } from 'style/ui.scss';

然后你还需要在你的 webpack 上添加一个 模块解析配置,如下所示:

module.exports = {
  ...
  resolve: {
    ...
    alias: {
      style: path.resolve(__dirname, 'src', 'style')
    }
  }
}

确保根据您的设置设置路径。

这使得 webpack 知道在哪里查找,因为它认为新的导入路径实际上是一个模块,因此它默认为 node_modules 目录。 使用此配置,它知道在哪里查找并找到它并且构建工作。

上面的答案对我不起作用,我正在研究 scss + TS + React(如果你也是,这个答案适合你)。 我所做的是:

在 src 文件夹中创建一个 declarations.d.ts 文件并在其中添加以下代码

declare module "*.scss" {
  const content: { [className: string]: string };
  export = content;
}

然后在 src 文件夹中创建了一个 tsconfig.json 文件并添加了以下代码

{
  "compilerOptions": {
    "plugins": [{ "name": "typescript-plugin-css-modules" }]
  },
  //add the following
  "include": ["src/**/*.ts", "declarations.d.ts"]
}

然后最后安装插件为 npm i typescript-plugin-css-modules

它奏效了:)

只需添加包含以下内容的文件typings.d.ts

declare module "*.module.css";

并记住用“模块”声明你的css文件。 例如styles.module.css

输入:

import React from 'react';
import styles from './styles.module.css'

100% 有效

只需在您的项目中放置一个“declarations.d.ts”并添加以下行:

declare module '*.css';

根据@Kalle 提供的答案,我还发现我需要在include tsconfig 选项中使声明类型可被发现:

"include": ["./src/**/*.tsx", "./src/**/*.ts", "./typings/*.ts"]

使用包含typings的答案中的declaration.d.ts文件的类型。

这对我有用(我正在使用 Typescript + vite)。

  1. 将此添加到项目根文件夹中的declaration.d.ts文件中

    declare module "*.module.css"; declare module "*.module.scss";
  2. tsconfig.json “declaration.d.ts”添加到“include”

{
  "compilerOptions": {...},
  "include": ["src", "declaration.d.ts"],
}

这将允许声明在src文件夹中工作,而不仅仅是declarations.d.ts所在的root文件夹。

您可以直接在您直接导入 styles 的文件夹中添加declaration.d.ts ,但这是一个坏主意。

我找到了答案(至少对我而言)。

许多答案在这里和那里说:

// declaration.d.ts
declare module '*.scss';

哦,是的,我在现有的 .d.ts 文件中做到了:

// this.name.is.at.your.disposal.d.ts
export type {};

declare module "*.css";

declare global {
  declare const NEXT_PUBLIC_SOME_URL: string;
}

但是 ts 编译器仍然抱怨“哦,我不明白这个 blablabla”

我注意到这条线

export type {};

是你需要用你的神的名字抹去的邪恶。

我得go现在买啤酒。

声明全局类型时的问题是未验证导入的分辨率\\可访问性。

就我而言,我升级了 NodeJS 的(主要)版本,这可能导致了问题。 在前端,我也看到了一个错误,大意是:

Node Sass couldn't find a binding for your current environment

在我的情况下的解决方案是:

  1. npm cache clean --force

  2. 删除项目的node_modules文件夹

  3. 删除package-lock.json文件

  4. npm install

在此之后,运行npm run dev产生以下消息:

Failed to load C:\path\tsconfig.json: Missing baseUrl in compilerOptions

所以解决的最后一步是:

  1. 编辑tsconfig.json文件并在"compilerOptions":下添加"baseURL": ".", ,如下所示:
"compilerOptions": {
    "baseUrl": ".",
    etc etc etc

此时问题已解决。

参考:

Node Sass 找不到适合您当前环境的绑定

只需添加包含以下内容的declaration.d.ts文件:

declare module "*.module.css";

请记住使用.module.css声明您的 css 文件。

输入:

import styles from './styles.module.css'

如果使用 Sass,请将.css语句替换为.scss

在我的情况下,我解决了它只是评论加载器 scss 和 sass:

{
                test: /\.css$/,
                use:
                    [
                        {
                            loader: 'style-loader'
                        },
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                modules: true
                            }
                        }
                        // ,
                        // {
                        //     loader: 'sass-loader'
                        // }
                        // ,
                        // {
                        //     loader: 'scss-loader'
                        // }
                    ]
            }

声明模块“*.module.css”; 不影响结果。

记住:永远奔跑

npm start 

测试这些配置更改以查看是否发生了某些事情**。 这样做可以节省我今天下午的时间。

在使用 CRA 创建的 React 应用程序中,我必须添加react-app-env.d.ts

declare module '*.css';

像上面建议的那样,在 declarations.d.ts 中添加此声明不起作用。

在我的项目中,在 /src 文件夹中,有一个包含内容的 react-app-env.d.ts 文件

/// <reference types="react-scripts" />

我想不通他为什么会这样? 我查看了导入它的搜索,但搜索显示 0 个结果。不知何故我删除了它,之后我得到了很多错误:

找不到模块“./Home.scss”或其对应的类型声明。 TS2307 编译时带有警告。

找不到模块 './BlockPosts.module.css' 或其相应的类型声明。 TS2307 编译时带有警告。

然后我恢复了这个文件,所有的错误都消失了

在你的项目的/src文件夹下创建一个文件react-app-env.d.ts把它写下来

/// <reference types="react-scripts" />

也许你也会停止犯错

正如@Kalle 提到的

TypeScript 不知道有 .ts 或 .tsx 以外的文件,因此如果导入的文件后缀未知,则会引发错误。

为避免 TS 显示此错误,我的方法是创建一个types文件夹,并在其中添加一个.d.ts扩展文件,其中包含 declarations

像这样:

在此处输入图像描述

关于.d.ts文件

TypeScript 主要有两种文件。 .ts文件是包含类型和可执行代码的实现文件。 这些是产生.js输出的文件,也是您通常编写代码的地方。

.d.ts文件是只包含类型信息的声明文件。 这些文件不会产生.js输出; 它们仅用于类型检查。 稍后我们将详细了解如何编写我们自己的声明文件。

您可以在此处阅读有关 TS 声明的更多信息

只需在你的 src 目录中添加文件react-app-env.d.ts并在那里写/// <reference types="react-scripts" />这将通过引入在node_modules/react-scripts/lib/react-app.d.ts中声明的各种名称来解决问题node_modules/react-scripts/lib/react-app.d.ts

但是,我遇到了这个确切的问题

  • typings.d.ts已正确配置
  • tsconfig.json已正确配置
  • webpack 配置已正确配置
  • 相同的设置在不同的项目上工作

而且我仍然收到此错误。

有用的是从typings.d.ts删除导入

- import { Theme } from '@mui/material/styles'

它根本没有给出任何错误或警告。 但是阻止了我声明的模块正常工作。 希望能帮助到你!

对于使用 typescript-plugin-css-modules package 的人。在这种情况下,您必须添加 tsconfig.json 文件:

{
  "extends": "../tsconfig.json",
  …
    "plugins": [
      {
        "name": "typescript-plugin-css-modules"
      }
    ]
}

对我来说,问题是myFile.scss.d.ts interface中只有一个property没有生成,所以我遇到了错误。

原因是我的myFile.scss上存在一个特定的 class 并且在我的组件上使用过,但是它上面有任何 CSS 属性!

.base {

&__rule1 {
// .base__rule1 was not been generated on my .d.ts file because it has any css property

        &__another {
            width: 120px;
            margin: 0 auto 8px;
        }

    }}

可能的解决方案是:

a) 从标记中删除base__rule1<div classes={style.base__rule1}><div>

b) 向 class 添加一些 css 属性

....
&__rule1 {
 width: inherit;
....
}

我在 angular 方面遇到了同样的问题,我尝试运行npm audit fix并解决了我的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM