React中使用less(use CSS Modules)的兩種配置方法

創(chuàng)建日期: 2020年3月2日
Demo源碼下載
參考鏈接:
鏈接1
鏈接2
customize-cra API

前言:
如果你想通過不暴露webpack,配置less,并且只想知道步驟,不關(guān)心你配置時候為什么不好用理卑,可以直接劃到下面看【3.總結(jié)】。
如果,你是初學(xué)者小白扇单,并沒有項目,你需要做如下準(zhǔn)備工作:
用create-react-app (CRA)腳手架或者IDE創(chuàng)建React項目奠旺。
參考:React入門(1)——我的第一個React.js項目

1.安裝less和less-loader

//npm 
$ npm install --save-dev less-loader less
//yarn
$ yarn add less less-loader -D

遺留問題:為什么我按官網(wǎng)的命令去安裝less蜘澜,在package.json里面不會顯示,而用上面的方式响疚,就會顯示呢鄙信?需要查下npm的子命令了。[參考]

安裝后忿晕,我們會看到package.json文件中装诡,添加了依賴:

  "devDependencies": {
    "less": "^3.11.1",
    "less-loader": "^5.0.0"
  }

Dependencies和devDependencies到底有什么區(qū)別呢?[參考鏈接]

2. 配置

2.1 方法一:暴露webpack

哇靶硬凇慎王!好尷尬??,翻了半天宏侍,也沒找到網(wǎng)上說的webpack.config.js文件赖淤,原因看這個

下面這個命令谅河,謹(jǐn)慎執(zhí)行咱旱,因為不可逆。但是只要做好代碼版本管理绷耍,可以隨意折騰吐限,大不了重頭再來版本管理git的使用

2.1.1 yarn eject

$ yarn eject

執(zhí)行的時候,有提示:NOTE: Create React App 2+ supports TypeScript, Sass, CSS Modules and more without ejecting: https://reactjs.org/blog/2018/10/01/create-react-app-v2.html
因為褂始,執(zhí)行該命令后會把已構(gòu)建依賴項诸典、配置文件和腳本復(fù)制到程序目錄中。該操作是不可逆轉(zhuǎn)的崎苗,執(zhí)行完成后會刪除這個命令狐粱,也就是說只能執(zhí)行一次舀寓。

插曲:執(zhí)行的時候,被git給阻擋了肌蜻,因為是在學(xué)習(xí)互墓,所以我直接用

$ find . -name ".git" | xargs rm -Rf

用這個命令把git給清除了。如果是項目蒋搜,自己按照提示篡撵,把git相關(guān)的commit,stash什么的豆挽,處理完畢就好育谬。
執(zhí)行完畢后,package.json文件被更改了祷杈,與此同時斑司,會生成新文件夾config:


config文件夾

2.1.2修改webpack.config.js配置文件。

我們找到sassRegex但汞,模仿它來配置lessRegex宿刮。
(1).配置less

// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/; //這一句和下一句是新增的less的配置
const lessModuleRegex = /\.module\.less$/;

(2).配置less-loader
找到"test: sassRegex"這個,搜一下即可私蕾,然后模仿這個來寫less的僵缺。

// Adds support for CSS Modules, but using LESS
            {
              test: lessRegex,
              exclude: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  modules: true,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'less-loader'
              ),
              sideEffects: true,
            },
            {
              test: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: {
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'less-loader'
              ),
            },

這里,我先直接copy了sass的配置踩叭,然后改成less磕潮,運(yùn)行后不好用。之后容贝,又在lessRegex里加了一句modules: true,才可以運(yùn)行自脯。致于 importLoaders: 3,這后面的數(shù)字斤富,是3膏潮,是1,都好用满力,沒有查具體意義焕参。待調(diào)查

2.1.3 修改代碼

新建styles.less文件:

//styles.less
.title {
  color: red;
}

修改index.js文件:

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './styles.less'

