此处的内网是指没办法连接互联网进行依赖下载的环境,本文以
windows
平台为例
背景说明
绝大部分政府机关、国有企业都是在内网开发,无法从互联网同步依赖,就需要另辟蹊径解决项目依赖的问题。
传统的单包项目还好,从互联网机器将依赖下载,打包拷贝到内网就能直接跑起来。
monorepo 项目相对而言复杂一些,下面我将介绍工作中用到的内网 monorepo 方案。
何为 monorepo
Monorepo
是一种项目代码管理方式,指单个仓库中管理多个项目,有助于简化代码共享、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性。Monorepo 提倡了开放、透明、共享的组织文化,这种方法已经被很多大型公司广泛使用,如 Google、Facebook 和 Microsoft 等。
上面的文案摘自带你了解更全面的 Monorepo - 优劣、踩坑、选型有详细介绍 😀。
基于 YARN
yarn workspaces 是 yarn 提供的 monorepo 的依赖管理机制,从 1.0 开始默认支持,用于在代码仓库的根目录下管理多个package的依赖,详见:yarn workspaces
基本配置
{
"private":"true", //必填,否则不能开启工作区功能
"workspaces": [
"packages/*", //告知 yarn 在 packages 下的文件夹均为包
],
"scripts": {
"webpack": "yarn workspace ui-webpack serve",
"vite": "yarn workspace ui-vite serve"
}
}
在 packages
下新建包,并配置 package.json (可以用 yarn init -y
快速初始化, name 属性必填)。整体目录如下图所示:
此时可以执行 yarn workspaces info
查看工作区结构
# yarn workspaces info
yarn workspaces v1.22.19
{
"@app-meta/basic-vue3": {
"location": "packages/basic-vue3",
},
"ui-vite": {
"location": "packages/ui-vite",
"workspaceDependencies": [
"@app-meta/basic-vue3"
]
},
"ui-webpack": {
"location": "packages/ui-webpack",
"workspaceDependencies": [
"@app-meta/basic-vue3"
]
}
}
安装依赖
直接执行yarn
即可完成依赖(统一存放在 node_modules
下)。
此时观察子包的目录,发现都有创建 node_modules\.bin
目录,里面是用到的命令行(如 webpack
、vite
),可删除(不影响命令执行)。
启动项目
- yarn workspace ui-webpack serve
迁移到内网
将整个工程目录node_modules
拷贝到新机器即可,简单快捷。
创建目录联接
此时 node_modules 下的依赖没有联接需要手动创建
- 删除 node_modules/@app-meta 目录
- 执行
mkdir ./node_modules/@app-meta && mklink /J .\node_modules\@app-meta\basic-vue3 .\packages\basic-vue3
- 其他的联接类似
利用 yarn 也可以创建联接:
- yarn workspace @app-meta/basic-vue3 link
- yarn link “@app-meta/basic-vue3”
基于 PNPM
关于配置
# .npmrc
# 我尝试了各种配置,结果发现如下配置最能打
shamefully-hoist=true
新建包
- CTRL+C、CTRL+V 新建一个包,并修改
package.json
的包名 - 此时发现 node_modules 内的依赖都是空的,若此时执行
pnpm i --offline
会报错
ERR_PNPM_NO_OFFLINE_META Failed to resolve xxxxx
- 我们更新下 pnpm-lock.yaml 文件的引用即可
迁移到内网
由于 pnpm 使用的是软链接,直接拷贝工程目录在新机器不能正常跑起来 🤣(如有更好的方案烦请告之哈)
- 将
store-dir
目录(可通过pnpm config get store-dir
命令查看)拷贝到内网机器 - 在新机器上设置
store-dir
- 在工程目录下执行
pnpm i --offline
- OK
这里不得提一下,此方案如果遇到多人协作开发,则需要在各个机器上重复操作,碰到依赖版本更新会很难受😢。
问题汇总
- vite 启动正常,运行时报错
场景
将联网机器中的项目(带依赖)拷贝到内网,webpack
能正常使用,vite
启动正常运行时去提示以下错误
Uncaught SyntaxError: The requested module '/@fs/.../node_modules/highlight.js/lib/core.js?v=bdf51948' does not provide an export named 'default' (at core.js?v=bdf51948:2:8)
此时需要重新执行pnpm i --offline
- pnpm-lock.yaml 文件
此文件被删除后,执行pnpm i --offline
会报下面的错
ERR_PNPM_NO_OFFLINE_META Failed to resolve vue-loader@>=15.9.7 <16.0.0-0 in package mirror...
基于 Rush.js(微软出品)
Rush makes life easier for JavaScript developers who build and publish many NPM packages at once. If you’re looking to consolidate all your projects into a single repo, you came to the right place! Rush is a fast, professional solution for managing this scenario.
我还没试验过(在内网安装 rush
都不容易哈哈),有兴趣的同学可以尝试下,这里有参考文章:基于Rush.js的Monorepo实战。
总结
这里局限地介绍了我用过的 monorepo 内网管理办法,我个人推荐yarn
方案,简单便捷且对更新依赖友好,希望对大家有所帮助。