2016-07-27 3 views
0

Я пытаюсь загрузить угловой пакет с удаленного URL-адреса CDN. Угловые активы скомпилированы с угловым CLI с использованием флага -prod.Невозможно загрузить сборку сборки CLI Angular2 из удаленного пакета.

ng build -prod 

Ниже из системного файла-конфигурации в хост-приложения (http://localhost:4200).

{ 
    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 в консоли, я могу видеть все пакетные модули, загруженные под «локальный: 4200» домена, а не домен CDN.

Однако, если я развожу сборку без комплекта, каждая вещь загружается правильно.

Может ли кто-нибудь дать представление? Это проблема с системой или угловым CLI?

ответ

0

После отладки через код SystemJS я смог определить, в чем проблема.

Когда вызывается System.register, имя модуля будет разрешено к абсолютному URL-адресу с использованием метода System.decanonicalize. Этот метод использует базовый url-объект вместо URL-адреса пакета, в который был загружен комплект.

Исправление состоит в том, чтобы отложить разрешение имен до этапа уменьшения, на котором у вас есть доступ к свойству loader.address.

К счастью, есть крючки, которые можно использовать для внесения необходимых изменений.

После загрузки systemjs я переопределяю функцию System.register так, чтобы она не деканализовала имя.

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 
     } 
    } 
    } 
Смежные вопросы