const App = () => {
  console.log(styles);//打印一下,是一個對象油额,對象的元素的key是title
  return(
    <h1 className={styles.title}>Hello world</h1>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));

這里叠纷,引入less文件,作為styles潦嘶,設(shè)置className的時候涩嚣,將原本的雙引號,改成花括號。至此缓艳,less的引用成功校摩。

參考鏈接1:樣式設(shè)置和CSS文件引入
配置的時候請注意:關(guān)于 less 配置規(guī)則放在 sass 的解析規(guī)則下面即可看峻,如果放在了 file-loader 的解析規(guī)則下面阶淘,less 文件解析不會生效。(這段注意來自于網(wǎng)絡(luò)互妓,沒有驗證過)



2.2 配置方法二:無需eject進(jìn)行配置(不用暴露webpack)

參考1: Create React App無eject配置(react-app-rewired 和 customize-cra)
參考2: create-react-app 優(yōu)雅定制指南

初學(xué)者:因為溪窒,eject是一個不可逆的過程,所以冯勉,這里澈蚌,你需要重新創(chuàng)建一個項目來實驗。新建項目后灼狰,參照上面宛瞄,修改代碼,新建styles.less文件交胚,以及修改inde.js文件份汗。記得要安裝less和less-loader。然后蝴簇,運(yùn)行杯活。嗯,hello world是黑色的熬词,styles.less的文件沒有被成功調(diào)用旁钧。

下面,我們來進(jìn)行第二種互拾,相對優(yōu)雅的設(shè)置方案歪今。
react-app-rewired
是 react 社區(qū)開源的一個修改 CRA 配置的工具。純 react-app-rewired 的方式自定義配置颜矿,參考 Extended Configuration Options 文檔寄猩。
注意
react-app-rewired 1.x 配合 create-react-app 1.x
react-app-rewired 2.x 配合 create-react-app 2.x

版本升級導(dǎo)致互不兼容,另外或衡,react-app-rewired 2.x 應(yīng)該是社區(qū)維護(hù)了焦影。
react-app-rewired@^2.0.0+ 版本需要搭配 customize-cra 使用

在 react-app-rewired 1.x 的版本中,它除了提供覆蓋配置的方法封断,還體用了一些 helpers斯辰,例如 rewireLess、rewirePreact 等坡疼,2.x 版本只保留了核心功能彬呻。
另外一個工具幫我們實現(xiàn)了這些,customize-cra.

customize-cra
這次我們使用 customize-cra 協(xié)助自定義,參考 Using the plugins 文檔闸氮。

2.2.1 安裝

yarn add react-app-rewired customize-cra -D

2.2.2 修改package.json文件

//package.json
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
  },

2.2.3 在項目根目錄新建config-overrides.js

//config-overrides.js
const { override } = require('customize-cra');
module.exports = {};

2.2.4 配置less (在react使用JavaScript語言下)

在第一部分中剪况,我們已經(jīng)安裝了less和less-loader依賴,這里我們開始配置蒲跨。
這個過程中译断,筆者找了很多文章來看,大部分都是依賴react-app-rewired來做的或悲,但是孙咪,文章比較老,現(xiàn)在版本更新巡语,我們需要[customize-cra]來協(xié)助翎蹈。
customize-cra API docs
addLessLoader(loaderOptions)
我們來修改config-overrides.js文件:

//config-overrides.js
const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
  }),
)

好了,less配置成功男公,來運(yùn)行你的代碼吧荤堪!
??????,什么?枢赔?澄阳?不好用?糠爬?寇荧?
沒錯,確實不好用!筆者也在這里卡住了执隧,讀了數(shù)十篇文章揩抡,依然沒有找到解決方案,最終镀琉,還是回歸官網(wǎng)的文檔峦嗤,才搞明白緣由。
其實屋摔,CRA生成的React項目烁设,是可以直接用css modules的,但是钓试,css文件的命名是有規(guī)則的装黑,例如:styles.module.css。同理依賴css modules的less弓熏,文件名的命名規(guī)則也如此:styles.module.less恋谭。
好了,我們修改下文件名及index.js里的引用挽鞠,再運(yùn)行一次代碼疚颊。
報錯:


