欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

「手把手」15分鐘搭一個企業(yè)級腳手架

1 寫在前面的話

我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、成都做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、鑲黃ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的鑲黃網(wǎng)站制作公司

搭一個腳手架,考驗(yàn)了你的 nodejs 水平、工程化能力、以及工具服務(wù)的設(shè)計能力,是前端進(jìn)階不可或缺的過程

筆者在開發(fā) cli 的過程中,調(diào)研流行的 cli 并形成最佳實(shí)踐,本文旨在用最短的篇幅實(shí)現(xiàn)主要功能,揭露核心原理,同時提供 demo 倉庫與大家學(xué)習(xí)探討。

通篇閱讀大約需要 10 分鐘,基于本教程自己擼一個 cli 大約需要花費(fèi) 15 分鐘

2 腳手架的雛形

其實(shí)腳手架的初衷,就是提供一個最佳實(shí)踐的基礎(chǔ)模板,因此模板拷貝是其核心功能

幾年前我曾寫過一個極簡的腳手架,大該干了這么一件事兒

  1. npm publish 一個全局安裝的包

  2. 執(zhí)行命令時,wget 我云服務(wù)上的一個壓縮包,并在當(dāng)前文件夾下解壓

一個命令,就可以把我預(yù)設(shè)的完整的工程目錄創(chuàng)建好,特別方便效率。

我想,這應(yīng)該算是一個雛形腳手架吧

3 腳手架需要考慮的

上面雛形腳手架可以很好的服務(wù)于個人需求,但是畢竟過于干癟和簡陋,要想成為被大家廣泛接受的工具,還需要完善。

大家熟知的 vue-cli create-react-app @tarojs/cli umi 最基本功能:首先提出一些列問題選項(xiàng),然后為你的新建項(xiàng)目提供一份模板并安裝依賴,再提供調(diào)試構(gòu)建命令

沒錯,最核心的部分就是這個思路;但如果要做成一個可伸縮的、用戶友好的,還需考慮這些需求:

  • 模板支持版本管理

  • 支持?jǐn)U展新模板

  • 自動檢測版本更新

  • 根據(jù)用戶選擇,生成個性化模板

  • 友好的UI界面

  • 構(gòu)建功能獨(dú)立,可因模板而異 (如區(qū)分H5/PC/weapp/RN)

  • 多人合作項(xiàng)目,能確保構(gòu)建結(jié)果一致

看起來信息量有點(diǎn)大,但其實(shí)都并不晦澀,我們一一說明一下意圖

3.1 模板支持版本管理

比如用戶使用 v1.0.0 的模板創(chuàng)建了項(xiàng)目,半年后,已經(jīng)迭代升級到了 v2.0.0。我們需要依舊能夠找到 v1.0.0 版本,因?yàn)槔嫌脩舨幌牖蛘卟环奖闵墶?/p>

像我之前的雛形腳手架,將模板打一個壓縮包放在云服務(wù)器上是不可行的,一旦更新就全量替換了

npm 倉庫天然支持版本管理,因此將模板發(fā)布到 npm 上自然解決了這個問題?(非開源項(xiàng)目,可考慮自建倉庫或者私有的倉庫)

3.2 支持?jǐn)U展新模板

比如我們一開始我們的腳手架支持 H5 的模板。

半年后,隨著業(yè)務(wù)發(fā)展,需支持微信小程序的模板。

此時,我們無需額外再開發(fā)一個 cli,而是讓 cli 一開始設(shè)計的就支持?jǐn)U展,這符合了開放封閉的設(shè)計原則

3.3 自動檢測版本更新

npm 提供了一些命令來檢測包的版本,比如你 npm view react version 返回 16.9.0,告知你最新版本

借此,可以判斷用戶目前安裝的是否最新版本,并提示用戶更新

3.4 根據(jù)用戶選擇,生成個性化模板

模板雖說是為了統(tǒng)一,但也要在統(tǒng)一中支持差異,可通過問詢用戶,來提供差異化支持,比如:

「手把手」15分鐘搭一個企業(yè)級腳手架

