All files / builder/application/plugin dynamic-library-entry.plugin.ts

95% Statements 38/40
80% Branches 16/20
100% Functions 9/9
95% Lines 38/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94  1x 1x 1x 1x 1x     1x     1x 1x 1x 11x 9x 9x   9x     10x     10x 10x         45x 45x 45x   45x               45x     10x       11x   11x 1x 1x   10x 10x 50x       10x       10x 10x 50x       50x       50x         50x 50x 10x                      
/* eslint-disable @typescript-eslint/no-explicit-any */
import { join, normalize } from '@angular-devkit/core';
import path from 'path';
import { Injectable } from 'static-injector';
import * as webpack from 'webpack';
import { LIBRARY_OUTPUT_ROOTDIR } from '../../library';
import type { LibraryComponentEntryMeta } from '../../library';
import { BuildPlatform } from '../../platform/platform';
import { LibrarySymbol } from '../const';
import type { LibraryLoaderContext } from '../type';
 
const CUSTOM_URI = 'dynamic';
const CUSTOM_URI_REG = /^dynamic:\/\/__license(?:\/|\\)(.*)\.ts$/;
@Injectable()
export class DynamicLibraryComponentEntryPlugin {
  private libraryComponentMap = new Map<string, LibraryComponentEntryMeta>();
  constructor(private buildPlatform: BuildPlatform) {}
  apply(compiler: webpack.Compiler) {
    compiler.hooks.thisCompilation.tap(
      'DynamicLibraryEntryPlugin',
      (thisCompilation) => {
        (thisCompilation as any)[LibrarySymbol] = (thisCompilation as any)[
          LibrarySymbol
        ] || { buildPlatform: this.buildPlatform };
        const hooks = webpack.NormalModule.getCompilationHooks(thisCompilation);
        hooks.readResource
          .for(CUSTOM_URI)
          .tapAsync(
            'DynamicLibraryEntryPlugin',
            (loaderContext: any, callback) => {
              const resourcePath: string = loaderContext.resourcePath;
              const id = resourcePath.match(CUSTOM_URI_REG)![1];
              const libraryMeta = this.libraryComponentMap.get(id);
 
              callback(
                undefined,
                `
            import * as amp from 'angular-miniprogram';
            import * as library from '${libraryMeta?.contextPath}';
            amp.componentRegistry(library.${libraryMeta?.className});
            `
              );
              return;
            }
          );
        compiler.hooks.finishMake.tapAsync(
          'DynamicLibraryEntryPlugin',
          (compilation, callback) => {
            const libraryLoaderContext: LibraryLoaderContext = (
              compilation as any
            )[LibrarySymbol];
            if (compilation !== thisCompilation) {
              callback(undefined);
              return;
            }
            Eif (libraryLoaderContext.libraryMetaList) {
              libraryLoaderContext.libraryMetaList.forEach((item) => {
                this.libraryComponentMap.set(item.id, item);
              });
            }
 
            Iif (this.libraryComponentMap.size === 0) {
              callback(undefined);
              return;
            }
            let j = 0;
            this.libraryComponentMap.forEach((meta) => {
              const entry = join(
                normalize(LIBRARY_OUTPUT_ROOTDIR),
                meta.libraryPath
              );
              const dep = webpack.EntryPlugin.createDependency(
                `${CUSTOM_URI}://${path.join('__license', meta.id)}.ts`,
                entry
              );
              compilation.addEntry(
                compiler.context,
                dep,
                entry,
                (err, result) => {
                  j++;
                  if (j === this.libraryComponentMap.size) {
                    callback(undefined);
                  }
                }
              );
            });
          }
        );
      }
    );
  }
}