149

我正在尝试从 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;

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

4

11 回答 11

191

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;
}
于 2017-01-30T22:40:52.017 回答
76

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

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您将在您的开发依赖项中需要所有这些:

  "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"
  }

然后,您应该在包含您定义的 CSS 类的mystyle.d.ts旁边获得一个mystyle.scss,您可以将其作为 Typescript 模块导入并像这样使用:

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 是旧版本,而不是刚刚在编译期间生成的新版本。只需再次编译。

享受。

于 2019-05-05T16:17:25.370 回答
27

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

declare module "*.module.css";

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

输入:

import React from 'react';
import styles from './styles.module.css'
于 2021-06-16T23:22:28.510 回答
12

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

npm install -D typescript-plugin-css-modules

tsconfig.json

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

于 2021-01-05T12:28:00.540 回答
9

100% 有效

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

declare module '*.css';
于 2021-09-25T09:36:32.677 回答
8

如果您使用 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 目录。使用此配置,它知道在哪里查找并找到它并且构建工作。

于 2019-10-26T00:43:43.563 回答
6

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

declare module "*.module.css";

记得用 . 声明你的 css 文件.module.css

输入:

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

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

于 2022-01-02T01:16:51.687 回答
1

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

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

typings包含@Kalle 的答案中看到的文件declaration.d.ts

于 2022-02-18T21:01:46.667 回答
0

就我而言,我解决了它只是评论加载器 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 

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

于 2022-02-17T23:45:19.810 回答
0

就我而言,我升级了 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文件并在"baseURL": ".",下添加"compilerOptions":,如下所示:
"compilerOptions": {
    "baseUrl": ".",
    etc etc etc

至此问题解决了。

参考:

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

于 2021-12-08T15:44:07.483 回答
-3

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

于 2021-07-16T15:37:18.880 回答