這些問詢的結(jié)果,將影響我們最終的模板,比如我們根據(jù)是否 TypeScript 會在兩套預(yù)設(shè)的模板中選一個套,將用戶輸入的「項(xiàng)目介紹」插入 package.json 的 description 字段等等

3.5 友好的UI界面

合適的格式、顏色、字體、進(jìn)圖條等,給與用戶良好的信息反饋

下文會介紹一些常用的庫,來提供這些功能

3.6 構(gòu)建功能獨(dú)立,可因模板而異

我們通常使用 webpack 來構(gòu)建/調(diào)試,對于不同的模板,構(gòu)建流程存在較大差異,我們需要支持為不同的模板配置不同的構(gòu)建

因此構(gòu)建能力也被抽離成單獨(dú)的 npm 包,模板中可指定其構(gòu)建包

3.7 多人合作項(xiàng)目,能確保構(gòu)建結(jié)果一致

因?yàn)榇嬖诙喟姹荆覀冃枰s束,讓所有項(xiàng)目的貢獻(xiàn)者的產(chǎn)出是一致的

其核心原則就是:針對那些可能導(dǎo)致差異的因素,我們都收錄到工程中,讓 git 倉庫記錄,從而實(shí)現(xiàn)同樣,因此,現(xiàn)在流行的腳手架,如 umi taro,都將?構(gòu)建能力 local 化到本地工程中,后續(xù)會做詳細(xì)闡明

4 腳手架的三類包

一個被實(shí)踐檢驗(yàn),能夠符合上述需求的腳手架架構(gòu),其實(shí)非常簡單,首先我們拆分成三類 npm 包:

包 功能 安裝位置 備注 全局命令包 就像一個大腦,負(fù)責(zé)響應(yīng)全局命令,并進(jìn)行調(diào)度 全局包路徑 global 安裝,提供全局命令 模板插件包 初始化工程所拷貝的模板 某個約定路徑,如 ~/.maoda 模板可隨業(yè)務(wù)擴(kuò)展 構(gòu)建插件包 提供構(gòu)建(webpack)能力 工程內(nèi)?(目前主流腳手架都改用此方案)?不同模板可使用同一構(gòu)建包,也可不同 注:構(gòu)建插件包,早期很多腳手架都把它放在工程外,比如放在全局,優(yōu)勢是多工程可復(fù)用一套 webpack 能力,但弊端也暴露出來,即在多人協(xié)同開發(fā)的項(xiàng)目中,由于構(gòu)建插件包不在工程里沒能被 git 倉庫收錄,導(dǎo)致一些不可預(yù)期的差異結(jié)果。

其調(diào)度關(guān)系如下:

「手把手」15分鐘搭一個企業(yè)級腳手架

5 全局命令包

前面說了一通理論,下面開始正式搭建

全局命令包的功能:負(fù)責(zé)接收全局命令,并調(diào)度。

比如我做的 cli 的模板 demo cli-tpl

npm?i?cli-tpl?-g
#?或?yarn?global?add?cli-tpl
復(fù)制代碼

全局安裝后,暴露出一個 dcli 命令?(自己隨便取的名字),該命令有以下典型功能:

暴露全局命令通過 package.json 中 bin 來指定,可參考我的 demo

命令 效果 dcli install [pkgName] 安裝一個「模板插件包」到 ~/.maoda 路徑,如果已經(jīng)安裝再執(zhí)行,則詢問更新到最新版,如安裝 dcli install gen-tpl dcli init 以某個模板初始化一個新工程,執(zhí)行后會讓你從已裝模板里選擇 dcli build 在工程根目錄執(zhí)行?(或?qū)戇M(jìn)工程的 scripts 里),嘗試讀取工程依賴的「構(gòu)建插件包」并執(zhí)行構(gòu)建 dcli dev 與 dcli build 類似,只不過是執(zhí)行調(diào)試 5.1 cli 開發(fā)中值得收藏的一些第三方調(diào)料包

