摘要:前言作為官方的腳手架是相當(dāng)好用的。注意就是腳手架的核心配置代碼。另一個(gè)是使用,用戶通過增加修改配置。所以才有了今天的主題基于的腳手架,確切說應(yīng)該是基于的腳手架。其中一定要填寫。
前言create-react-app作為facebook官方的react腳手架是相當(dāng)好用的。主要設(shè)計(jì)原理是將配置好的如Webpack,Babel,ESLint,合并到react-scripts這npm包中,用戶就可以開箱即用。很多開發(fā)者都在這基礎(chǔ)上進(jìn)行改造開發(fā)。注意react-scripts就是create-react-app腳手架的核心配置代碼。
目前如果要自己定制配置,有兩種方案可選。一個(gè)是eject,他的原理是將react-scripts拆除然后將配置暴露到應(yīng)用頂層,用戶就可以自行進(jìn)行配置。另一個(gè)是使用react-app-rewired,用戶通過config-overrides.js增加修改配置。兩者各有好處。eject直接暴露可以自行配置,但是壞處就是react-scripts被解散了,就不能隨官方配置進(jìn)行升級(jí)。react-scripts包攬了那些最基礎(chǔ)配置的臟活累活,并且一直再維護(hù),比如修復(fù)BUG和打包優(yōu)化,運(yùn)行速度優(yōu)化。前端發(fā)展的迅速,這些基礎(chǔ)配置隨著基礎(chǔ)設(shè)施的升級(jí),可能隨時(shí)都會(huì)變化。我覺得eject后要就需要承擔(dān)維護(hù)成本的風(fēng)險(xiǎn)。我的理念是將專業(yè)的事情交給專業(yè)的人去做就好了,我們應(yīng)該享受金字塔底層帶來的基礎(chǔ)設(shè)施便利去創(chuàng)造價(jià)值,沒必要重復(fù)造輪子,更沒必要在輪子上耗費(fèi)過多的維護(hù)成本。
我的理念是推薦使用config-overrides.js來定制配置,降低維護(hù)成本。也就是在react-scripts的配置上進(jìn)行增刪改查,不影響底層配置代碼,在未來需要的時(shí)候還可以進(jìn)行無縫升級(jí)react-scripts,來提升速度或者解決你未關(guān)注到的BUG等等。但是create-react-app只是提供最最基礎(chǔ)的設(shè)施建設(shè),我們最常用的框架配置都需要自己去定制,每次創(chuàng)建項(xiàng)目的時(shí)候都需要再寫一次定制代碼,相當(dāng)煩人。所以才有了今天的主題基于create-react-app的腳手架,確切說應(yīng)該是基于react-scripts的腳手架。
所以這篇文章主題應(yīng)該有兩個(gè)
怎么制作CLI工具
怎么根據(jù)react-scripts來寫腳手架
項(xiàng)目核心代碼在github上:(github.com/LinYouYuan/…),這個(gè)鏈接上面也有使用幫助說明,可以先點(diǎn)擊進(jìn)去看,可以更好的理解使用和需求。
項(xiàng)目核心需求我們需求是:
保證基礎(chǔ)依賴和官方同步;
創(chuàng)建時(shí)增加常用框架選擇;
創(chuàng)建項(xiàng)目后配置項(xiàng)可定制;
第一點(diǎn),我們需要引入react-scripts和react-app-rewired,來保持官方同步和可定制型。
第二點(diǎn),我整理出我們常用的框架可選項(xiàng):
類型 | 可選框架名稱 |
---|---|
語言 | JavaScript / TypeScript |
狀態(tài)管理庫 | Redux / Mobx |
css預(yù)處理器 | SCSS / LESS / styled-components |
UI組件 | Antd / Ant-mobile |
代碼規(guī)范 | Airbnb |
HTTP庫 | Axios |
路由 | react-router |
第三點(diǎn),創(chuàng)項(xiàng)目后我們可以通過config-overrides.js文件來預(yù)先配置,然后用戶可以再此文件進(jìn)行繼續(xù)配置和改造。
制作CLI工具 引入常用工具包首先創(chuàng)建nodejs項(xiàng)目。制作常用的Cli工具,我們一般都需要安裝下面5個(gè)工具包:(執(zhí)行npm install或者其他工具安裝)
commander: 用來接收輸入命令參數(shù),然后處理事件;
execa: 用來執(zhí)行操作命令,一個(gè)更好的child_process;
inquirer: 這是創(chuàng)建cli最主要的工具,可以生成非常美觀的命令行界面;
chalk: 可以修改字體顏色;
fs-extra: 比原生fs更好用的fs;
創(chuàng)建全局使用我們首先要?jiǎng)?chuàng)建一個(gè)像creact-react-app一樣直接在全局就可以執(zhí)行使用的命令。
我們?cè)诟夸浵聞?chuàng)建文件夾和文件lib/index.js,這個(gè)其實(shí)就是入口執(zhí)行文件。其中#!/usr/bin/env node一定要填寫。
lib/index.js
#!/usr/bin/env node
console.log("hello world")
然后在package.json中添加代碼,如下,其中react-cli就是全局要使用的命令名稱,lib/index.js就是上面要執(zhí)行的文件地址。
package.json
"bin": { "react-cli": "lib/index.js" }
執(zhí)行npm link。執(zhí)行完成后,我們就可以把命令掛載到全局,效果和npm install -g后一樣,可以全局輸入命令。link的主要目的是給我開發(fā)調(diào)試用的?,F(xiàn)在可以直接在控制臺(tái)輸入react-cli執(zhí)行,你就可以看到打印的hello world了。
等開發(fā)完成,你可以試試發(fā)布到npm包上,但是我推薦等開發(fā)完成后再發(fā)布,當(dāng)然不妨礙你好奇心想試試。發(fā)布前需要執(zhí)行npm login,登錄npm賬號(hào)密碼,注意你如果是淘寶源你需要通過npm config set registry http://registry.npm.tongdun.cn暫時(shí)切回官方源。然后執(zhí)行npm publish發(fā)布,這個(gè)時(shí)候也要注意,你的package.json中的name也就是項(xiàng)目名稱不要和別人重名了。發(fā)布好你就可以通過npm i
在lib/index.js中,我們輸入如下
const program = require("commander");
const chalk = require("chalk");
program
.version(require("../package").version)
.usage(" [options]" );
program
.command("create " )
.description("create a new project powered by react-cli")
.action(name => {
// 這里處理邏輯
console.log(chalk.blue(`React CLI v${require("../package").version}`));
// const create = require("./cli/create");
// create(name);
});
這里主要通過commander來配置接受不同命令處理。這里主要就是要接受create
然后繼續(xù)處理未輸入和輸入錯(cuò)時(shí)候彈出幫助如下
program
.arguments("" )
.action((cmd) => {
program.outputHelp()
console.log(` ` + chalk.red(`Unknown command ${chalk.yellow(cmd)}.`))
console.log()
})
program.parse(process.argv);
if (!program.args.length) {
program.outputHelp();
}
交互界面
接收到用戶輸入的命令后,我們就要呈現(xiàn)交互界面,這個(gè)時(shí)候我們就用到了非常好用的工具inquirer。具體可以實(shí)現(xiàn)多少種交互形式可以點(diǎn)inquirer的npm網(wǎng)站的介紹看。我這里主要用了list和confirm的功能,也就是列表選擇和尋問功能。比如讓用戶選擇使用什么框架:
function selectManually(appName) {
inquirer
.prompt([
{
type: "list",
name: "language",
message: "pick a language:",
choices: [
"JavaScript",
"TypeScript",
]
},
{
type: "list",
name: "stateManagement",
message: "Pick a state management:",
choices: [
"Mobx",
"Redux",
]
},
{
type: "list",
name: "cssPre",
message: "Pick a CSS pre-processor:",
choices: [
"LESS",
"SCSS/SASS",
"styled-components",
]
},
{
type: "list",
name: "design",
message: "Pick a UI Design:",
choices: [
"Ant Design",
"Ant Design Mobile",
]
},
])
.then(answers => {
const creator = new Creator(appName, answers);
creator.create();
})
}
創(chuàng)建項(xiàng)目
新建一個(gè)Creator類,主要用來創(chuàng)建項(xiàng)目用的,初始化接受兩個(gè)參數(shù),一個(gè)是項(xiàng)目名稱,一個(gè)是用戶選擇的框架。我項(xiàng)目中的模板存放在lib/packages/common-default中。這里我主要針對(duì)各種不同的配置,來修改packages.json、babelrc、config-overrides.js文件的內(nèi)容就好了,然后執(zhí)行復(fù)制操作。
const chalk = require("chalk");
const fs = require("fs-extra");
const path = require("path");
const inquirer = module.require("inquirer");
const {
getPackageJson,
writeJsonToApp,
copyFiles,
setNewPackageVersion,
installPackge,
setUserConfig,
} = require("../packages/common");
class Creator {
constructor(appName, answers) {
this.appName = appName;
this.answers = answers;
this.appDir = path.resolve(process.cwd(), this.appName);
this.package = getPackageJson("cli-switch");
this.babelrc = {
plugins: [
[
"import",
{
libraryName: "antd",
style: true,
}
]
]
}
}
async testExistDir() {
if (fs.existsSync(this.appDir)) {
const { override } = await inquirer.prompt([
{
type: "confirm",
name: "override",
message: chalk.red(`directory ${this.appName} exist,override it");)
}
]);
if (override) {
console.log(chalk.green("removing..."));
fs.removeSync(this.appDir);
return true;
} else {
process.exit(1);
return false;
}
}
return true;
}
async create() {
const { stateManagement, cssPre, design } = this.answers;
console.log();
console.log(`you pick: ${chalk.yellow(`${stateManagement}, ${cssPre}, ${design}, Router, ESLint`)}`);
console.log();
const isOk = await this.testExistDir(this.appDir, this.appName);
if (!isOk) {
return;
}
console.log(`
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/7313.html
摘要:弄清之后,就去腳手架源代碼里面找。這樣更加靈活,而且復(fù)用性高,起新項(xiàng)目,如果差別不大,幾乎可以做到零配置,這樣開發(fā)者壓根就不需要關(guān)心業(yè)務(wù)之外的東西從零開始開發(fā)一個(gè)腳手架三 上一篇已經(jīng)初步整了個(gè)kkk-react,這一篇不寫代碼,粗略講解下create-react-app的部分源碼。 前沿:科普下看源碼的思路。以本人看過N多源碼的經(jīng)驗(yàn)總結(jié),想要看這種腳手架或者npm包的源碼,第一步就是看...
摘要:這個(gè)選項(xiàng)看意思就知道了,默認(rèn)使用來安裝,運(yùn)行,如果你沒有使用,你可能就需要這個(gè)配置了,指定使用。 2018-06-13 更新。昨天突然好奇在Google上搜了一波關(guān)于create-react-app 源碼的關(guān)鍵詞,發(fā)現(xiàn)掘金出現(xiàn)好幾篇仿文,就連我開頭前沿瞎幾把啰嗦的話都抄,我還能說什么是吧?以后博客還是首發(fā)在Github上,地址戳這里戳這里?。∞D(zhuǎn)載求你們注明出處、改編求你們貼一下參考鏈...
摘要:編碼規(guī)范是獨(dú)角獸公司內(nèi)部的編碼規(guī)范,該項(xiàng)目是上很受歡迎的一個(gè)開源項(xiàng)目,在前端開發(fā)中使用廣泛,本文的配置規(guī)則就是以編碼規(guī)范和編碼規(guī)范作為基礎(chǔ)的。 更新時(shí)間:2019-01-22React.js create-react-app 項(xiàng)目 + VSCode 編輯器 + ESLint 代碼檢查工具 + Airbnb 編碼規(guī)范 前言 為什么要使用 ESLint 在項(xiàng)目開發(fā)過程中,編寫符合團(tuán)隊(duì)編碼規(guī)...
摘要:使用來進(jìn)行按需加載安裝關(guān)于插件的介紹和使用,可參考使用這個(gè)插件之后仍然可以用來引入組件,但是這個(gè)時(shí)候插件會(huì)幫你轉(zhuǎn)換成的寫法。另外此插件配合屬性可以做到模塊樣式的按需自動(dòng)加載。 引言 create-react-app:是一個(gè)創(chuàng)建react項(xiàng)目特別方便的腳手架,他幫我們配置好了各種需要使用的工具,減少了很多工作量。antd:是螞蟻金服推出的一個(gè)很優(yōu)秀的react UI庫,其中包含了很多我...
摘要:通過文件可以對(duì)圖標(biāo)名稱等信息進(jìn)行配置。注意,注冊(cè)的只在生產(chǎn)環(huán)境中生效,并且該功能只有在下才能有效果該文件是過濾文件配置該文件是描述文件定義了項(xiàng)目所需要的各種模塊,以及項(xiàng)目的配置信息比如名稱版本許可證等元數(shù)據(jù)。 一、 快速開始: 全局安裝腳手架: $ npm install -g create-react-app 通過腳手架搭建項(xiàng)目: $ create-react-app 開始項(xiàng)目: ...
閱讀 1255·2023-04-26 03:02
閱讀 1315·2023-04-25 19:18
閱讀 2662·2021-11-23 09:51
閱讀 2645·2021-11-11 16:55
閱讀 2702·2021-10-21 09:39
閱讀 1788·2021-10-09 09:59
閱讀 2083·2021-09-26 09:55
閱讀 3611·2021-09-26 09:55