有没有更好的方法来构建带有库的 Angular monorepo 应用程序?



我的 Angular monorepo 项目中有几个应用程序。此外,我编写了大约 5 个库来跨应用程序使用。

我想知道的是如何更好地构建/构建这些库

具体如下:

  1. 库仅供内部使用(意味着除了文件夹中的应用外,不得在其他应用中发布或使用projects)
  2. 库具有不同的依赖项,如lodashRxJs
  3. 一个库可以在自身内部导入另一个库

到目前为止我做了什么:

  1. 在每个库的ng-package.json中指定umdModuleIds
  2. 外部
  3. 库(如lodashRxJs)上的指定peerDependencies
  4. 设置我的应用程序构建,其中包含大约 5 个命令prebuildng build lib-name通过"&&"组合
  5. 我以下一种方式导入洛达什import { cloneDeep } from 'lodash'

现在我看到我的main.js块比将一些服务/组件/函数提取到外部库之前要大得多。现在main.js在生产构建上的大小是 2.1 Mb,在我看来太大了。

另外,我不确定是否值得为每个库(UMD,FESM2015,FESM5)制作3个不同的版本。

我按照在下一个表单import { LibService } from 'lib'的文档中的建议从dist文件夹导入库。

Nrwl 工具由 Angular 核心贡献者开发,专门研究企业架构,包括单声道存储库。

Nrwl nx-example是一个很好的入门资源。

我首先使用nx来构建一个新项目。最后,我的项目结构最终如下:

platform-directory/
|
---apps/
|  |
|  ---app1/
|  |
|  ---app2/
|
---library1/
|  |
|  ---src/
|
---library2/
|  |
|  ---src/
|
---angular.json
|
---package.json
|
---README.md
|
---tsconfig.json

tsconfig.json

顶级tsconfig.json应包含应用程序和库的大部分全局配置,以及paths快捷方式(如果需要)。

路径快捷方式可以按如下方式配置:

{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"baseUrl": "./",
"declaration": false,
"downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"module": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"target": "es6",
"lib": [
"es2018",
"dom"
],
"paths": {
"@app1*": [
"./apps/app1/src/app*"
],
"@lib1/package1": [
"./lib1/src/package1/public_api.ts"
],
"@lib1/package2": [
"./lib1/src/package2/public_api.ts"
],
...
}

库导入

在应用程序中,可以直接从库源导入库代码,例如:

import { MyLibraryComponent } from '@lib1/package1'

由于您不发布库,因此无需构建它们。当您在应用程序代码上运行 Angular 编译器时,库代码将自动包含并根据需要进行优化。

重要说明:在每个库中,不要使用路径快捷方式导入文件,因为这会导致难以调试的循环依赖项。例如,在lib2内可以使用:

import { MyLibraryComponent } from '@lib1/package1'

但是,如果这个导入在lib1中使用,它将创建一个循环依赖。

作为旁注,每个应用程序都有一个tsconfig.app.jsontsconfig.spec.json,如下所示:

{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc/apps/app1"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}

特别是关于您对捆绑包大小的担忧:我怀疑 Lodash 是那里的罪魁祸首。请尝试改用lodash-es,并仅从所需的包导入。例如

import cloneDeep from 'lodash-es/cloneDeep';

这应该会大大减少捆绑包中的lodash量,但它仍然不会像大多数用例那样小。为此,我专门为此制作了一个库,称为micro-dash。例如,它包括cloneDeep,正如文档所说,它会将397 bytes添加到您的捆绑包中(大致 - 它取决于多种因素),而 lodash 版本添加了12,289 bytes.

但是,最终,要对超大捆绑包进行故障排除,您应该确切地看到每个库向其中添加了多少内容。这就是source-map-explorer的境界。绝对在你的最终产品捆绑包上运行它,并首先解决最严重的违规者!

最新更新