重要性 包名稱 功能 必要 minimist 解析用戶命令,將 process.argv 解析成對象 必要 fs-extra 對 fs 庫的擴(kuò)展,支持 promise 必要 chalk 讓你 console.log 出來的字帶顏色,比如成功時的綠色字 必要 import-from 類似 require,但支持指定目錄,讓你可以跨工程目錄進(jìn)行 require,比如全局包想引用工程路徑下的內(nèi)容 必要 resolve-from 同上,只不過是 require.resolve 必要 inquirer 詢問用戶并記錄反饋結(jié)果,界面互動的神器 必要 yeoman-environment 【核心】用于執(zhí)行一個「模板插件包」,后文詳細(xì)描述 錦上添花 easy-table 類似 console.table,輸出漂亮的表格 錦上添花 ora 提供 loading 菊花 錦上添花 semver 提供版本比較 錦上添花 figlet console.log出一個漂亮的大logo 錦上添花 cross-spawn 跨平臺的child_process (跨 Windows/Mac) 錦上添花 osenv 跨平臺的系統(tǒng)信息 錦上添花 open 跨平臺打開 app,比如調(diào)試的時候開打 chrome 5.2 命令解析與分發(fā)

命令的解析與分發(fā),是「全局命令包」的核心功能,其過程比較簡單。大家也可以直接看倉庫 cli-tpl?(全部功能壓縮到大約300行代碼)

  1. cli 版本更新判斷:

  • 先獲取本 package.json 中的 version

  • 再通過 npm view cli-tpl version 命令查詢當(dāng)前 npm 庫最新版本

  • 兩者比較得出結(jié)論,提醒用戶更新

  1. 解析用戶命令

  • 通過 process.argv[2] 獲取到用戶執(zhí)行的實(shí)際命令,比如 dcli install 可拿到 install?(正式版推薦使用 minimist 解析參數(shù))

  1. 處理命令

  • 比如 install 命令,則通過 require 動態(tài)映射 install.js 文件來處理該邏輯

  • 注:require 支持動態(tài)名稱,如 require('./scripts/' + command) 這樣,如果 command 是 install 則映射執(zhí)行 script/install.js 文件

接下來我們看下 4 個核心命令,主要是:

命令 效果 install 幫用戶安裝/升級一個「模板插件包」 init 幫用戶初始化一個工程,并拷貝模板 build 調(diào)用工程中的「構(gòu)建插件包」,幫用戶webpack構(gòu)建 dev 幫用戶啟動 devServer 進(jìn)行調(diào)試 下面逐一闡述每個命令的實(shí)現(xiàn)過程以及效果:

5.3?install命令:安裝一個「模板插件包」

install 意思就是把這個模板插件包下載到硬盤;此處我做了一個最小功能的 demo 包 gen-tpl?(后文詳細(xì)分解)?來輔助講解

dcli?install?gen-tpl
復(fù)制代碼

「手把手」15分鐘搭一個企業(yè)級腳手架

核心處理流程如下:

  1. 先判斷是否硬盤緩存目錄 ~/.maoda 下是否已經(jīng)有安裝過 gen-tpl 包

  • 如果沒有,則接下來進(jìn)行安裝?(相當(dāng)于在 ~/.maoda 目錄下執(zhí)行 npm install)

  • 如果有,且版本低,則提示升級

  • 如果有,且版本最新,則不作為

  1. 安裝過程即 execSync('npm i gen-tpl@latest -S', { cwd: '~/.maoda' })

我們可以為「模板插件包」的名稱做一個約定,即具備固定的前綴,諸如 gen-xxx

5.4?init命令: 選一個「模板插件包」來初始化一個新工程

這是一個腳手架高頻而核心的功能

dcli?init
復(fù)制代碼

「手把手」15分鐘搭一個企業(yè)級腳手架

