typescript項目中咱們使用typings-for-css-modules-loader來替代css-loader實現css modules。
Webpack
加載器,用做css-loader
的替代產品,可動態生成CSS
模塊的TypeScript
類型
這句話是什麼意思呢?就是編譯時處理css
文件,爲這些css
文件生成對應的.d.ts
聲明文件而且具備css-loader
功能,用import/require
處理css
引用資源(url和@import)
,使得css
模塊化,配置modules
字段能夠啓用css modules
。css
爲何須要爲css
文件生成聲明文件呢?由於在typescript
項目中不管是咱們本身寫的代碼仍是導入第三方庫和樣式,都應該符合typescript
語言規範,就好比在react+typescript
項目中,安裝了react、react-dom
後還得安裝@types/react、@types/react-dom
,這兩個庫是react、react-dom
的聲明文件。node
在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
sass-loader
的做用固然是把 SASS
文件編譯成 CSS
文件;typings-for-css-modules-loader
是在 css-loader
上包了一層,它的選項徹底兼容 css-loader
。除此以外,它會爲每一個 SASS
文件生成對應的 xxx.scss.d.ts
的解釋文件,這樣在 TypeScript
中就能夠正確解析,編輯器裏面也能有很是友好的代碼提示。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
咱們改用以模塊的方式導入樣式文件,但這會遇到一個問題TS2307: cannot find module '.xxx'
,由於樣式文件不是AMD/CMD
規範文件,不支持模塊導入,typescript
語法可使用declare module
聲明模塊,咱們定義一個.d.ts
文件,而後寫樣式模塊聲明,項目編譯過程當中會自動去讀取.d.ts
這種類型的文件,因此不須要咱們手動地加載他們。固然.d.ts
文件也不能隨便放置在項目中,這類文件和ts文件
同樣須要被typescript
編譯,因此同樣只能放置在tsconfig.json
中include
屬性所配置的文件夾下。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
參考:
https://blog.csdn.net/weixin_...
https://www.npmjs.com/package...less