乐趣区

关于angular2:Angular单运行时多项目共享依赖方案

ngx-center

一个核心, 多个 ……

  • 应用介绍(视频)

    这是什么?

  • 一个 Angular 单运行时多我的项目共享依赖的解决方案
  • 只启动一个 Angular 平台 (PlatformRef), 其余子项目进行导出(类 es6 module), 通过资源文件清单(或独自 js 文件) 进行申请加载

性能

  • 反对子项目在开发时代码变更的刷新
  • 反对子项目调用主我的项目导出的命名(export * from 'xxx')
  • 反对子项目及主我的项目的 splitChunks(包含懒加载等 …)
  • 反对懒加载路由的子项目申请及其他动静模块的申请
  • 反对 可信 近程 子项目开发
  • 不须要理解各种概念, 因为导出导入解决齐全遵循 动静 import的类解决计划
  • 子模块构建速度极快, 且在大多数工夫不须要向 node 申请内存
  • 实践上子项目同时能够加载子项目, 也就是能够存在多层级子项目的加载
  • 能够通过子项目嵌套其余框架反对的调用
  • 通过在编译时构建形成关系, 对源代码无侵入性, 不须要过多革新

依赖

  • Angular10 Angular11 Angular12
  • node12+

原理

依赖共享

  • 也就是 node_modules 中的依赖变成 dll(动态链接库), 主, 子利用都应用这个 dll 保障实例的一致性

命名共享

  • 主我的项目的命名会导出, 供子项目用, 实现子项目调用主我的项目的组件 / 模块 / 服务 / 管道等 ng 与非 ng 的导出

子项目资源启动

  • 主我的项目通过启动子我的项目的资源文件 / 资源配置, 来加载子项目资源, 并且在加载后实现主动取得子项目的导出, 能够作为懒加载路由, 懒加载模块等动静应用的中央调用

应用办法

  • 本我的项目依赖的是 Angular 的 ng generate 命令, 疾速生成开发骨架
  • 相干插件可在在 webpack-ng-dll-plugin,'webpack-bootstrap-assets-plugin 查看, 或者可手动配置文件
  • 倡议先在新我的项目中应用, 待理解实现后, 再应用到已有我的项目中

主我的项目初始化

  • 运行npx ng g ngx-center:main-init
  • 配置
/**
 * 主我的项目初始化
 */
declare interface MainInitSchematics {
  /**
   * 链接库 (lib) 名称, 默认 dll
   */
  dllName?: string;
  /**
   * 主我的项目的名字(为空读取默认值)
   */
  projectName?: string;
  /**
   * 应用裸露 webpack 配置的形式(交互)
   */
  webpackMode?: string;
  /**
   * 将 webpack 晋升到根依赖(yarn 会默认晋升)
   */
  webpackPromotion?: boolean;
}
  • 除了 webpackMode 外, 其余配置均为静默设置, 除非应用 -xxx yyy 显式设置
  • 运行实现后, 能够先执行 npm run build:center-dll 生成 dll 库, 再运行 npm run start:center-main 启动主我的项目

    如依赖无变更, 每次可仅启动npm run start:center-main

  • 主我的项目的依赖一旦变更, 就须要从新生成dll(npm run build:center-dll).
  • 如果主我的项目想导出某些命名给子项目应用 (包含不限于 ts 失常语法导出, 组件, 指令, 管道, 模块, 服务等), 能够申明在export-module.ts 文件中, 申明形式为 export * from './xxx', 同时子项目应用能够应用相对路径, 然而也能够应用impot {a} from "@center-main/.../xxx" 这种形式(@center-main 为配置 tsconfig 中的 paths, 默认主我的项目的 sourceRoot)
  • 主我的项目的导出命名变动后(增加依赖), 须要重启子项目
  • 主我的项目应用子项目应用的是 ng 原生办法, 懒加载, 只不过懒加载的不是原来的 ts 文件, 而是资源文件, 示例:
RouterModule.forRoot([
  {
    path: 'sub1',
    loadChildren: () => {return fetch(`http://127.0.0.1:4201/bootstrap.json`)
        .then((item) => item.json())
        .then((res) => loadRemoteModuleManifest(res))
        .then((item) => item.module);
    },
  },
]);

子项目生成

  • 运行npx ng g ngx-center:sub
  • 配置
/**
 * 子项目生成
 */
declare interface SubSchematics {
  /**
   * 子项目的名字(交互)
   */
  name: string;
  /**
   * 主我的项目的名字(默认 defaultProject)
   */
  mainProjectName?: string;
  /**
   * 应用裸露 webpack 配置的形式(交互)
   */
  webpackMode?: string;
  /**
   * 开发端口(交互, 每一个子项目开发时独立占据一个端口)
   */
  port: number;
}
  • 先启动主我的项目, 等 center-dll,center-main 都启动胜利后, 再启动子我的项目
  • 子项目的开发, 与一般的开发完全一致, 能够了解为, 就是一个独立的我的项目开发, 反对所有你日常开发的操作

