在 Webpack 2 中使用 TypeScript 加载 SASS 模块

Posted

技术标签:

【中文标题】在 Webpack 2 中使用 TypeScript 加载 SASS 模块【英文标题】:Loading SASS Modules with TypeScript in Webpack 2 【发布时间】:2018-01-06 18:59:04 【问题描述】:

我有一个使用 TypeScript、ReactJS 和 SASS 设置的简单项目,并希望使用 Webpack 将其全部捆绑。有大量关于如何使用 javascript 和常规旧 CSS 实现此目的的文档。但是,我找不到任何结合了我需要的加载器并使用 Webpack 2 语法(而不是加载器的原始 Webpack 语法)的文档。因此,我不确定如何创建正确的配置。

你可以找到我的webpack.config.js file here。 我将如何修改配置以使 TypeScript 接受我的 SCSS 模块,并让 Webpack 正确地将我的 SCSS 与我的 TypeScript 捆绑在一起?

这也可能有帮助:当我现在运行 Webpack 时,我收到以下错误:

ERROR in ./node_modules/css-loader!./node_modules/typings-for-css-modules-loader/lib?"namedExport":true,"camelCase":true!./node_modules/sass-loader/lib/loader.js!./src/raw/components/styles.scss
Module build failed: Unknown word (1:1)

> 1 | exports = module.exports = require("../../../node_modules/css-loader/lib/css-base.js")(undefined);
    | ^
  2 | // imports
  3 |
  4 |

 @ ./src/raw/components/styles.scss 4:14-206
 @ ./src/raw/components/greetings/greetings.tsx
 @ ./src/raw/index.tsx
 @ multi ./src/raw/index.tsx

ERROR in [at-loader] ./src/raw/components/greetings/greetings.tsx:3:25
    TS2307: Cannot find module '../styles.scss'.

请注意,./src/raw/index.tsx 是我的应用程序的入口点,./src/raw/components/greetings/greeting.tsx 是我唯一的 React 组件,./src/raw/components/styles.scss 是我唯一的 SCSS 文件。

【问题讨论】:

【参考方案1】:

typings-for-css-modules-loadercss-loader 的替代品(技术上它在底层使用css-loader),这意味着它需要CSS 并将其转换为JavaScript。您还使用了css-loader,但失败了,因为它接收到的是 JavaScript,但需要的是 CSS(因为 JavaScript 不是有效的 CSS,它无法解析)。

此外,您没有使用 CSS 模块,因为您没有在 CSS 加载器上设置 modules: true 选项(或 typings-for-css-modules-loader,它将其传递给 css-loader)。

您的.scss 规则应该是:


    test: /\.scss$/,
    include: [
        path.resolve(__dirname, "src/raw")
    ],
    use: [
         loader: "style-loader" ,
        
            loader: "typings-for-css-modules-loader",
            options: 
                namedexport: true,
                camelcase: true,
                modules: true
            
        ,
         loader: "sass-loader" 
    ]

【讨论】:

为了使上述工作正常,需要安装以下依赖项: npm i -D css-loader@1.0.1 sass-loader styles-loader node-sass typings-for-css-modules-装载机。【参考方案2】:

这是一个小扩展版本(因为上面的内容对我不起作用),使用从陈旧的typings-for-css-modules-loader 派生的另一个包 (css-modules-typescript-loader)。

如果有人遇到同样的问题 - 这是一个适合我的配置:

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

享受。

【讨论】:

以上是关于在 Webpack 2 中使用 TypeScript 加载 SASS 模块的主要内容,如果未能解决你的问题,请参考以下文章

typeScrip 类

Springboot + mybatis + React+redux+React-router+antd+Typescript: React+Typescrip项目的搭建

在 Webpack 2 中使用 TypeScript 加载 SASS 模块

我啥时候在 Webpack 2 module.rules 中使用“use”和“loader”?

如何避免在 Webpack 2 的配置中使用可选的解析选项?

使用 webpack-2 在 chrome 中检测到源映射但未加载原始源