typescript项目css modules

typescript项目中咱们使用typings-for-css-modules-loader来替代css-loader实现css modules。

一、typings-for-css-modules-loader加载器介绍

Webpack加载器,用做 css-loader的替代产品,可动态生成 CSS模块的 TypeScript类型

这句话是什么意思呢?就是编译时处理css文件,为这些css文件生成对应的.d.ts声明文件而且具备css-loader功能,用import/require处理css引用资源(url和@import),使得css模块化,配置modules字段能够启用css modulescss

为何须要为css文件生成声明文件呢?由于在typescript项目中不管是咱们本身写的代码仍是导入第三方库和样式,都应该符合typescript语言规范,就好比在react+typescript项目中,安装了react、react-dom后还得安装@types/react、@types/react-dom,这两个库是react、react-dom的声明文件。node

二、typings-for-css-modules-loader加载器使用

typescript项目webpack配置以下:react

{
    test: /\.(sc|sa|c)ss$/,
    include: [path.join(__dirname, '../', './src')],
    use: [
      // 'style-loader', // style-loader将第二步编译出来的代码转为js代码
      {
        loader: MiniCssExtractPlugin.loader,
        options: {
          publicPath: (resourcePath, context) => {
            // resourcePath = E:\学习项目\从零搭建typescript+react项目\ts-react\src\index.scss
            // context = E:\学习项目\从零搭建typescript+react项目\ts-react
            return path.relative(path.dirname(resourcePath), context) + '/';
          },
        }
      },
      // css-loader将编译出来的代码再次编译成为符合CommonJS的代码
      {
        loader: 'typings-for-css-modules-loader',
        options: {
          modules: true, // 使用css modules
          namedExport: true, // 类名导出
          camelCase: true, // 支持驼峰
          sass: true, // 是否使用sass
          localIdentName: '[name]__[local]__[hash:base64:5]' // 定义类名
        }
      },
      {
        // 给css加上前缀
        loader: 'postcss-loader',
        options: {
          plugins: [require('autoprefixer')]
        }
      },
      'sass-loader' // sass-loader将sass代码编译为css(默认使用node-sass)
    ]
}

简单解释下三个 Loader 的做用:webpack

  1. sass-loader 的做用固然是把 SASS 文件编译成 CSS 文件;
  2. typings-for-css-modules-loader 是在 css-loader 上包了一层,它的选项彻底兼容 css-loader。除此以外,它会为每一个 SASS 文件生成对应的 xxx.scss.d.ts 的解释文件,这样在 TypeScript 中就能够正确解析,编辑器里面也能有很是友好的代码提示。
  3. style-loader 就是把样式使用<style>标签打到页面上。

整个过程就是,读到一个 SCSS 文件,丢给 sass-loader(调用node-sass) 处理成 css,而后给 typings-for-css-modules-loader 生成 xxx.scss.d.ts 文件而且把 css 处理成 JavaScript 可使用的样子(这步实际上是 css-loader 在处理,为啥要把 css 文件处理成 JavaScript 能够用的样子呢,由于 webpack 只能处理 JavaScript,因此须要作转换),最后把处理好的给 style-loader,页面加载的时候就会打到页面上。web

其实 loader 的本质就是anything to JavaScript,由于 Webpack 只处理 JavaScript。记住这一点,就对为何要用这个 loader 那个 loader 有个清晰的认识了。typescript

好比在react + typescript项目中,配置好typings-for-css-modules-loader后,咱们定义index.scss、index.tsx两个文件,并在index.tsx中导入index.scss样式。因为启用了css modules,全部的样式类名都会以hash字符串替换,若是咱们import './index.scss'导入样式,那么只能在元素中className="填写对应类名对应hash字符串",可是类名的hash字符串是编译时生成的,而咱们在写代码时并不知道咱们须要的类名会编译成哪一个hash字符串,而且hash字符串很长不方便书写和记忆。npm

image.png

咱们改用以模块的方式导入样式文件,但这会遇到一个问题TS2307: cannot find module '.xxx',由于样式文件不是AMD/CMD规范文件,不支持模块导入,typescript语法可使用declare module声明模块,咱们定义一个.d.ts文件,而后写样式模块声明,项目编译过程当中会自动去读取.d.ts这种类型的文件,因此不须要咱们手动地加载他们。固然.d.ts文件也不能随便放置在项目中,这类文件和ts文件同样须要被typescript编译,因此同样只能放置在tsconfig.jsoninclude属性所配置的文件夹下。json

// typed-css.d.ts
// scss模块声明
declare module '*.scss' {
  const content: {[key: string]: any}
  export = content
}
// less模块声明
declare module '*.less' {
  const content: { [key: string]: any }
  export default content
}

这样,样式文件就可使用模块导入的方式了。sass

image.png

参考:
https://blog.csdn.net/weixin_...
https://www.npmjs.com/package...less

相关文章
相关标签/搜索