近程子项目生成

  • 新建我的项目
  • 装置ngx-center
  • 在新建的我的项目中运行npx ng g ngx-center:remote-sub-init
  • 取得主我的项目manifest.json(依赖),main-manifest.json(我的项目导出命名)
  • 如果须要应用主我的项目服务, 则须要建设虚构主我的项目(即建设与原主我的项目导出层级雷同的文件), 文件中只须要将类型配置正确即可.

    如导出一个文件, 那么就须要建设一个层级雷同的门路, 使最初的资源援用上下文与资源文件 json 中的门路联合时, 能找到这个文件即可
    导出模块组件 (指令, 管道) 应用时, 只须要指定下 selector 及公开属性, 不便提醒即可,
    虚构主我的项目相当于一个桩只有 ng 的 loader 通过, 就没有用了

  • 最初由主我的项目调用近程子项目的资源清单 (或者间接拿到资源内容) 即可和一般的子项目一起应用

注意事项

  • 子项目的依赖要和主我的项目放弃一样(最好是指定版本)
  • 主我的项目资源清单变动时(减少 / 缩小依赖), 须要同步子项目资源清单保持一致

构建生成

  • 参考命令, 先构建, 再讲子项目复制进主我的项目文件夹中
{"deploy": "yarn build:center-dll:prod&&yarn build:center-main:prod&&yarn build:sub1:prod&&cpx \"dist/sub1/**/*\"dist/ng-cli-plugin/sub1"}
  • 如果你的部署文件寄存有要求, 能够批改 angular.json 中子我的项目的 deployUrl 配置, 改为你要放的子文件夹地位, 而后再将命令批改为复制到对应的地位即可, 当然主我的项目中的申请门路也要相应批改

    比方, 原我的项目为 deployUrl:'sub1', 想放到主文件夹中的router/sub1 中, 那么就要批改 deployUrl:'router/sub1', 同时, 代码申请局部也改成fetch('router/sub1/bootstrap.json'), 复制到cpx \"dist/sub1/**/*\" dist/ng-cli-plugin/router/sub1
    如果没有要求, 默认子项目名与部署地址地位雷同

demo 参考

  • 源码地址:https://github.com/wszgrcy/ng-cli-plugin-demo
  • 演示地址:https://wszgrcy.github.io/ng-cli-plugin-demo/
  • 近程子项目演示:https://wszgrcy.github.io/ng-window/

注意事项

  • tsconfig 有独立进行配置的开发者, 请自行批改由原理图 (schematics) 生成的相干配置, 因为可能与您具体应用场景不同
  • 申明文件名如果与默认不同(typings.d.ts), 也须要自行复制或增加到 tsconfig 中
  • 如果应用非 @angular-builders/custom-webpack 作为 webapck 配置的导出, 也请自行依据生成的文件批改为您本身的 builder 须要的格局, 临时没有安顿适配其余 builder.

常见问题

  1. 主我的项目路由申明了子项目拜访, 也点击拜访子项目路由了, 导航地址曾经变动, 然而没有任何报错, 也没有任何反馈

    可能须要从新构建 center-dll, 因为 ng 我的项目初始化时, 如果你没有抉择生成路由, 这就导致了构建center-dll 时,@angular/router没有在 center-dll 中, 所以子项目, 主我的项目用的两套路由依赖, 所以出的问题

  2. 构建正告, 如下:
Warning: /Users/chen/my-project/ng-cli-plugin-demo/src/polyfills.ts is part of the TypeScript compilation but it's unused.
Add only entry points to the 'files' or 'include' properties in your tsconfig.

当申明了 polyfills,styles 等文件 (可能也有导出依赖), 然而在构建时将入口去掉后,ng 的本身查看机制, 目前通过ngx-center 构建的, 基本上曾经躲避这个问题, 即便不躲避也没问题, 只不过正告看的好受

  1. 构建正告, 如下:
/Users/chen/my-project/ng-cli-plugin-demo/src/app/show-in-main/show-in-main.component.ts  not export from main project!

这个是查看插件 NgNamedImportCheckPlugin 在起作用, 因为主我的项目和子项目并不是强关联, 有时候开发可能不盲目的援用了一些没有到导出的, 尽管构建不会报错, 然而会间接援用主我的项目的代码, 也就是生成了两份, 这时就须要将报正告的文件退出到 export-module.ts 中, 不须要加绝对路径, 只须要绝对援用就 ok 了

  1. 在主我的项目退出一个导出到 export-module.ts 中后, 子项目援用没有找到.

重启子项目即可, 如果重启仍然复现, 请查看其余起因

  1. 子项目呈现某些模块, 明明引入了, 然而不晓得为啥应用对应组件时报错

重启子项目, 具体起因未知, 仿佛是应用导出这种形式后,ng 没有对应的查看更新, 然而重启就会好了, 呈现概率较低, 已知就是如果应用自定义表单控件模块, 先应用, 再引入就有可能产生 …, 然而, 如果重启后仍旧呈现问题, 那么就不是这个问题导致的, 请排查其余问题

  1. 构建异样, 如下:
An unhandled exception occurred: Dll Reference Plugin Invalid Options

options.manifest.content should NOT have fewer than 1 properties
options.manifest.content should match some schema in anyOf
options.manifest should be string
options.manifest should match exactly one schema in oneOf
options should NOT have additional properties
options should have required property 'content'
options should have required property 'name'
options should match some schema in anyOf

导出模块 export-module.ts 未导出任何命名, 请增加一个, 或者移除这个性能(搜寻export-module, 移除相干代码及文件即可)

退出移动版