无法从远程包加载Angular2 CLI生产版本

时间:2016-07-27 15:58:28

标签: angular systemjs

我正在尝试从远程CDN URL加载角度包。使用-prod标志,使用角度CLI编译角度资产。

ng build -prod

以下内容来自主机应用程序(http://localhost:4200)中的system-config文件。

{
  map: {'sharedcomponent':'http://mycdn.com/shared-component'}
  packages: {
    "http://mycdn.com/shared-component": {
      "main": "main.js",
      "meta": {
        "*": {
          "format": "system",
          "scriptLoad": true
      }
    }
  }
}

主机应用程序稍后导入该组件会返回一个空对象。

System.import('sharedcomponent')
  .then(function(comp){
    console.log(comp); //outputs {}
  });

在控制台中检查SystemJS.defined时,我可以看到在“localhost:4200”域而不是CDN域下加载的所有捆绑模块。

但是,如果我部署非捆绑版本,则每件事都会正确加载。

任何人都可以提供任何见解吗?这是一个带有systemjs还是角度CLI的问题?

1 个答案:

答案 0 :(得分:0)

通过SystemJS代码调试后,我能够确定问题所在。

调用System.register时,模块名称将使用System.decanonicalize方法解析为绝对URL。该方法使用基本url对象而不是加载bundle的包的URL。

修复是将名称解析推迟到您可以访问loader.address属性的reduce步骤。

幸运的是,您可以利用钩子进行必要的更改。

加载systemjs后,我重写System.register函数,使其不会对名称进行decanonical化。

System.register = function(name, deps, declare) {
  if (typeof name != 'string') {
    declare = deps; deps = name; name = null;
  }

  if (typeof declare == 'boolean')
    return this.registerDynamic.apply(this, arguments);

  this.pushRegister_({
    amd: false,
    entry: {
      name: name,
      deps: deps,
      declare: declare,
      declarative: true,
      executingRequire: false,
      esmExports: false,
      evaluated: false,
      originalIndices: null,
      execute: null,
      normalizedDeps: null,
      groupIndex: null,
      module: null,
      esModule: null
    }
  });
};

然后我覆盖reduceRegister_函数以查找元数据标志,以确定是否应该使用decanonicalize方法来解析模块名称。

如果设置为false,我只需使用load.address与基本URL对象解析名称。

System.reduceRegister_ = function(load, register){
  if (register) {
    let entry = register && register.entry;
    entry.name = (load.metadata && load.metadata.decanonicalize === false) ?
      new URL(entry.name, load.address).href.replace(/%05/g, '#') :
      this.decanonicalize(entry.name, load.address);
  }
  this.__proto__.reduceRegister_.call(this, load, register);
}

包配置在这里:

{
  map: {'sharedcomponent':'http://mycdn.com/shared-component'}
  packages: {
    "http://mycdn.com/shared-component": {
      "main": "main.js",
      "meta": {
        "*": {
          "format": "system",
          "scriptLoad": true,
          "decanonicalize":false
      }
    }
  }