過期的技術,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模板仍然會打進去)

代碼地址

相關文章
相關標籤/搜索