Nuxt + Typescript最佳实践5:使用yarn workspace管理多个项目

很多情况下我们可能有多个nuxtjs项目,多个项目之前有或多或少的关联,每个项目第一次启动项目都要安装一遍依赖,非常占用磁盘空间,那么可以不可以在一个文件夹下管理多个项目呢,这就是monorepo的概念。

很多流行的库都使用了monorepo的方式管理,比如vue, react



monorepo的管理方式可以使用lernayarn workspace, 这里说说yarn workspace管理多个nuxtjs项目,当然也可以管理其他的vue项目。

原理

nodejs项目引入外部依赖包,首先从本级目录查找,查找不到就到上级目录查找,直到系统根目录。

monorepo其实就是把各个项目里面的包,安装到根目录下,就是利用这个原理。但是如果包版本冲突呢?
举个例子:

A 依赖了  C@^2.0.0
B 依赖了  C@^2.9.0

系统会判定这两个没有冲突,因为根据语义化结果只需要安装[email protected]以上的版本就行。

但是如果:

A 依赖了  C@^1.0.0
B 依赖了  C@^2.9.0

那么A只能安装[email protected] 的最高版本,那么B只能安装[email protected] 的最高版本。
这就形成了冲突,yarn workspace就会把低版本的包放到对应的子目录的node_modules里,高版本的放在根目的node_modules录,这样各自都能找到自己需要依赖的包了。

如何配置

如果我们的项目根目录是这样的

+-- common #基础包
+-- project1   #项目1
+-- project2   #项目2
+-- package.json

yarn worskspace 要求根目录的package.json,必须含有, 如何两个字段:

{
  "private": true,
  "workspaces": ["common", "project1", "project2"] // 也可以使用通配符设置为 ["project*"]
}

执行安装依赖(无论在根目录或者子目录执行)

yarn

安装之后我们可以看到都安装到了根目录的node_modules里面了。

那如果我们要执行子目录的命令怎么办?
两个办法:

  • 直接在子目录命令行里敲命令, 比如 yarn build
  • 直接在父目录命令行执行 比如 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里面引入本地包即可,版本号对应即可。
比如project1引入common, 将它的依赖加入dependencies字段即可:

"dependencies": {
  "common": "^1.0.0"
}

project1的项目代码里即可引入了

import * as common from 'common';
console.log(common):

*common项目要符合npm包的规范才可以正常使用。

需要注意的问题

1.node_modules 里的包移动后带来的问题。

很多原本安装在子项目node_modules的包被安装到了父目录了,而有些安装包并没有对monorepo进行适配, 所以编译会报错。

举几个例子:


  • postcss 编译报错
    在linux服务器编译postcss,说配置未找到。
    在根目录创建一份配置即可


  • 某些包编译配置依赖要改变。
    比如webpack-cdn-plugin插件
 plugins:[new WebpackCdnPlugin({
    modules: buildConfig.cdnConfig, // CDN配置
    pathToNodeModules: path.resolve(__dirname, './../')    // 指定查找的node_modules的目录,指向上级目录
})];


  • 多个项目的冲突。

你如你在project1 里面引入了element-ui。 nuxtjs项目的types文件夹扩展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项目,这个俩定义重复了就报错误,当然这并不影响运行结果。

你可能感兴趣的:(Nuxt + Typescript最佳实践5:使用yarn workspace管理多个项目)