[angular] single runtime multi project sharing dependency scheme

Time:2022-5-7

ngx-center

One center, multiple

  • Introduction to use (video)

    what is it?

  • A solution of angular single runtime multi project sharing dependency
  • Start only one angular platform(PlatformRef)Other subprojects are exported (class ES6 module) and loaded through the resource file list (or separate JS file)

function

  • It supports the refresh of code changes during the development of subprojects
  • Support the naming of subprojects calling the main project export(export * from 'xxx')
  • Support splitchunks of subprojects and main projects (including lazy loading…)
  • Support lazy load routing subproject requests and other dynamic module requests
  • supportcredibleoflong-rangeSub project development
  • You don’t need to understand various concepts, because the export and import processing completely followsDynamic importClass processing scheme for
  • The sub module construction speed is extremely fast, and there is no need to apply for memory from node most of the time
  • Theoretically, sub projects can be loaded at the same time, that is, multi-level sub projects can be loaded
  • You can nest calls supported by other frameworks through subprojects
  • By constructing the composition relationship at compile time, it is non intrusive to the source code and does not need too much modification

rely on

  • Angular10 Angular11 Angular12
  • node12+

principle

Dependency sharing

  • that isnode_modulesThe dependency in becomes a DLL (Dynamic Link Library), which is used by the main and sub applications to ensure the consistency of instances

Named share

  • The naming of the main project will be exported for the sub project, which enables the sub project to call the ng and non ng export of the main project’s components / modules / services / pipelines

Subproject resource start

  • The main project loads the sub project resources by starting the resource file / resource configuration of the sub project, and automatically obtains the export of the sub project after loading, which can be used as a place for dynamic use such as lazy loading route and lazy loading module

usage method

  • This project relies on angularng generateCommand to quickly generate development skeleton
  • Relevant plug-ins can be found inwebpack-ng-dll-plugin,'webpack-bootstrap-assets-pluginView, or manually configure the file
  • It is recommended to use it in the new project first, and then use it in the existing project after understanding the implementation

Main project initialization

  • functionnpx ng g ngx-center:main-init
  • to configure
/**
 *Main project initialization
 */
declare interface MainInitSchematics {
  /**
   *Link library (LIB) name, default DLL
   */
  dllName?: string;
  /**
   *Name of the main item (if it is blank, read the default value)
   */
  projectName?: string;
  /**
   *How to expose the webpack configuration (interaction)
   */
  webpackMode?: string;
  /**
   *Promote webpack to root dependency (yarn will promote by default)
   */
  webpackPromotion?: boolean;
}
  • exceptwebpackModeAll other configurations are silent settings, unless used-xxx yyyExplicit settings
  • After the operation is completed, it can be executed firstnpm run build:center-dllGenerate DLL library and then runnpm run start:center-mainStart main project

    If there is no change in the dependency, you can only start it each timenpm run start:center-main

  • Once the dependency of the main project is changed, it needs to be regenerateddll(npm run build:center-dll).
  • If the main project wants to export some names to sub projects (including but not limited to TS normal syntax export, components, instructions, pipes, modules, services, etc.), it can be declared inexport-module.tsIn the file, the declaration method isexport * from './xxx'At the same time, relative paths can be used for subprojects, but they can also be usedimpot {a} from "@center-main/.../xxx"This way(@center-mainTo configure paths in tsconfig, the default is sourceroot of the main project)
  • After the export name of the main project changes (adding dependencies), you need to restart the sub project
  • The main project uses the ng native method, and the subproject uses lazy loading, but the lazy loading is not the original TS file, but the resource file. Example:
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);
    },
  },
]);

Subproject generation

  • functionnpx ng g ngx-center:sub
  • to configure
/**
 *Subproject generation
 */
declare interface SubSchematics {
  /**
   *Name of subproject (interaction)
   */
  name: string;
  /**
   *Name of the main project (default project)
   */
  mainProjectName?: string;
  /**
   *How to expose the webpack configuration (interaction)
   */
  webpackMode?: string;
  /**
   *Development port (interactive, each sub project occupies a port independently during development)
   */
  port: number;
}
  • Start the main project first, etccenter-dll,center-mainStart the subproject after successful startup
  • The development of subprojects is completely consistent with ordinary development. It can be understood that it is an independent project development that supports all your daily development operations

