webpack css_module配置與使用

本文主要是基于webpack+es6+react關于css module腳手架的搭建。可以從css_module_demo下載相關案例,本文擬從4種可能的情形配置啟動css_module。

css_module

css module最簡單的情形,只需要在css-loader啟動css module配置即可。

webpack css-loader

module: {
     rules: [{
         test:  [/\.js$/, /\.jsx$/, /\.es6$/],
         include: [
           path.resolve(__dirname, 'src'),
         ],
         use: {
           loader: "babel-loader"
         },
       }, {
         test: [/\.css/],
         exclude: path.resolve(__dirname, 'src/styles/global'),
         use: [
           'style-loader',
           {
             loader: 'css-loader',
             options: {
                 modules: true,
                 localIdentName: '[name]__[local]-[hash:base64:5]'
             }
           }
         ]
      }, {
        test: [/\.css/],
        include: path.resolve(__dirname, 'src/styles/global'),
        use: [
          'style-loader',
          'css-loader'
        ]
      }]
   },

一般項目中,會有normalize.css或者global.css全局css樣式,此時若不需要處理,可以配置兩種css的管理方式。具體的使用方法,可參照css_module_demo demo1的配置。

css_module + less\scss

若需要配合less、scss編輯器,配置與css-loader類似,在css、less相關配置中設置如下即可.

  ...
    {
         test: [/\.css$/, /\.less$/],
         exclude: path.resolve(__dirname, 'src/styles/global'),
         use: [
           'style-loader',
           {
             loader: 'css-loader',
             options: {
                 modules: true,
                 localIdentName: '[name]__[local]-[hash:base64:5]'
             }
           },
           {
             loader: 'postcss-loader',
             options: {
               ident: 'postcss',
               plugins: (loader) => [
                 require('postcss-import')({ root: loader.resourcePath }),
                 require('postcss-cssnext')(),
                 require('autoprefixer')(),
                 require('cssnano')()
               ]
             }
           },
           'less-loader'
         ]
      }, {
        test: [/\.css$/, /\.less$/],
        include: path.resolve(__dirname, 'src/styles/global'),
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: (loader) => [
                require('postcss-import')({ root: loader.resourcePath }),
                require('postcss-cssnext')(),
                require('autoprefixer')(),
                require('cssnano')()
              ]
            }
          },
          'less-loader'
        ]
      }
...

這樣我就可以使用less的功能了,如我們在app.less中

.global {
  text-align: left;
  font-size: 20px;
  composes: box from "../styles/views/layout.less";
  .title {
    font-size: 22px;
    color: red;
  }
  .title:before {
    content: 'before i come'
  }
  .title:hover {
    font-size: 40px;
  }
}

但是css module中,不能在子選擇器中使用compose,如我們在title中定義composes

.global {
  text-align: left;
  font-size: 20px;
  composes: box from "../styles/views/layout.less";
  .title {
    font-size: 22px;
    composes: heading from "../styles/views/typography.less";
    color: red;
  }
  .title:before {
    content: 'before i come'
  }
  .title:hover {
    font-size: 40px;
  }
}

會提示類似如下的錯誤

ERROR in ./node_modules/.0.28.7@css-loader?{"modules":true,"localIdentName":"[name]__[local]-[hash:base64:5]"}!./node_modules/.2.0.8@postcss-loader/lib?{"ident":"postcss"}!./node_modules/.4.0.5@less-loader/dist/cjs.js!./src/components/app.less
Module build failed: Error: composition is only allowed when selector is single :local class name not in ":local(.global) :local(.title)"

css module作者在issues/261中提到“Composition works differently to mixins. It does not mutates rules, just concatenates names.”

css_module + react-css-modules

在每個樣式中都是style.*中的形式比較麻煩,可以使用react-css-modules解決這種問題。例如在app.js中

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import CSSModules from 'react-css-modules';
import { Link } from 'react-router-dom';
import styles from './app.less'
class App extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div styleName='global'>
                <h1 styleName='title'>css module test case</h1>
                <ul role="nav" styleName='nav'>
                    <li><Link to="/CompositionOverrides">CompositionOverrides</Link></li>
                    <li><Link to="/GlobalSelectors">GlobalSelectors</Link></li>
                    <li><Link to="/ScopedAnimations">ScopedAnimations</Link></li>
                    <li><Link to="/ScopedSelectors">ScopedSelectors</Link></li>
                    <li><Link to="/StyleVariantA">StyleVariantA</Link></li>
                </ul>
                {this.props.children}
            </div>
        );
    }
}
export default CSSModules(App, styles)

react-css-modules缺點是是需要運行時的依賴,而且需要在運行時才獲取className,性能損耗大。在比較大的項目中,會導致較大的延遲。那么這個問題怎么解決那,可以使用bable-plugins-react-css-modules 把className獲取前置到編譯階段。

css_module + bable-plugins-react-css-modules

bable-plugins-react-css-modules與react-css-modules是同一個作者開發的工具,bable-plugins-react-css-modules相對于react-css-modules,在性能方面有了較大的提高。
bable-plugins-react-css-modules有兩種配置方式,一是配置在webpack.config.js,二是配置在.babelrc中,本文采取的方式是配置在webpack.config.js中。

       ...
       {
       test:  [/\.js$/, /\.jsx$/, /\.es6$/],
         include: [
           path.resolve(__dirname, 'src'),
         ],
         use: {
           loader: "babel-loader",
           options: {
             cacheDirectory: true,
             plugins: [
               [ "react-css-modules", {
                 context: path.resolve(__dirname, "src"),
                 "generateScopedName": "[path][name]__[local]--[hash:base64:5]"
               }]
             ]
           }
         },
       }
      ...

總結

css module具有靈活性、易移植的優點,可以配合less、scss等多種css編譯器使用。本文依賴于webpack css-loader,配置了css module、css module + less\scss、css module+react-css-modules、css module + babel-plugin-react-css-modules等四種css_module使用方式。

參考文獻

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容

  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,214評論 7 35
  • GitChat技術雜談 前言 本文較長,為了節省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,706評論 7 110
  • 學習流程 參考文檔:入門Webpack,看這篇就夠了Webpack for React 一. 簡單使用webpac...
    Jason_Zeng閱讀 3,163評論 2 16
  • 衣服風格能反映一個人的生活態度,也能決定一個人的第一印象。毫無疑問,簡單淡雅的人一定不會穿有太多顏色的衣服,對...
    漁舟舟愛看花閱讀 497評論 2 5
  • 睜開明亮的雙眼,除去睡意的干擾,舒展美麗的笑容,擁抱快樂的一天,大家好,我是你們的老朋友“手抓餅”愿新的一天你們工...
    junlingyurui閱讀 306評論 2 2