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

相關文章
相關標籤/搜索