[英]Angular library module is loaded without being imported
I'm trying to use a local library (created by the Angular CLI) for sharing components between projects. 我正在尝试使用本地库(由Angular CLI创建)在项目之间共享组件。 I've structured the library so that it holds multiple modules, each having their own components, services and shared logic.
我已经构建了库,以便它拥有多个模块,每个模块都有自己的组件,服务和共享逻辑。
I have a wrapping module in the consuming projects for each module inside the library. 我在库中的每个模块的消费项目中都有一个包装模块。 These local modules are being lazy-loaded which AFAIK is the only way to enable lazy-loading for the library modules.
这些本地模块是延迟加载的,AFAIK是为库模块启用延迟加载的唯一方法。 I can lazy-load these local modules without problems, everything works fine, the library components load and render correctly, no errors whatsoever.
我可以懒得加载这些本地模块没有问题,一切正常,库组件加载和正确渲染,没有任何错误。
The problem is that once a Module from the library is being loaded, it does not only load that specific module, but also the other modules from the library, even though I'm not importing them in my consuming project. 问题是,一旦加载了库中的模块,它不仅会加载该特定模块,还会加载库中的其他模块,即使我没有在我的消费项目中导入它们。
How can I set this up so that only this specific Module is loaded? 如何设置它以便仅加载此特定模块? It seems like no tree shaking is being performed.
似乎没有树正在摇晃。
This is what the folder structure looks like: 这就是文件夹结构的样子:
├── projects
│ ├── project1
│ ├── project2
│ └── lib
│ ├── src
│ │ ├── lib
│ │ │ ├── widgets (module1)
│ │ │ ├── blobs (module2)
│ │ │ └── lib.module.ts
│ │ └── public-api.ts
Each of the modules inside this library has their own public-api.ts
file, containing the exports for this module. 此库中的每个模块都有自己的
public-api.ts
文件,其中包含此模块的导出。 For my WidgetsModule
this would be: 对于我的
WidgetsModule
这将是:
export { WidgetsModule } from './widgets.module';
export { Importance } from './enums/importance.enum';
export { BlockItem } from './interfaces/block-item.interface';
export { WidgetConfig } from './interfaces/widget-config.interface';
export { Link } from './interfaces/link.interface';
The main public-api.ts
file of the library combines all these exports: 库的主要
public-api.ts
文件结合了所有这些导出:
export * from './lib/widgets/public-api';
export * from './lib/blobs/public-api';
BlobsModule
is a testing module which holds an insanely large JSON blob in a component to increase the page size - just for debugging purposes. BlobsModule
是一个测试模块,它在组件中保存一个非常大的JSON blob以增加页面大小 - 仅用于调试目的。
In my consuming project, I import the WidgetsModule
like this: 在我的消费项目中,我像这样导入
WidgetsModule
:
// widgets-wrapper.module.ts - This local module file is being lazy loaded
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { WidgetsModule } from 'lib'; // This is the library, I import *only* the WidgetsModule
import { WidgetsWrapperRoutingModule } from './widgets-routing.module';
@NgModule({
declarations: [...],
imports: [CommonModule, WidgetsWrapperRoutingModule, WidgetsModule], // I import it
exports: [...]
})
export class WidgetsWrapperModule {}
I have 0 references to my BlobsModule
throughout the project. 在整个项目中,我对我的
BlobsModule
有0个引用。 WidgetsModule
has 0 references or dependencies to my BlobsModule
. WidgetsModule
对我的BlobsModule
有0个引用或依赖BlobsModule
。 And yet, when I browse to the page where the WidgetsWrapperModule
is being lazy loaded, I can see in the Chrome networking tab that the BlobsModule
, including the huge JSON blob, is being downloaded as well. 然而,当我浏览到延迟加载
WidgetsWrapperModule
的页面时,我可以在Chrome网络选项卡中看到BlobsModule
,包括巨大的JSON blob,也正在下载。 I can see this ending badly when I have 30+ modules in this library. 当我在这个库中有30多个模块时,我可以看到这个结尾很糟糕。 I do not want to load them all when I only require 1 tiny module.
当我只需要一个小模块时,我不想加载它们。
Perhaps the built-in library support from Angular isn't able to do this? 也许Angular的内置库支持无法做到这一点? Do I have to switch to eg ng-packagr for this to work the way I want it to?
我是否必须切换到例如ng-packagr才能按照我想要的方式工作?
UPDATE: 更新:
Running "ng serve project1" (which uses the library) produces the following chunk: widgets-widgets-module.js
. 运行“ng serve project1”(使用该库)会生成以下块:
widgets-widgets-module.js
。 This chunk holds the code for both WidgetsModule
and BlobsModule
which I really don't think should be happening? 这个块包含
WidgetsModule
和BlobsModule
的代码,我真的不认为应该发生这些代码?
Running "ng serve project1 --prod" removes the BlobsModule
from the chunk which is what I'd expect, so this is good. 运行“ng serve project1 --prod”会从块中删除
BlobsModule
,这是我所期望的,所以这很好。
However, when also creating a new route in the project which will lazy load BlobsModule
, the following chunks get generated (both in dev and prod): widgets-widgets-module.js
, blobs-blobs-modules.js
and default~blobs-blobs-module~widgets-widgets-module.js
. 但是,当在项目中创建一个延迟加载
BlobsModule
的新路由时,会生成以下块(在dev和prod中): widgets-widgets-module.js
, blobs-blobs-modules.js
和default~blobs-blobs-module~widgets-widgets-module.js
。
widgets-widgets-module.js
and blobs-blobs-module.js
both only hold a fraction of their Modules code. widgets-widgets-module.js
和blobs-blobs-module.js
都只包含其模块代码的一小部分。 default~blobs-blob-module~widgets-widget-module.js
holds the biggest part, including the huge JSON blob. default~blobs-blob-module~widgets-widget-module.js
占据最大的部分,包括巨大的JSON blob。 This huge chunk is being loaded as soon as either lazy-loading modules start loading, resulting in most of the code ( as well as the huge JSON blob which is part of BlobsModule
) being loaded when either module is being loaded, resulting in the same problem. 一旦延迟加载模块开始加载,就会加载这个巨大的块,导致大多数代码(以及
BlobsModule
的巨大JSON blob)在加载任何模块时被加载,导致相同问题。
In a production build, this long-named chunk is being renamed to 5.xxxxxxx.js
, so I do not think this is the common chunk as that filename should start with a 0. I'm also not using or referencing the BlobModule
anywhere else outside of its' route, so there should be no reason to move it to a common chunk. 在生产版本中,这个长命名的块正在重命名为
5.xxxxxxx.js
,所以我不认为这是常见的块,因为该文件名应该以0开头。我也没有在任何地方使用或引用BlobModule
除了它的'路线之外,所以没有理由将它移动到一个共同的块。
I've changed the library to use ng-packagr as the build tool. 我已经更改了库以使用ng-packagr作为构建工具。 Now everything works as expected: all the lazy-loading works, only the required Modules are being loaded and no weird combinations for the code chunks are taking place.
现在一切都按预期工作:所有延迟加载工作,只加载所需的模块,并且代码块没有奇怪的组合发生。
The changes are actually minimal: every Module inside the library now has its own package.json file containing: 这些更改实际上是最小的:库中的每个模块现在都有自己的package.json文件,其中包含:
// projects/lib/src/lib/widgets/package.json
{
"name": "lib/widgets",
"version": "0.0.1",
"private": true,
"ngPackage": {
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public-api.ts"
},
"dest": "../../../../../dist/lib/widgets"
}
}
And a change in the main package.json which I use for building the library: 并且我用于构建库的主package.json中的更改:
// old
{
...
"scripts": {
"build": "ng build",
...
}
// new
{
...
"scripts": {
"build": "ng-packagr -p ./projects/lib/src/lib/widgets/package.json",
...
}
(the above build command has to be run for every module inside the library folder, I've created a separate script to do that for me) (必须为库文件夹中的每个模块运行上面的构建命令,我已经为我创建了一个单独的脚本)
And lastly, the imports inside my consuming projects have been updated as well: 最后,我的消费项目中的导入也已更新:
// widgets-wrapper.module.ts
// old
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { WidgetsModule } from 'lib'; // <-- This
...
// new
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { WidgetsModule } from 'lib/widgets'; // <-- To this
...
Everything works flawlessly. 一切都完美无瑕。 I'm still confused why the default setup using the Angular CLI doesn't work though.
我仍然困惑为什么使用Angular CLI的默认设置不起作用。 I'm probably just overlooking something so I'll leave this question open for now - I'd like to return to the Angular method without using ng-packagr directly.
我可能只是忽略了一些东西,所以我现在暂时打开这个问题 - 我想在不使用ng-packagr的情况下返回Angular方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.