




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第Vue3中使用pnpm搭建monorepo開發(fā)環(huán)境目錄前言Pnpm和Monorepo搭建開發(fā)環(huán)境創(chuàng)建項(xiàng)目配置monorepo安裝依賴初始化Typescript準(zhǔn)備兩個(gè)模塊sharedreactivity編寫構(gòu)建腳本完成第一次調(diào)試小結(jié)
前言
Vue3源碼閱讀系列,計(jì)劃從環(huán)境搭建開始,將Vue3的響應(yīng)式模塊,運(yùn)行時(shí)模塊和編譯器模塊,以及狀態(tài)庫Pinia、路由庫Vue-Router的核心原理做一個(gè)梳理。這大概是一個(gè)漫長的過程。祝自己不要爛尾,祝大家有所收獲。
Pnpm和Monorepo
Pnpm是新一代的nodejs包管理工具。第一個(gè)P意為Performance,代表著更佳的性能。
它的主要優(yōu)點(diǎn)有兩個(gè),一是采用了hard-link機(jī)制,避免了包的重復(fù)安裝,節(jié)省了空間,同時(shí)能提高項(xiàng)目依賴的安裝速度。二是對monorepo的支持非常友好,只需要一條配置就能實(shí)現(xiàn)。
Monorepo是一種新的倉庫管理方式。過去的項(xiàng)目,大多采用一個(gè)倉庫維護(hù)一個(gè)項(xiàng)目的方案。對于一個(gè)龐大復(fù)雜的項(xiàng)目,哪怕只進(jìn)行一處小小的修改,影響的也是整體。而采用monorepo的形式,我們可以在一個(gè)倉庫中管理多個(gè)包。每個(gè)包都可以單獨(dú)發(fā)布和使用,就好像是一個(gè)倉庫中又有若干個(gè)小倉庫。
Vue3源碼采用monorepo方式進(jìn)行管理,將眾多模塊拆分到packages目錄中。
這帶來的最直觀的好處,就是方便管理和維護(hù)。而且,它不像Vue2那樣將源碼整體打包對外暴露。Vue3的這種組織形式,方便的實(shí)現(xiàn)了Tree-shaking,需要哪個(gè)功能就引入對應(yīng)的模塊,能大大減少打包后項(xiàng)目的體積。
搭建開發(fā)環(huán)境
創(chuàng)建項(xiàng)目
首先全局安裝pnpm:
npminstall-gpnpm
新建一個(gè)目錄并進(jìn)行初始化:
mkdirvue3-learn
cdvue3-learn
pnpminit
mkdirpackages
配置monorepo
在項(xiàng)目根目錄下新建pnpm-workspace.yaml文件:
packages:
-'packages/*'
意思是,將packages目錄下所有的目錄都作為單獨(dú)的包進(jìn)行管理。
通過這樣一個(gè)簡單的配置,Monorepo開發(fā)環(huán)境搭建好了。
如果大家之前接觸過lerna+yarnworkspace的方案,就會(huì)深有體會(huì),使用pnpm的確方便。Vue3,ElementPlus以前采用的方案就是前者,現(xiàn)在都已經(jīng)改用后者了。
安裝依賴
如果你使用過Vite,就一定體驗(yàn)過它的快。因?yàn)閂ite內(nèi)置了esbuild作為開發(fā)階段的構(gòu)建工具。esbuild的特點(diǎn)就是快。
Vue3采用了和vite一致的選擇,開發(fā)階段使用esbuild作為構(gòu)建工具,在生產(chǎn)階段采用rollup進(jìn)行打包。
我們先安裝一些依賴:
#源碼采用typescript編寫
pnpmadd-D-wtypescript
#構(gòu)建工具,命令行參數(shù)解析工具
pnpmadd-D-wesbuildrolluprollup-plugin-typescript2@rollup/plugin-json@rollup/plugin-node-resolve@rollup/plugin-commonjsminimistexeca
說明:
-D:作為開發(fā)依賴安裝
-w:monorepo環(huán)境默認(rèn)會(huì)認(rèn)為應(yīng)該將依賴安裝到具體的package中。使用-w參數(shù),告訴pnpm將依賴安裝到workspace-root,也就是項(xiàng)目的根目錄。
依賴說明:
依賴描述typescript項(xiàng)目使用typescript進(jìn)行開發(fā)esbuild開發(fā)階段的構(gòu)建工具rollup生產(chǎn)階段的構(gòu)建工具rollup-plugin-typescript2rollup編譯ts的插件@rollup/plugin-jsonrollup默認(rèn)采用esm方式解析模塊,該插件將json解析為esm供rollup處理@rollup/plugin-node-resolverollup默認(rèn)采用esm方式解析模塊,該插件可以解析安裝在node_modules下的第三方模塊@rollup/plugin-commonjs將commonjs模塊轉(zhuǎn)化為esm模塊minimist解析命令行參數(shù)execa生產(chǎn)階段開啟子進(jìn)程
初始化Typescript
pnpmtsc--init
pnpm的使用基本和npm一致。這里的用法就相當(dāng)于npm中的npx:
npxtsc--init
意思是,去node_modules下的.bin目錄中找到tsc命令,并執(zhí)行它。
執(zhí)行完該命令,會(huì)在項(xiàng)目根目錄生成一個(gè)tsconfig.json文件,進(jìn)行一些配置:
{
"compilerOptions":{
"outDir":"dist",//輸出的目錄
"sourceMap":true,//開啟sourcemap
"target":"es2016",//轉(zhuǎn)譯的目標(biāo)語法
"module":"esnext",//模塊格式
"moduleResolution":"node",//模塊解析方式
"strict":false,//關(guān)閉嚴(yán)格模式,就能使用any了
"resolveJsonModule":true,//解析json模塊
"esModuleInterop":true,//允許通過es6語法引入commonjs模塊
"jsx":"preserve",//jsx不轉(zhuǎn)義
"lib":["esnext","dom"],//支持的類庫esnext及dom
"baseUrl":".",//當(dāng)前目錄,即項(xiàng)目根目錄作為基礎(chǔ)目錄
"paths":{//路徑別名配置
"@my-vue/*":["packages/*/src"]//當(dāng)引入@my-vue/時(shí),去packages/*/src中找
準(zhǔn)備兩個(gè)模塊
我們先在packages目錄下新建兩個(gè)模塊,分別是reactivity響應(yīng)式模塊和shared工具庫模塊。然后編寫構(gòu)建腳本進(jìn)行第一次的開發(fā)調(diào)試。
shared
在packages下新建shared目錄,并初始化:
pnpminit
然后修改package.json:
{
"name":"@my-vue/shared",
"version":"1.0.0",
"description":"@my-vue/shared",
"main":"dist/shared.cjs.js",
"module":"dist/shared.esm-bundler.js"
注意name字段的值,我們使用了一個(gè)@scope作用域,它相當(dāng)于npm包的命名空間,可以使項(xiàng)目結(jié)構(gòu)更加清晰,也能減少包的重名。
編寫該模塊的入口文件:
//src/index.ts
*判斷對象
exportconstisObject=(value)={
returntypeofvalue==='object'value!==null
*判斷函數(shù)
exportconstisFunction=(value)={
returntypeofvalue==='function'
*判斷字符串
exportconstisString=(value)={
returntypeofvalue==='string'
*判斷數(shù)字
exportconstisNumber=(value)={
returntypeofvalue==='number'
*判斷數(shù)組
exportconstisArray=Array.isArray
reactivity
在packages下新建reactivity目錄,并初始化:
pnpminit
然后修改package.json:
{
"name":"@my-vue/reactivity",
"version":"1.0.0",
"description":"@my-vue/reactivity",
"main":"dist/reactivity.cjs.js",
"module":"dist/reactivity.esm-bundler.js",
"buildOptions":{
"name":"VueReactivity"
在瀏覽器中以IIFE格式使用響應(yīng)式模塊時(shí),需要給模塊指定一個(gè)全局變量名字,通過buildO進(jìn)行指定,將來打包時(shí)會(huì)作為配置使用。
main指定的文件支持commonjs規(guī)范進(jìn)行導(dǎo)入,也就是說在nodejs環(huán)境中,通過require方法導(dǎo)入該模塊時(shí),會(huì)導(dǎo)入main指定的文件。
同理,module指定的是使用ESModule規(guī)范導(dǎo)入模塊時(shí)的入口文件。
編寫該模塊的入口文件:
//src/index.ts
import{isObject}from'@my-vue/shared'
constobj={name:'Vue3'}
console.log(isObject(obj))
在reactivity包中用到了另一個(gè)包shared,需要安裝才能使用:
pnpmadd@my-vue/shared@workspace--filter@my-vue/reactivity
意思是,將本地workspace內(nèi)的@my-vue/shared包,安裝到@my-vue/reactivity包中去。
此時(shí),查看reactivity包的依賴信息:
"dependencies":{
"@my-vue/shared":"workspace:^1.0.0"
編寫構(gòu)建腳本
在根目錄下新建scripts目錄,存放項(xiàng)目構(gòu)建的腳本。
新建dev.js,作為開發(fā)階段的構(gòu)建腳本。
//scripts/dev.js
//使用minimist解析命令行參數(shù)
constargs=require('minimist')(process.argv.slice(2))
constpath=require('path')
//使用esbuild作為構(gòu)建工具
const{build}=require('esbuild')
//需要打包的模塊。默認(rèn)打包reactivity模塊
consttarget=args._[0]||'reactivity'
//打包的格式。默認(rèn)為global,即打包成IIFE格式,在瀏覽器中使用
constformat=args.f||'global'
//打包的入口文件。每個(gè)模塊的src/index.ts作為該模塊的入口文件
constentry=path.resolve(__dirname,`../packages/${target}/src/index.ts`)
//打包文件的輸出格式
constoutputFormat=format.startsWith('global')'iife':format==='cjs''cjs':'esm'
//文件輸出路徑。輸出到模塊目錄下的dist目錄下,并以各自的模塊規(guī)范為后綴名作為區(qū)分
constoutfile=path.resolve(__dirname,`../packages/${target}/dist/${target}.${format}.js`)
//讀取模塊的package.json,它包含了一些打包時(shí)需要用到的配置信息
constpkg=require(path.resolve(__dirname,`../packages/${target}/package.json`))
//buildO是模塊打包為IIFE格式時(shí)的全局變量名字
constpgkGlobalName=pkg.buildO
console.log('模塊信息:\n',entry,'\n',format,'\n',outputFormat,'\n',outfile)
//使用esbuild打包
build({
//打包入口文件,是一個(gè)數(shù)組或者對象
entryPoints:[entry],
//輸入文件路徑
outfile,
//將依賴的文件遞歸的打包到一個(gè)文件中,默認(rèn)不會(huì)進(jìn)行打包
bundle:true,
//開啟sourceMap
sourcemap:true,
//打包文件的輸出格式,值有三種:iife、cjs和esm
format:outputFormat,
//如果輸出格式為IIFE,需要為其指定一個(gè)全局變量名字
globalName:pgkGlobalName,
//默認(rèn)情況下,esbuild構(gòu)建會(huì)生成用于瀏覽器的代碼。如果打包的文件是在node環(huán)境運(yùn)行,需要將平臺(tái)設(shè)置為node
platform:format==='cjs''node':'browser',
//監(jiān)聽文件變化,進(jìn)行重新構(gòu)建
watch:{
onRebuild(error,result){
if(error){
console.error('build失敗:',error)
}else{
console.log('build成功:',result)
}).then(()={
console.log('watching...')
使用該腳本,會(huì)使用esbuild對packages下的包進(jìn)行構(gòu)建,打包的結(jié)果放到各個(gè)包的dist目錄下。
在開發(fā)階段,我們默認(rèn)打包成IIFE格式,方便在瀏覽器中使用html文件進(jìn)行測試。在生產(chǎn)階段,會(huì)分別打包成CommonJS,ESModule和IIFE的格式。
完成第一次調(diào)試
給項(xiàng)目增加一條scripts命令:
//package.json
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《經(jīng)濟(jì)學(xué)原理與應(yīng)用》課件
- 消防維保人員工作總結(jié)模版
- 十二指腸潰瘍的臨床護(hù)理
- 某年春開學(xué)典禮教師代表發(fā)言稿模版
- 《帕金森病》課件
- 《進(jìn)階面試技巧》課件
- 管理與員工的關(guān)系構(gòu)建策略
- 危重新生兒救治復(fù)習(xí)測試卷
- 《血液制品安全管理》課件
- 《母愛如海》課件
- 教職工工作調(diào)動(dòng)申請表
- 學(xué)校體育學(xué)(第三版)ppt全套教學(xué)課件
- Alltech 2000型蒸發(fā)光散射檢測器解決HPLC檢測難題
- 休學(xué)家長安全承諾書
- JJF 1343-2022 標(biāo)準(zhǔn)物質(zhì)的定值及均勻性、穩(wěn)定性評(píng)估
- 水文學(xué)習(xí)題和答案解析
- 高效課堂新授課評(píng)價(jià)量化表
- 信和SDS2MS使用說明書
- 維修手冊震旦218現(xiàn)場
- 畫法幾何與陰影透視復(fù)習(xí)題(DOC)
- 螺旋密封的設(shè)計(jì)及在流體機(jī)械中的應(yīng)用
評(píng)論
0/150
提交評(píng)論