很多情況下我們可能有多個nuxtjs項目愤诱,多個項目之前有或多或少的關(guān)聯(lián)吁峻,每個項目第一次啟動項目都要安裝一遍依賴唐断,非常占用磁盤空間柑船,那么可以不可以在一個文件夾下管理多個項目呢佃延,這就是
monorepo
的概念现诀。
很多流行的庫都使用了monorepo
的方式管理,比如vue
, react
履肃。
monorepo
的管理方式可以使用lerna
和 yarn workspace
, 這里說說yarn workspace
管理多個nuxtjs項目,當(dāng)然也可以管理其他的vue項目仔沿。
原理
nodejs項目引入外部依賴包,首先從本級目錄查找尺棋,查找不到就到上級目錄查找封锉,直到系統(tǒng)根目錄。
monorepo
其實就是把各個項目里面的包膘螟,安裝到根目錄下成福,就是利用這個原理。但是如果包版本沖突呢荆残?
舉個例子:
A 依賴了 C@^2.0.0
B 依賴了 C@^2.9.0
系統(tǒng)會判定這兩個沒有沖突奴艾,因為根據(jù)語義化結(jié)果只需要安裝C@2.9.0以上的版本就行。
但是如果:
A 依賴了 C@^1.0.0
B 依賴了 C@^2.9.0
那么A只能安裝C@1.x.x 的最高版本内斯,那么B只能安裝C@2.9.x 的最高版本蕴潦。
這就形成了沖突,yarn workspace
就會把低版本的包放到對應(yīng)的子目錄的node_modules
里俘闯,高版本的放在根目的node_modules
錄潭苞,這樣各自都能找到自己需要依賴的包了。
如何配置
如果我們的項目根目錄是這樣的
+-- common #基礎(chǔ)包
+-- project1 #項目1
+-- project2 #項目2
+-- package.json
yarn worskspace
要求根目錄的package.json
真朗,必須含有, 如何兩個字段:
{
"private": true,
"workspaces": ["common", "project1", "project2"] // 也可以使用通配符設(shè)置為 ["project*"]
}
執(zhí)行安裝依賴(無論在根目錄或者子目錄執(zhí)行)
yarn
安裝之后我們可以看到都安裝到了根目錄的node_modules
里面了此疹。
那如果我們要執(zhí)行子目錄的命令怎么辦?
兩個辦法:
- 直接在子目錄命令行里敲命令, 比如
yarn build
- 直接在父目錄命令行執(zhí)行 比如
yarn workspace project1 build
一般來講我們可以把子目錄的各種命令放到根目錄
#根目錄下的 `package.json`, 加入腳本
"scripts": {
"project1-build": "yarn workspace project1 build",
"project1-dev": "yarn workspace project1 dev",
"project2-build": "yarn workspace project2 build",
"project2-dev": "yarn workspace project2 dev"
}
引入本地包
yarn workspace
的包是可以相互引入的遮婶,引入方式也很簡單秀菱,在需要引入的子項目的package.json
里面引入本地包即可,版本號對應(yīng)即可蹭睡。
比如project1
引入common
, 將它的依賴加入dependencies
字段即可:
"dependencies": {
"common": "^1.0.0"
}
在project1
的項目代碼里即可引入了
import * as common from 'common';
console.log(common):
*common項目要符合npm包的規(guī)范才可以正常使用衍菱。
需要注意的問題
1.node_modules 里的包移動后帶來的問題。
很多原本安裝在子項目node_modules
的包被安裝到了父目錄了肩豁,而有些安裝包并沒有對monorepo
進(jìn)行適配, 所以編譯會報錯脊串。
舉幾個例子:
-
postcss
編譯報錯
在linux服務(wù)器編譯postcss辫呻,說配置未找到。
在根目錄創(chuàng)建一份配置即可
- 某些包編譯配置依賴要改變琼锋。
比如webpack-cdn-plugin
插件
plugins:[new WebpackCdnPlugin({
modules: buildConfig.cdnConfig, // CDN配置
pathToNodeModules: path.resolve(__dirname, './../') // 指定查找的node_modules的目錄放闺,指向上級目錄
})];
- 多個項目的沖突。
你如你在project1
里面引入了element-ui
缕坎。 nuxtjs項目的types
文件夾擴(kuò)展vue
定義
// node_modules\@nuxt\types\app 第119行
export interface NuxtApp extends Vue {
/***給vue拓展了 $loading***/
$loading: NuxtLoading
}
而element-ui
也定義了
// node_modules\element-ui\types\loading.d.ts 59行
declare module 'vue/types/vue' {
interface Vue {
$loading (options: LoadingServiceOptions): ElLoadingComponent
}
}
如果是TypeScript項目怖侦,這個倆定義重復(fù)了就報錯誤,當(dāng)然這并不影響運行結(jié)果谜叹。