[英]Angular 8: A better way to build monorepo app with libraries
I have several apps in my Angular monorepo project.我的 Angular monorepo 项目中有几个应用程序。 Also there are about 5 libraries I've written to use across the apps.
我还编写了大约 5 个库以在应用程序中使用。
What I want to know is how to better build/architect these libraries .我想知道的是如何更好地构建/架构这些库。
The ins are follows: ins如下:
projects
folder)projects
文件夹中的应用程序)lodash
and RxJs
lodash
和RxJs
What I've done so far:到目前为止我所做的:
umdModuleIds
in each library's ng-package.json
.ng-package.json
指定了umdModuleIds
。peerDependencies
on external libraries like lodash
and RxJs
peerDependencies
像外部库lodash
和RxJs
prebuild
with about 5 commands ng build lib-name
combined via "&&"prebuild
约5命令ng build lib-name
通过“&&”组合import { cloneDeep } from 'lodash'
import { cloneDeep } from 'lodash'
Now I see that my main.js
chunk is much bigger than it was before extracting some services/components/functions into external libraries.现在我看到我的
main.js
块比将一些服务/组件/函数提取到外部库之前大得多。 Now main.js
's size on prod build is 2.1 Mb which in my opinion is too big.现在
main.js
在 prod 构建上的大小是 2.1 Mb,在我看来这太大了。
Also, I'm not sure whether it's worth making 3 different builds of each library (UMD, FESM2015, FESM5).另外,我不确定是否值得为每个库(UMD、FESM2015、FESM5)制作 3 个不同的版本。
I import libraries from dist folder as it recommended in docs following next form import { LibService } from 'lib'
.我按照文档中的建议从 dist 文件夹中导入库,遵循下一个表单
import { LibService } from 'lib'
。
Nrwl tools, developed by Angular core contributors, specializes in enterprise architectures, including mono repositories. Nrwl工具由 Angular 核心贡献者开发,专门研究企业架构,包括单一存储库。
The Nrwl nx-examples is a great resource to get started. Nrwl nx-examples是一个很好的入门资源。
I started by using nx
to build a new project.我开始使用
nx
来构建一个新项目。 In the end, my project structure ended up as follows:最后,我的项目结构如下:
platform-directory/
|
---apps/
| |
| ---app1/
| |
| ---app2/
|
---library1/
| |
| ---src/
|
---library2/
| |
| ---src/
|
---angular.json
|
---package.json
|
---README.md
|
---tsconfig.json
The top level tsconfig.json
should contain the bulk of the global configuration for the apps and libraries as well as paths
shortcuts if desired.如果需要,顶级
tsconfig.json
应包含应用程序和库的大部分全局配置以及paths
快捷方式。
Path shortcuts may be configured as follows:路径快捷方式可以配置如下:
{
"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"
],
...
}
In the applications, library code may be imported directly from the library sources, such as:在应用程序中,可以直接从库源中导入库代码,例如:
import { MyLibraryComponent } from '@lib1/package1'
Since you are not publishing the libraries, there is no need to build them.由于您不发布库,因此无需构建它们。 When you run the Angular compiler on your application code, the library code will be automatically included and optimized as needed.
当您在应用程序代码上运行 Angular 编译器时,库代码将根据需要自动包含和优化。
IMPORTANT: Within each library, do not import files using the path shortcuts, since this causes hard-to-debug circular dependencies.重要提示:在每个库中,不要使用路径快捷方式导入文件,因为这会导致难以调试的循环依赖。 For example, within
lib2
it is okay to use:例如,在
lib2
中可以使用:
import { MyLibraryComponent } from '@lib1/package1'
However, if this import were used within lib1
, it would create a circular dependency.但是,如果在
lib1
中使用此导入,则会创建循环依赖项。
As a side note, each app will have a tsconfig.app.json
and tsconfig.spec.json
such as the following:作为旁注,每个应用程序都有一个
tsconfig.app.json
和tsconfig.spec.json
,如下所示:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc/apps/app1"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
Specifically regarding your concern with bundle size: I suspect Lodash is a major culprit there.特别是关于您对包大小的担忧:我怀疑 Lodash 是其中的主要罪魁祸首。 Try using
lodash-es
instead, and importing from only packages you need.尝试使用
lodash-es
,并仅从您需要的包中导入。 Eg例如
import cloneDeep from 'lodash-es/cloneDeep';
That should reduce the amount of lodash
in your bundle substantially, but it still won't be nearly as small as it could be for most use cases.这应该会大大减少包中的
lodash
数量,但它仍然不会像大多数用例那样小。 I made a library specifically for this reason called micro-dash
.我为此专门制作了一个名为
micro-dash
。 For example it includes cloneDeep
, which as the docs say adds 397 bytes
to your bundle (roughly - it depends on multiple factors), whereas the lodash version adds 12,289 bytes
.例如,它包括
cloneDeep
,正如文档所说,它为您的包添加了397 bytes
(大致 - 这取决于多种因素),而 lodash 版本添加了 12,289 12,289 bytes
。
Ultimately, though, to troubleshoot an oversized bundle you should see exactly how much each library is adding to it.不过,最终,要对过大的包进行故障排除,您应该确切地看到每个库向其中添加了多少。 That is the realm of
source-map-explorer
.这就是
source-map-explorer
的领域。 Absolutely run that on your final prod bundles, and address the worst offenders first!绝对在您的最终产品包上运行它,并首先解决最严重的违规者!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.