javascript - 如何像 Visual Studio 项目一样开发/构建 Javascript monorepo 项目?

标签 javascript node.js npm yarnpkg package.json

在典型的 .NET Core 项目(使用 Visual Studio 2019)中,我们有这样的结构:

Example/
|-- Example.Common/
|   |-- FileExample1.cs
|   |-- FileExample2.cs
|   `-- Example.Common.csproj
|-- Example.WebAPI/
|   |-- Controllers/
|   |-- Program.cs
|   |-- Startup.cs
|   `-- Example.WebAPI.csproj
|-- Example.CLI/
|   |-- Program.cs
|   `-- Example.CLI.csproj
|-- Example.sln

在这个项目中,Example.CLIExample.Web.API 都引用了Example.Common 项目。 Example.sln 文件引用了所有三个 *.csproj 并且每个 csproj 都有自己的依赖项,可以是以下 4 种之一:

<!-- It is a NuGet package (similar to Node.js npm packages) that always resolves from the public nuget.org registry -->
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.3" />

<!-- It is local, never resolves from registry -->
<ProjectReference Include="../Example.Common/Example.Common.csproj" />

<!-- Resolves from a machine-wide installed DLL -->
<Reference Include="Global.Dependency.Example" />

<!-- Resolves from a local DLL -->
<Reference Include="Local.Dependency.Example">
  <HintPath>path/to/Local.Dependency.Example.dll</HintPath>
</Reference>

在开发期间在本地运行时,如果我在 Common 源代码中更改某些内容并运行 CLI 项目,它会自动重建 Common 并将 DLL 复制到目标位置,以便 CLI 可以运行具有这些最新更改的版本。即使我在解决方案中有更多项目,它也只会重建 CLI 所依赖的项目,以及自上次运行以来是否有任何更改。

部署时,它会重建所有内容并在本地解决本地依赖项。我对 Node.js 和 NPM 包的问题是:

  • 当本地开发变得容易时,部署和生成 docker 镜像就变得困难。
  • 当部署和生成 docker 镜像变得容易时,本地开发就变得困难了。

我想在 Node.js 项目中做同样的事情,分享 common 源代码以用于 web-apicli,并且我想在一个 npm 包中分解项目的每个组件,这样每个包都可以有自己的依赖项。

在一个 Node.js 项目中,我有一个类似的结构:

example/
|-- common/
|   |-- file-example1.js
|   |-- file-example2.js
|   `-- package.json
|-- web-api/
|   |-- controllers/
|   |-- index.js
|   |-- routes.js
|   `-- package.json
|-- cli/
|   |-- index.js
|   `-- package.json
|-- package.json

问题在于 Node.js 和 npm/yarn/pnpm 如何解决依赖关系。我尝试使用 Yarn Workspaces、Lerna、Lerna + Yarn Workspaces,但似乎所有这些工具都是为发布到注册表的包而制作的,而不是为了帮助模块化单个项目。

我想要的是一个简单的方法来做到这一点:

  • 本地开发时,修改common源码,使用更新版本的common运行web-api或cli,无需每次都调用yarn install或创建npm手动链接
  • 部署时,使用本地源码/构建解决依赖,并按照正确的顺序构建

我试过:

  • Yarn link: 协议(protocol),适用于开发,但当我运行 yarn install --production 时,它会尝试使用注册表进行解析。不会工作,因为我的任何包都不会发布到任何注册表。
  • NPM file: 协议(protocol),适合部署,但对于开发,当我在公共(public)包中进行更改时,我需要删除 node_modules 中的公共(public)文件夹,并且再次运行 yarn install。即使使用 file: 协议(protocol),我仍然需要一种以正确顺序构建的方法,否则,npm/yarn 只会将依赖项的源代码复制到目标 node_modules 文件夹。

最佳答案

简答:

lerna bootstrap
lerna run dev

bootstrap 会将依赖项安装到相应的包中。 示例:common 应安装在 web-api 中。 Lerna 将在 web-api 中安装 common 作为 node_module

package.json 中添加 private: true 也将确保 lerna publish 不会发布这些项目。


(长答案:)

给定文件夹目录

example/
|-- common/
|   |-- file-example1.js
|   |-- file-example2.js
|   `-- package.json
|-- web-api/
|   |-- controllers/
|   |-- index.js
|   |-- routes.js
|   `-- package.json
|-- package.json

<强>1。 yarn 工作区。

示例/package.json

{
  "private": true,
  "workspaces": ["common", "web-api"]
}

在各自的子文件夹中初始化 yarn 。

终端

~/example         $ cd ./common
~/example/common  $ yarn init -y
~/example/common  $ cd ../web-api
~/example/web-api $ yarn init -y

在示例/common/package.json 中

{
  "name": "common",
  "version": 1.0.0
  ...
}

例如/web-api/package.json

{
  "name" "web-api",
  "dependencies": {
    "common": "1.0.0"
  }
}

终端 (在 web-api 目录中)

~/example/web-api $ yarn install

在根目录中应该有一个 node_modules 应该包括:

web-api/
common/

yarn 将从在根级别创建的 node_modules 文件夹中创建 commonwebapi 之间的符号链接(symbolic link)。

但是,yarnpkg约定是使用

{
  "private": true,
  "workspaces": ["packages/"]
}

引用:Ben awad tutorial on yarn workspaces


<强>2。勒纳

Lerna 在引擎盖下使用 yarn 工作区 ref但是你需要一个 lerna.json 配置(它可以指定你需要的包管理器 npm, yarn...)

lerna.json

{
  "packages": [
    "packages/*"
  ],
  "version": "0.0.0"
}

lerna 中有额外的命令,例如:
- lerna diff common 它将为您提供自上次提交以来的 git diff,或者。 - lerna run test 将在每个包中运行 test 脚本。 (使用 --scope={common} 只针对 common test 脚本)。

create-react-app它们还包括一个“变更日志”字段,我认为人们会如何自动为他们的提交消息添加前缀。

引用:Ben awad tutorial on lerna

关于javascript - 如何像 Visual Studio 项目一样开发/构建 Javascript monorepo 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61189279/

相关文章:

React-Redux 应用程序未触发 Javascript Video loadmetadata 事件

node.js - Node js 从 utf-8 转换

angular - 类型错误 : Cannot read properties of undefined (reading 'match' )

javascript - 错误 : Cannot find module '@discordjs/opus'

javascript - 传递给生成器时对象和数组解构复杂化

javascript - 语法错误: Unexpected token <

javascript - 使用 Bootstrap3 更改滚动 Jquery 上导航栏的高度

node.js:具有正确 header 的浏览器图像缓存

api - 使用nodejs从API调用缓存数据的正确方法

node.js - 运行 `yarn`时如何更改主目录?