【问题标题】:How to develop/build Javascript monorepo project like Visual Studio projects?如何开发/构建像 Visual Studio 项目这样的 Javascript monorepo 项目?
【发布时间】:2020-04-13 13:46:46
【问题描述】:

在一个典型的 .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 项目中做同样的事情,分享web-apicli 中使用的common 源代码,我想在一个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 link
  • 部署时,使用本地源码/build解决依赖,并按照正确的顺序构建

我试过了:

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

【问题讨论】:

    标签: javascript node.js npm yarnpkg package.json


    【解决方案1】:

    简答:

    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.纱线工作区

    示例/package.json

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

    在各个子文件夹中初始化纱线。

    终端

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

    在 example/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 之间创建符号链接。

    但是,yarnpkg 约定是使用

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

    参考:Ben awad tutorial on yarn workspaces


    2。勒纳

    Lerna 在 ref 底层使用 yarn 工作区,但您需要 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 中,它们还包含一个“changelog”字段,我假设人们将如何自动为其提交消息添加前缀。

    参考:Ben awad tutorial on lerna

    【讨论】:

      猜你喜欢
      • 2021-11-02
      • 2021-08-08
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2011-04-08
      相关资源
      最近更新 更多