此時會分發(fā)去執(zhí)行 script/init.js 文件,我們看看其邏輯

  1. 查詢硬盤緩存目錄 ~/.maoda 下的 package.json 文件,讀取其中 dependacies 字段,拿到已安裝的「模板插件包」

  • 如果一個都沒安裝,則提示用戶要先 install

  1. 讓用戶選擇一套模板

  • 利用 inquery 庫發(fā)起對話,羅列出已裝模板,讓用戶選擇,比如上圖的 gen-pc gen-h6 gen-tpl

  1. 觸發(fā)模板初始化流程

  • 比如用戶選擇了 gen-tpl 這個模板,則用 yeoman-environment 這個庫去執(zhí)行緩存目錄里的這個包 ~/.maoda/gen-tpl/index.js

  • 注:這里相當(dāng)于跨目錄的兩個 js 文件引用執(zhí)行,用到了之前說的 import-from 這個庫

  1. 「模板插件包」被執(zhí)行,則啟動了常規(guī)的模板拷貝過程?(后面展開細(xì)說)

這里直接用包名稱做選項(xiàng),為了演示更直觀,實(shí)際通常用包的 description 做選項(xiàng),更友好一些,比如 gen-pc 包可能描述為 生成PC模板

5.5?build命令:在工程里執(zhí)行構(gòu)建

dcli?build復(fù)制代碼

「手把手」15分鐘搭一個企業(yè)級腳手架

  1. 確定工程目錄

  • 工程目錄即執(zhí)行目錄,通過 process.cwd() 獲取

  1. 讀取該工程所用的構(gòu)建插件

  • 讀取工程中約定的配置文件,本demo中為 maoda.js?(采用約定式的配置,類似 webpack.config.js .babelrc .prettierrc)

  • 讀取 maoda.js 中 builder 配置項(xiàng)?(即指定的構(gòu)建插件包),比如本 demo 中指定為 build-tpl

  • 如果有的話,讀取自定義 webpack 配置?(約定為 webpackCustom 字段,后續(xù)會被合并/覆蓋到默認(rèn) webpack 配置上)

  1. 使用制定的構(gòu)建插件包來進(jìn)行 webpack 打包

  • 判斷工程中是否已經(jīng)安裝 build-tpl

  • 未安裝,則在工程中路徑中執(zhí)行 npm install?(或 yarn add,此處有個小技巧,可根據(jù)用戶工程中 lock 文件的類型,判斷用戶使用的 npm 還是 yarn)

  • 已安裝,則直接執(zhí)行 build-tpl

通常,我們用配置文件指明「構(gòu)建插件包」,也可以直接在命令里指明,比如 dcli build --builder=build-h6;后者往往適用于一套代碼打包出多種結(jié)果,如京東的 Taro cli

平時大家用慣了 npm run build yarn build,只需在我們的模板中的 package.json 添加一行:

{?"script":?{
++?"build":?"dcli?build"
?}
}
復(fù)制代碼

5.6?dev命令:啟動 devServer 進(jìn)行調(diào)試

類似 build 只不過 webpack 配置不同,此處略

6 模板插件包

核心功能:提供模板文件夾 + 文件夾的拷貝。這里同樣提供了一個樣例工程 gen-tpl?(僅 50 行代碼)

處理流程如下:

  1. 詢問用戶,并獲取反饋的答案

  • 比如工程名是什么,描述一下你的工程,是否使用 TypeScript,是否使用 Sass/Less/Stylus 等

  1. 根據(jù)用戶的答案,拷貝對應(yīng)的模板,細(xì)分兩種拷貝

  • 直接拷貝,直接把模板插件包里的文件夾/文件,拷貝到用戶工程目錄

  • 填充模板拷貝,將用戶答案,填充到文檔的對應(yīng)位置,類似 WebpackHTMLPlugin、ejs,如將 name: <%= packageName %> 填充成 name: 我的工程

  1. 在工程中執(zhí)行 npm 依賴的安裝

「手把手」15分鐘搭一個企業(yè)級腳手架

【重點(diǎn)來了】看似流程蠻多,其實(shí)只用一個現(xiàn)成的輪子即可搞定,即 yeoman-generator,它幫我們把這些過程都封裝好了,我們只需繼承基類,并寫幾個預(yù)設(shè)的生命周期函數(shù)即可,無腦到令人發(fā)指?(細(xì)節(jié)處理,可參考模板倉庫)

