Back
Featured image of post 为css/scss加上typescript 声明文件

为css/scss加上typescript 声明文件

问题简述

导入scss文件,打包client的时候,报警告

报警告: export ‘default’ (imported as ‘classes’) was not found in ‘./index.scss’ (possible exports: )

import * as classes from  '../assets/global.scss'

原因

这里其实是一个typescript的语法问题。

根据CSS modules 的特性,它可以将一个css 文件变成一个对象。你可以在类似tsx/jsx的地方,使用对象一样去调用对应的className。

<h1 className={classes.button}>首页2132132页面 test</h1>
<h2 className={classes.t}>n的值:{n}</h2>

其实为什么要用typescript,基本就是为了它的自动类型推断,自动提示。

而对于typescript来说,.scss文件就是一个样式文件,而不是一个module。换而言之,就是ts根本就不认识这个鬼东西。

所以当你以一个模块进行import的时候,它就很奇怪为啥找不到对应exports

你要清晰地知道,ts和webpack是两回事的东西。

解决方案

  • require替代import

这样子确实是解决了这个报错问题。但是你这样子就得不到类型检查以及一些自动提示。

其实就是不能这么玩。

  • declare 声明文件 + import
// Button.scss

.foo {
  color: chocolate;
}
.barBaz {
  color: tomato;
}

// Button.scss.d.ts

export const foo: string;
export const barBaz: string;

那我们不可能像个傻子一样去写这个声明文件吧。

所以我们可以去借助一些webpackloader去解决这个问题。

在这里要用到的loader就是@teamsupercell/typings-for-css-modules-loader文档

具体的配置看对应的文档好了,这里就懒得逼逼赖赖了。


引用一下官方的例子。根据scss直接生成xx.d.ts

.some-class {
  // some styles
  &.someOtherClass {
    // some other styles
  }
  &-sayWhat {
    // more styles
  }
}


declare namespace MyComponentScssModule {
  export interface IMyComponentScss {
    "some-class": string;
    someOtherClass: string;
    "some-class-sayWhat": string;
  }
}

declare const MyComponentScssModule: MyComponentScssModule.IMyComponentScss & {
  /** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
  locals: MyComponentScssModule.IMyComponentScss;
};

export = MyComponentScssModule;
comments powered by Disqus