【问题标题】:Can't import CSS/SCSS modules. TypeScript says "Cannot Find Module"无法导入 CSS/SCSS 模块。 TypeScript 说“找不到模块”
【发布时间】:2017-03-15 22:28:22
【问题描述】:

我正在尝试从 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 import sass webpack css-modules


    【解决方案1】:

    就我而言,我升级了 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 couldn't find a binding for your current environment

    【讨论】:

      【解决方案2】:

      100% 有效

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

      declare module '*.css';
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          只需添加文件 typings.d.ts 包含:

          declare module "*.module.css";
          

          记得用'module'声明你的css文件。例如 styles.module.css

          导入:

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

          【讨论】:

            【解决方案5】:

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

            npm install -D typescript-plugin-css-modules

            tsconfig.json

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

            【讨论】:

              【解决方案6】:

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

              【讨论】:

              • 嘿,这对我不起作用,最近发生了一些变化。 stackoverflow.com/questions/56563243/…
              • 仅供参考,这可能会有所帮助。对我来说,我不得不将 declaration.d.ts 文件放在项目根目录中。将它放在 tsconfig 文件中“类型”下的路径的子文件夹中对我不起作用。
              • 我正在使用typescript-plugin-css-modules 插件,在构建时仍然出现错误,这为我解决了问题。
              【解决方案7】:

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

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

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

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

              所以你可以这样做:

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

              然后你还需要在你的 webpack 上添加一个 modules resolve 配置,如下所示:

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

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

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

              【讨论】:

                【解决方案8】:

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

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

                然后你应该在你的mystyle.scss 旁边得到一个mystyle.d.ts,其中包含你定义的 CSS 类,你可以将其作为 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 是旧版本,而不是刚刚在编译期间生成的新版本.只需再次编译。

                享受。

                【讨论】:

                • "注意:添加/删除/重命名 CSS 类后的第一次构建失败,因为新生成的 .d.ts 打字稿模块稍后才会被拾取" -- 如何解决该部分?跨度>
                • @JonLauridsen 可以通过在 webpack.config.js 中规则数组的底部(末尾)设置 ts-loader 来解决。所以 ts-loader 会在每次编译时拾取一个正确的 *.scss.d.ts 文件,因为它们会在之前生成。
                猜你喜欢
                • 2022-12-31
                • 2023-04-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-05-25
                • 2016-07-05
                • 1970-01-01
                相关资源
                最近更新 更多