简体   繁体   English

角度库模块在未导入的情况下加载

[英]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? 这个块包含WidgetsModuleBlobsModule的代码,我真的不认为应该发生这些代码?

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.jsblobs-blobs-modules.jsdefault~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.jsblobs-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.

相关问题 Angular 2 +延迟加载模块被导入的模块覆盖 - Angular 2 + Lazyloaded Module is being overridden by an imported module 为什么导入的模块会影响Angular 12中的懒加载模块? - Why imported module influence lazy-loaded module in Angular 12? 如何在 Angular 中没有方法的情况下存根导入的模块? - How to stub imported module without methods in Angular? Angular2-导入组件时找不到模块 - Angular2 - module not being found when imported into component Angular Library Route Module 在应用程序中导入时不起作用 - Angular Library Route Module does not work when imported in application 无法使用库中的嵌套延迟加载模块构建 angular 8 应用程序 - Cannot build angular 8 application with nested lazy-loaded module in library 预先加载的模块-是否在核心模块中导入或导出? - Eagerly loaded module - Imported or Exported in core module? Angular - 动态加载的模块/组件中的更改检测而不使用`ChangeDetectorRef` - Angular - change detection in dynamically loaded module/component without using `ChangeDetectorRef` Angular 2库如何加载? - How is Angular 2 library loaded? 角度传递数据到导入的模块 - Angular pass data to an imported module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM