使用typescript无非就是因为它的代码约束和提示能力. 以react为例:
原始结构
组件目录结构
Error
│ index.scss
│ index.tsx
index.tsx
import * as React from 'react'
import * as styles from './index.scss'
const Error = () => (
<div className={styles.centered}>
<div className={styles.emoji}>😭</div>
<p className={styles.title}>Ooooops!</p>
<p>This page doesn't exist anymore.</p>
</div>
)
export default Error
index.scss
.centered {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.emoji {
font-size: 9em;
user-select: none;
}
.title {
font-size: 3em;
text-align: center;
color: gray;
}
在不加任何配置的情况下, 如无意外, 报错了😂
抛开webpack, 在typescript来看, 不认识scss解决方法大体有三种
-
使用require写法
const styles = require('./index.scss')
require默认的定义
-
添加全局声明
declare module '*.scss' { const content: any; export default content; }
修改import
import styles from './index.scss'
-
为index.scss生成index.scss.d.ts
正如一开始所说, 使用typescript无非就是因为它的代码约束和提示能力, 那么, 第三种才是我们的最优解.
怎么生成
typed-css-modules
typed-css-modules的使用方法比较简单, 主要通过命令行去生成d.ts, 支持watch模式
tcm src -c -w
当然还可以通过引入typed-css-modules模块自行开发插件
typings-for-css-modules-loader
typings-for-css-modules-loader是一个webpack loader. 在webpack配置文件中的module处修改scss文件规则
const typingsForCssModulesLoaderConf = {
loader: 'typings-for-css-modules-loader',
options: {
modules: true,
namedExport: true,
camelCase: true,
sass: true
}
}
......
[
{
test: /\.scss$/,
exclude: resolve('src/commonStyles'),
rules: [
{
use: ['style-loader', typingsForCssModulesLoaderConf]
}
]
},
{
// 位于src/commonStyles里的不使用css module
test: /\.scss$/,
include: resolve('src/commonStyles'),
rules: [
{
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
]
为了避免webpack因为生成众多的scss.d.ts而导致速度变慢,在webpack plugin处添加
new webpack.WatchIgnorePlugin([/css\.d\.ts$/])
生成结果
以上两种生成d.ts的方法最终的目录结构都为
Error
│ index.scss
│ index.scss.d.ts
│ index.tsx
index.scss.d.ts
export const centered: string;
export const emoji: string;
export const title: string;
终于可以愉快地使用scss中的className了