Remote subproject generation

  • New project
  • installngx-center
  • Run in a new projectnpx ng g ngx-center:remote-sub-init
  • Get master projectmanifest.json(dependent),main-manifest.json(project export naming)
  • If you need to use the master project service, you need to create a virtual master project (that is, create a file with the same export level as the original master project), and you only need to configure the type correctly in the file

    If you export a file, you need to establish a path with the same level, so that the file can be found when the final resource reference context is combined with the path in the resource file JSON
    When exporting module components (instructions, pipes) for use, you only need to specify the next selector and public attributes to facilitate prompt,
    The virtual main project is equivalent to a pile. As long as NG’s loader passes, it is useless

  • Finally, the main project calls the resource list of the remote sub project (or directly gets the resource content) and can be used together with the ordinary sub project

matters needing attention

  • The dependency of the sub project should be the same as that of the main project (preferably the specified version)
  • When the main project resource list changes (increase / decrease dependency), the sub project resource list needs to be synchronized to keep consistent

Build generation

  • Refer to the command, build first, and then copy the sub project into the main project folder
{
  "deploy": "yarn build:center-dll:prod&&yarn build:center-main:prod&&yarn build:sub1:prod&&cpx \"dist/sub1/**/*\" dist/ng-cli-plugin/sub1"
}
  • If your deployment file has storage requirements, you can modify itangular.jsonNeutron projectdeployUrlConfiguration, change the location of the subfolder you want to put, and then modify the command to copy to the corresponding location. Of course, the request path in the main project should also be modified accordingly

    For example, the original project isdeployUrl:'sub1', which you want to put in your home folderrouter/sub1Medium, then it needs to be modifieddeployUrl:'router/sub1'At the same time, the code request part is also changed tofetch('router/sub1/bootstrap.json'), copy tocpx \"dist/sub1/**/*\" dist/ng-cli-plugin/router/sub1
    If not required, the default subproject name is the same as the deployment address location

Demo reference

matters needing attention

  • Tsconfig has developers who configure independently. Please modify the relevant configuration generated by schematics, because it may be different from your specific use scenario
  • If it is different from the default file name (types. Config), it also needs to be copied to the default file name (TSD)
  • If non@angular-builders/custom-webpackAs the export of webapck configuration, please modify the format required by your own builder according to the generated file. There is no arrangement to adapt to other builders for the time being

common problem

  1. The main project route declares the sub project access, and click to access the sub project route. The navigation address has changed, but there is no error or response

    It may need to be rebuiltcenter-dll, because when the ng project is initialized, if you do not choose the generation route, it will lead to the constructioncenter-dllWhen,@angular/routerNot incenter-dllThe two sets of routes used by all subprojects and main projects depend on each other, so there is a problem

  2. Build warnings as follows:
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.

When declaredpolyfills,stylesAnd other files (there may also be export dependencies), but after removing the entry during construction, NG’s self inspection mechanism is currently passedngx-centerIt has basically avoided this problem. Even if it is not avoided, it is no problem, but it is hard to see the warning

  1. Build warnings as follows:
/Users/chen/my-project/ng-cli-plugin-demo/src/app/show-in-main/show-in-main.component.ts  not export from main project!

This is the check plug-inNgNamedImportCheckPluginBecause the main project and sub projects are not strongly related, sometimes the development may unconsciously reference some that have not been exported. Although the construction will not report an error, it will directly reference the code of the main project, that is, two copies will be generated. At this time, it is necessary to add the warning file to theexport-module.tsIn, you don’t need to add absolute paths, just relative references

  1. Add an export to in the main projectexport-module.tsThe subproject reference was not found after

Restart the subproject. If the restart still occurs, please check other reasons

  1. There are some modules in the subproject, which are obviously introduced, but I don’t know why the corresponding components are used to report errors

The specific reason for restarting the subproject is unknown. It seems that after using the export method, ng does not have the corresponding check update, but the restart will be good. The probability of occurrence is low. It is known that if the user-defined form control module is used first and then imported, it may occur, However, if the problem still occurs after restart, it is not caused by this problem. Please check other problems

  1. Build exception, as follows:
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 moduleexport-module.tsNo names have been exported, please add one or remove this feature (search)export-module, remove relevant codes and files)