module.exports?=?class?extends?Generator?{?//?【問詢環(huán)節(jié)】
?prompting()?{?return?this.prompt([
?{?type:?'input',
?name:?'appName',
?message:?'請輸入項(xiàng)目名稱:',
?},
?{?type:?'list',
?choices:?['Javascript',?'TypeScript'],
?name:?'language',
?message:?'請選擇項(xiàng)目語言',?default:?'TypeScript',
?},
?]).then(answers?=>?{?this.answers?=?answers
?})
?}?
?//?【模板拷貝】
?writing()?{?//?從模板路徑拷貝到工程路徑
?this.fs.copy(this.templatePath(),?this.destinationPath())
?}?//?【安裝依賴】
?install()?{?this.installDependencies()
?}
?end()?{?this.log('happy?coding!')
?}
}
復(fù)制代碼

很明顯,「模板插件包」導(dǎo)出的是一個 class,我們需要通過上文提到的「全局命令包」里的 yeoman-environment 來啟動:

//?【節(jié)選自?全局命令包?init?命令,略修改以增加可讀性】
yoemanEnv.register(resolveFrom('./maoda',?'gen-tpl'),?'gen-tpl')
yoemanEnv.run('gen-tpl',?(e,?d)?=>?{
?d?&&?this.console('happy?coding',?'green')
})
復(fù)制代碼

這里同樣用到前文提到的 resolve-from 包,進(jìn)行跨目錄的引用解析

yeoman 是一個比較完善的生態(tài),模板插件包可用 yeoman 提供的全局命令 yo 來創(chuàng)建,但并非必要,此處就不展開說了

7 構(gòu)建插件包

同樣我們提供了一個構(gòu)建插件包的模板 build-tpl?(20行代碼,啟動 webpack),webpack 配置都是空的,大家在開發(fā)過程中可自行定制

構(gòu)建插件包其實(shí)核心就是 webpack 能力,webpack 能力這里就不展開說了,這里只描述一下調(diào)用關(guān)系

以 dcli build 為例,「全局命令包」在收到 build 命令后,啟動「構(gòu)建插件包」

importFrom(process.cwd(),?'build-tpl')
復(fù)制代碼

沒錯,就是這么簡單,import-from 庫能跨文件目錄,指定使用特定目錄的文件;使得全局包可以直接去執(zhí)行工程目錄的包?效果與同工程下 require('build-tpl') 一樣

此處也可以使用 import-cwd 庫

而 build-tpl 這個構(gòu)建插件包,負(fù)責(zé)將內(nèi)置的 webpack.config.js 與用戶工程下自定義的 webpackCustom 進(jìn)行 merge,然后執(zhí)行 webpack 流程

「手把手」15分鐘搭一個企業(yè)級腳手架

當(dāng)然,構(gòu)建工具不一定非要使用 webpack,比如可以選擇 rollup 或者像 Taro 在構(gòu)建小程序代碼時候,自己創(chuàng)建一套工具

8 寫在最后的話

筆者認(rèn)為,只有夠精簡,才能降低入門門檻,才能強(qiáng)化記憶;因此,本文的案例,在成熟的腳手架上進(jìn)行不斷刪減,剔除掉哪些徒增記憶負(fù)擔(dān)的部分,只保留精髓和核心,旨在快速在腦海里建模出一個企業(yè)級腳手架

同時提供了腳手架 3 個組成部分的 倉庫/npm 包,以增加可操作性

如需引用與實(shí)際開發(fā)中,我們需要繼續(xù)豐滿其血肉,包括但不限于:

  • 異常處理 (如一些邊界情況)

  • webpack 配置部分需完善?(本 demo 中 webpack.config 是空的)

  • UI 和提升語可更友好

  • 根據(jù)業(yè)務(wù)需求,擴(kuò)展額外的命令,比如卸載包,發(fā)布cdn等

「手把手」15分鐘搭一個企業(yè)級腳手架

分享名稱:「手把手」15分鐘搭一個企業(yè)級腳手架
標(biāo)題網(wǎng)址:http://www.chinadenli.net/article8/pecpip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號品牌網(wǎng)站建設(shè)網(wǎng)站收錄服務(wù)器托管商城網(wǎng)站定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計