过期的技术,ng library静态打包实现

研究缘由

  • ng library生成的模块,虽然有构建过程,实际上仅仅进行了一次简易的包装,在项目中还要走一遍构建流程(虽然有metadata,可是还要分析一遍...)
  • 指望相似jquery那种,引入一个连接就可使用,减小编译时的时间

改版说明

  • 仅仅是为了支持aot模式的library打包,启动ivy会直接构建能够用的模块,因此此项目的研究,应该有点过期
  • 原意是将library打包输出为构建好的ngfactory模块
  • 目前绝大部分已经成功,惟一bug(已知)应该是ngstyle也就是style不能使用,没法输出ngstyle
  • js直接引入 能够实现的就是远程路由技术,远程模块技术
  • 传统引入方法,被引入构建时,仍然会从新构建一遍ngfactory,若是要修改,估计要直接修改angular部分包进行支持

使用说明

  • tsconfig.json
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../out-tsc/lib",
    "target": "es2015",
    "declaration": true,
    "inlineSources": true,
    "types": [],
    "lib": [
      "dom",
      "es2018"
    ]
  },
  // 这里参考设置
  "angularCompilerOptions": {
    // 必须
    "annotateForClosureCompiler": false,
    // 必须
    "skipTemplateCodegen": false,
    "strictMetadataEmit": true,
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true,
    "enableResourceInlining": true,
    // 必须
    "enableIvy":false
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}
  • 将此分支构建之后npm link替换掉原来的ng-packagr后,就可使用了(正常构建流程)

实现原理

  • 首先上面的tsconfig设置是要保证代码使用默认的emit方式,既默认输出方式
  • 而后在代码中(本项目中)将es5的默认配置注释掉,使得和es2015输出一致(umd包是会根据es5打包的)
  • 最后经过逻辑,将输出的ngfactory文件加入到导出中(若是不加入,那么umd构建仍然不包含)

调用构建包

  • 直接经过js引入,而后相似动态生成模块那样就Ok了
/**LibAotModuleNgFactory 这个就是经过引入的umd包中的导出*/
    const ref = LibAotModuleNgFactory.create(this.inject);
    console.log(ref);
    const fac = ref.componentFactoryResolver.resolveComponentFactory(
      ref.instance.entry
    );
    console.log(fac);
    this.viewContainerRef.createComponent(fac);
  • 经过路由引用loadChildren方式,直接引用ngfactory
未测试,可是ng源码的测试用例中可使用

已知问题(因为占用时间过多,已经没精力解决了,愿意搞的大牛能够试试)

  • 不能使用style,由于没有导出ngstyle文件
  • 引用构建好的library后,仍然会在构建时生成ngfactory,不知道是ngfactory有特殊的引用方法,仍是须要改ng源码,进行一些重定向或者移除替换操做(由于externals只会移除部分,html模板仍然会打进去)

代码地址

相关文章
相关标签/搜索