image.png

至此狈孔,我已哭死!!!調(diào)查后,發(fā)現(xiàn)是因為css-loader更新到3.0以后材义,出現(xiàn)的這個問題均抽,也因此,之前博客的方法其掂,都不起作用油挥。

參考1: https://github.com/arackaf/customize-cra/issues/201
我們先將"customize-cra": "^1.0.0-alpha.0"升級,此時清寇,用的就是這個版本的喘漏,
然后參考:https://github.com/rails/webpacker/issues/2197的gyurcigyurma說的,將config-overrides.js文件改成如下:(此時华烟,使用的是styles.module.less文件名)

//config-overrides.js
const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    loader: "css-loader",
    options: {
      modules: {
        localIdentName: "[name]__[local]___[hash:base64:5]",
      },
      sourceMap: true
    }
  }),
)

好了,我看到紅色的Hello world了持灰,終于可以正確運(yùn)行了盔夜。。堤魁。

2.2.5 配置less(在react使用TypeScript語言下)

用IDE新建項目喂链,比如webStorm,新建時妥泉,選擇支持TypeScript椭微。參考上面的1~4,進(jìn)行一次盲链,less文件用styles.modules.less這種.modules.less命名規(guī)則蝇率。我們也要更新customize-cra的版本。
除此之外刽沾,還有修改react-app-env.d.ts文件:

//react-app-env.d.ts
declare module "*.module.less"

筆者第二次執(zhí)行時本慕,運(yùn)行一直出錯,提示:

./src/styles.module.less (./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--6-oneOf-8-3!./node_modules/less-loader/dist/cjs.js??ref--6-oneOf-8-4!./src/styles.module.less)
ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'options'. These properties are valid:
   object { lessOptions?, prependData?, appendData?, sourceMap? }

筆者修改了config-overrides.js:

const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
  }),
)

好了侧漓,運(yùn)行成功锅尘,我們看見了紅色Hellow world。
因為沒有第一次運(yùn)行時候的demo布蔗,所以藤违,筆者并不確定問題具體出在哪,即便纵揍,按上面的步驟走顿乒,估計也會出錯,因為less-loader更新了骡男。淆游。傍睹。
為此,筆者貼出自己實驗的時候犹菱,所用依賴包的信息拾稳,僅供參考。

  "devDependencies": {
    "customize-cra": "^1.0.0-alpha.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "react-app-rewired": "^2.1.5"
  }

2.2.6 配置less(在react使用TypeScript語言下的優(yōu)化–––去掉含module的后綴名)

修改config-overrides.js:

const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    javascriptEnabled: true,
    cssLoaderOptions: {
      modules: {localIdentName: '[name]_[local]_[hash:base64:5]'},
    }, // .less file used css-loader option, not all CSS file.
  }),
)

修改react-app-env.d.ts文件:

/// <reference types="react-scripts" />

declare module "*.less"

最后腊脱,注意也要修改styles.less的文件名以及在indext.tsx的import路徑访得。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2.2.6 擴(kuò)展:引用CSS Module

新建文件styles.module.css

//styles.module.css
.title {
  color: blue;
}

修改index.js文件:

//index.js
import stylesCss from './styles.module.css'
//.......省略
<h1 className={stylesCss.title}>Hello CSS Modules</h1>
//.......省略

運(yùn)行,成功陕凹。

3. 總結(jié)

為了方便快速瀏覽悍抑,筆者對第二種比較優(yōu)雅的配置方法,進(jìn)行總結(jié)杜耙。如果上面部分已經(jīng)看過了搜骡,這部分可以忽略,僅僅是對上面陳述的方法二的總結(jié)佑女。

3.1 安裝依賴

