寫在開頭
為什么會有這篇文章?
眾所周知兰伤,前端技術棧太過廣泛内颗,要一個技術人員選擇一套高度可復用的前端架構也是挺費事費神的,筆者這篇文章敦腔,主要講述的是一套基于react技術棧開發(fā)網(wǎng)站的成熟方案均澳,重點解決在集成這一套技術棧過程中的坑點,從開發(fā)到上線符衔,從依賴包到腳手架找前。本文將 從0到1 講解使用react開發(fā)網(wǎng)站中使用到的技術棧。
1判族、使用create-react-app創(chuàng)建項目
在開始之前躺盛,你可能需要安裝 yarn。
yarn create react-app antd-demo
# or
$ npx create-react-app antd-demo
工具會自動初始化一個腳手架并安裝 React 項目的各種必要依賴形帮,如果在過程中出現(xiàn)網(wǎng)絡問題槽惫,請嘗試配置代理或使用其他 npm registry。
2辩撑、支持less
- 為項目創(chuàng)建本地git倉庫
git init
git add .
git commit -m 'init'
如果不進行這一步操作界斜,直接運行 yarn eject
會報如下錯誤
This git repository has untracked files or uncommitted changes:
因為在初始化項目之后,該項目并沒有本地 git 倉庫槐臀,而此項目目錄下又有 .gitignore 文件锄蹂,所以此時會向上級尋找未提交的項目。
- 安裝依賴
yarn add less less-loader -D
- 暴露webpack配置
yarn eject
運行完命令水慨,中間會有一個交互命令,直接輸入:y 即可敬扛,完成后會生成config和script兩個文件夾
- 配置webpack.config.js
修改config/webpack.config.js
新增less配置變量
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/; // 新增less配置
const lessModuleRegex = /\.module\.less$/; // 新增less配置晰洒,這個其實不配置也行
增加module下面rule規(guī)則,可以copy cssRegex
或者sassRegex
的配置啥箭。
{
test: sassModuleRegex,
use: getStyleLoaders({
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent
},
"sass-loader"
)
},
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders({
importLoaders: 1,// 值是1
// modules: true, // 增加這個可以通過模塊方式來訪問css, 這里之所以注釋谍珊,是因為和后面的自定義主題有沖突
sourceMap: isEnvProduction && shouldUseSourceMap
},
"less-loader"
),
sideEffects: true
},
{
test: lessModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent
},
"less-loader"
)
},
// "file" loader makes sure those assets get served by WebpackDevServer.
至此,項目已經(jīng)支持less了急侥,可以將src下的App.css
改成App.less
砌滞,記得引用的地方也要改侮邀。然后修改一個樣式保存試試,贝润,執(zhí)行yarn start
發(fā)現(xiàn)已經(jīng)修改成功
需要注意以下幾個地方:
1.lessRegex
中importLoaders的值為1
當然這個是2也能使用绊茧,但是它的值是根據(jù)lessRegex變量后面正則中匹配的loader數(shù)來決定的,比如
const cssRegex = /\.css$/
只是處理css一種類型的文件打掘,那應該就是1华畏;const sassRegex = /\.(scss|sass)$/;
對應的是scss和sass兩種類型,那就應該是2.
2.lessRegex
的use中增加modules配置
modules可以不設置尊蚁,不設置的話亡笑,less只能通過字符串名的方式使用,比如定義了一個
.title
,引用時import './index.less'
横朋,使用時:<div className="title"></div>
仑乌。如果需要通過模塊的方式調用,則需要把modules設置成true琴锭,就可以通過styles.title
方式使用了绝骚。import styles from './index.less'
,使用<div className={styles.title}></div>
。一開始筆者也是設置成了true祠够,后面發(fā)現(xiàn)和antd自定義主題存在沖突压汪,一時沒搞明白,就暫且不用這種方式古瓤,也不影響止剖。
3、安裝antd落君、配置按需加載穿香、自定義主題
- 安裝依賴
yarn add antd babel-plugin-import
- 配置antd按需加載
antd按需加載不用每次都在引入組件的地方引入特定樣式 或者 全局引入antd樣式。
在package.json的babel中插入如下配置即可:
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": "css"
}
]
]
- 配置antd主題
antd的默認主題往往不能滿足需求绎速,這個時候就需要自定義主題
通過上面修改package.json
我們已經(jīng)實現(xiàn)了antd組件按需加載了皮获,不需要再額外引入組件樣式了,但是如果要更改antd主題顏色的話纹冤,這里這個style屬性值就不能是css
了洒宝。必須改成true
,原因是因為值是css時按需加載時加載的就是antd編譯后之后的css文件萌京,要更改主題顏色是要更改less變量的雁歌,而true標識直接加載antd的less文件,注意知残,坑來了?肯埂!當你設為true時,你會發(fā)編譯失敗乏盐,頁面中antd組件也會沒有樣式了佳窑,命令行拋出如下異常:
這是因為你還沒配置less-loader
的配置項,在之前我復制修改的那個地方只是引入使用了less-loader父能,并沒有添加配置項神凑,導致他就會出現(xiàn)這個異常,在網(wǎng)上找資料大概less的版本2.7.3以前不會出現(xiàn)這個問題法竞,所以我們要先給less-loader一個修改antd主題顏色的配置耙厚。
修改getStyleLoaders方法,支持傳入自定義options
# 方法多接收一個newOptions參數(shù)
- const getStyleLoaders = (cssOptions, preProcessor) => {
+ const getStyleLoaders = (cssOptions, preProcessor, newOptions) => {
# 將newOptions添加到loaders中
if (preProcessor) {
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
// 開始添加
...newOptions,
// 結束添加
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
{
loader: require.resolve(preProcessor),
options: {
// 開始添加
...newOptions,
// 結束添加
sourceMap: true,
},
}
);
}
less配置中的 getStyleLoaders 添加options參數(shù)的值
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap
},
"less-loader",
// 開始添加
{
javascriptEnabled: true,
modifyVars: { "primary-color": "#ff4c4c", }
}
// 結束添加
),
sideEffects: true
}
至此自定義主題就已經(jīng)配置完畢岔霸!
4薛躬、使用react-router
react-router 是一個基于 react 之上的強大路由庫,它可以讓你向應用中快速地添加視圖和數(shù)據(jù)流呆细,同時保持頁面與 URL 間的同步型宝,umi中也集成了react-router。
- 安裝依賴
yarn add react-router-dom
- 使用路由
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { HashRouter, Route, Switch } from 'react-router-dom'
import * as serviceWorker from './serviceWorker';
import Home from './pages/Home';
import About from './pages/About';
ReactDOM.render(<HashRouter>
<Switch>
<Route exact path='/' component={Home} />
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
</Switch>
</HashRouter>, document.body);
serviceWorker.unregister();
詳細使用參考 react-router使用
5絮爷、項目打包給文件增加隨機碼趴酣,解決 微信/瀏覽器 緩存問題
- 打開
webpack.config.js
,添加如下常量
// 新增時間戳作為版本號坑夯,解決緩存(微信緩存)問題
const version = Date.now();
- 修改文件名
修改前如下:
修改后如下:
這個時候通過 yarn build
命令打包出來的文件岖寞,會多出一個時間戳后綴,至此緩存問題解決柜蜈!
6仗谆、制作成腳手架
通過上面的操作,其實我們想當于已經(jīng)搭建了一個開箱即用的淑履、基于react+antd+less+react-router
等模板的開發(fā)輪子隶垮,那么這個時候為了避免以后我們每次創(chuàng)建工程都要重復這些操作,這個時候可以考慮將這個搭建好的工程做成一個腳手架上傳秘噪,以后每次只需要簡單一個命令就可以快速創(chuàng)建一個同樣的工程了狸吞。
腳手架作用和原理
日常工作中我們其實接觸到了不少腳手架,像vue-cli
指煎、create-react-ap
之類的蹋偏,那么從這里我們就可以看出,腳手架其實就是一個快速構建初始工程的腳本贯要,來幫助開發(fā)者節(jié)省開發(fā)時間暖侨,提高開發(fā)效率的工具。
開始制作腳手架
- 創(chuàng)建腳手架工程
// 創(chuàng)建腳手架目錄崇渗,命令為 create-cli
mkdir create-cli
// 初始化npm模板,根據(jù)引導創(chuàng)建 package.json文件
npm init
- 安裝依賴
commander.js,可以自動的解析命令和參數(shù)宅广,用于處理用戶輸入的命令葫掉。
download-git-repo,下載并提取 git 倉庫跟狱,用于下載項目模板俭厚。
Inquirer.js,通用的命令行用戶界面集合驶臊,用于和用戶進行交互挪挤。
handlebars.js,模板引擎关翎,將用戶提交的信息動態(tài)填充到文件中扛门。
ora,下載過程久的話纵寝,可以用于顯示下載中的動畫效果论寨。
chalk,可以給終端的字體加上顏色爽茴。
log-symbols葬凳,可以在終端上顯示出 √ 或 × 等的圖標。
yarn add commander download-git-repo Inquirer handlebars ora chalk log-symbols
- 編寫腳本
創(chuàng)建 bin 目錄來存放腳本文件室奏,編寫如下腳本 .bin/index.js
#!/usr/bin/env node
const program = require('commander');
const download = require('download-git-repo');
const ora = require('ora');
const chalk = require('chalk');
const symbols = require('log-symbols');
const spinner = ora('start create ...')
program.version('1.0.0', '-v, --version')
.command('init <name>')
.action((name) => {
spinner.start()
download('direct:gitbug地址', name, {clone: true}, (err) => {
if(err){
spinner.fail('create failed')
}else{
spinner.succeed('create success')
}
})
});
program.parse(process.argv);
修改 package.json 文件 package.json
{
"name": "create-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": "./bin/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
- 本地測試
編寫完成了腳本火焰,我們可以先不發(fā)布到npm
官網(wǎng),先做一下本地測試胧沫,在工程根目錄執(zhí)行 npm link
即可在本地安裝腳本全局映射昌简。然后執(zhí)行如下命令測試腳本是否正常運行:
create-cli init test
- 發(fā)布npm
測試完成之后,運行如下命令將命令發(fā)布到 npm
公網(wǎng):
npm publish
之后團隊其他人員就可以通過如下命令安裝腳手架了
npm install create-cli -g
參考文章
create-react-app使用less最詳細說明 2019-04-13
create-react-app 16.8最新版配置less以及antd自定義主題
react中打包時解決瀏覽器緩存的問題
基于node.js的腳手架工具開發(fā)經(jīng)歷
用Node.js簡單寫個腳手架