#安裝less和less-loader
$yarn add less less-loader -D
#安裝react-app-rewired
$yarn add react-app-rewired -D
#安裝customize-cra 如果记靡,你安裝時的最新版本已經(jīng)超過這個,可以不用指定版本
$yarn add customize-cra@^1.0.0-alpha.0 -D

3.2 修改package.json文件

//package.json
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
  },

3.3 在項目根目錄新建config-overrides.js

并對less進(jìn)行配置:

//config-overrides.js
const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    loader: "css-loader",
    options: {
      modules: {
        localIdentName: "[name]__[local]___[hash:base64:5]",
      },
      sourceMap: true
    }
  }),
)

3.4 對于支持TypeScript的項目的配置

修改config-overrides.js:

const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
  }),
)

修改react-app-env.d.ts文件:

//react-app-env.d.ts
declare module "*.module.less"

3.5 對于支持TypeScript的項目的配置的優(yōu)化(去掉.module的后綴)

修改config-overrides.js:

const { override, addLessLoader } = require('customize-cra');

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    javascriptEnabled: true,
    cssLoaderOptions: {
      modules: {localIdentName: '[name]_[local]_[hash:base64:5]'},
    }, // .less file used css-loader option, not all CSS file.
  }),
)

修改react-app-env.d.ts文件:

/// <reference types="react-scripts" />

declare module "*.less"

最后团驱,注意也要修改styles.less的文件名以及在indext.tsx的import路徑摸吠。

3.6 測試

注意less文件命名規(guī)則,后綴為.module.less

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './styles.module.less' 

const App = () => {
  console.log(styles);//打印一下嚎花,是一個對象寸痢,對象的元素的key是title
  return(
    <h1 className={styles.title}>Hello world</h1>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
//styles.module.less
.title {
  color: red;
}

3.7 糾錯

筆者,在第二次補(bǔ)充的時候紊选,發(fā)現(xiàn)又跑不起來了啼止。經(jīng)調(diào)查,發(fā)現(xiàn)是因為less-loader版本更新的原因丛楚,為此族壳,筆者貼出測試的時候,所用依賴庫的版本:

  "devDependencies": {
    "customize-cra": "^1.0.0-alpha.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "react-app-rewired": "^2.1.5"
  }

網(wǎng)上趣些,查看各種文檔都不好用的時候仿荆,包括筆者這篇也被淘汰的時候,建議你看看官網(wǎng)customize-cra API坏平,這個是找答案最快捷的辦法拢操。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舶替,隨后出現(xiàn)的幾起案子令境,更是在濱河造成了極大的恐慌,老刑警劉巖顾瞪,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舔庶,死亡現(xiàn)場離奇詭異抛蚁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惕橙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門瞧甩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弥鹦,你說我怎么就攤上這事肚逸。” “怎么了彬坏?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵朦促,是天一觀的道長。 經(jīng)常有香客問我栓始,道長务冕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任混滔,我火速辦了婚禮洒疚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坯屿。我一直安慰自己,他們只是感情好巍扛,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布领跛。 她就那樣靜靜地躺著,像睡著了一般撤奸。 火紅的嫁衣襯著肌膚如雪吠昭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天胧瓜,我揣著相機(jī)與錄音矢棚,去河邊找鬼。 笑死府喳,一個胖子當(dāng)著我的面吹牛蒲肋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钝满,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼兜粘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弯蚜?” 一聲冷哼從身側(cè)響起孔轴,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碎捺,沒想到半個月后路鹰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贷洲,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年晋柱,在試婚紗的時候發(fā)現(xiàn)自己被綠了优构。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡趣斤,死狀恐怖俩块,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浓领,我是刑警寧澤玉凯,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站联贩,受9級特大地震影響漫仆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泪幌,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一盲厌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祸泪,春花似錦吗浩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至右蒲,卻和暖如春阀湿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瑰妄。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工陷嘴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人间坐。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓灾挨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親眶诈。 傳聞我的和親對象是個殘疾皇子涨醋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容