使用ngc编译Angular代码时重复导入,而使用TypeScript路径进行导入

时间:2018-07-05 18:12:45

标签: javascript angular typescript systemjs rollupjs

最近,我一直在尝试找出如何将我们使用AngularJS构建的平台过渡到Angular V6。我们广泛使用了延迟加载(不仅仅通过路由器),并且在查看了可用的工具之后,希望将ngc,汇总和systemJS结合起来使用。

无论如何,直到进入服务为止,一切都进行得很好,并且在使用tsconfig定义的“路径”的服务中使用provedIn:'root'的情况下,在与@Injectable批注相关的编译器生成的代码方面,我一直处于挣扎中作为进口。我发现使用内部命名标准来复制“外部”路径,然后将其用于生成的工厂中,我认为该工厂用于注入。

复制步骤:

  • 使用@Injectable和providerIn:'root'
  • ,创建两个单独的库,每个服务(服务A和服务B)
  • 使用index.js导出serviceB以便在serviceA中使用
  • npm将Lib B链接到Lib A
  • 在lib A的tsconfig中创建到tsconfig中的lib B模块的路径映射,例如

    "lib-two": ["../node_modules/lib-two/build/src"]

  • 将serviceB导入serviceA。

ServiceA.ts

import { Injectable } from "@angular/core";
import { ServiceB } from 'lib-two';

@Injectable({
    providedIn: 'root'
})
export class ServiceA {
    constructor(private serviceB: ServiceB) {

    }
}

ServiceB.ts

import { Injectable } from "@angular/core";

@Injectable({
    providedIn: 'root'
})
export class ServiceB {
    constructor() {

    }
}
  • 使用ngc进行编译,目标:es5,模块:es2015
  • 请注意,作为代码生成的一部分,为@Injectable添加工厂,原始导入将使用import *语法进行复制

ServiceA.js

import { Injectable } from "@angular/core";
import { ServiceB } from 'lib-two';
import * as i0 from "@angular/core";
import * as i1 from "lib-two/build/src/index";

var ServiceA = /** @class */ (function () {
    function ServiceA(serviceB) {
        this.serviceB = serviceB;
    }

    ServiceA.decorators = [
        { type: Injectable, args: [{
            providedIn: 'root'
            },] 
    }];

    /** @nocollapse */
    ServiceA.ctorParameters = function () { return [
        { type: ServiceB }
    ]; };

    ServiceA.ngInjectableDef = i0.defineInjectable({ factory: function ServiceA_Factory() { return new ServiceA(i0.inject(i1.ServiceB)); }, token: ServiceA, providedIn: "root" });
     return ServiceA;
}());

export { ServiceA };

ServiceB.js

import { Injectable } from "@angular/core";
import * as i0 from "@angular/core";

var ServiceB = /** @class */ (function () {

    function ServiceB() {
    }

    ServiceB.decorators = [
        { type: Injectable, args: [{
                providedIn: 'root'
            },] }
    ];

    /** @nocollapse */
    ServiceB.ctorParameters = function () { return []; };
    ServiceB.ngInjectableDef = i0.defineInjectable({ factory: function ServiceB_Factory() { return new ServiceB(); }, token: ServiceB, providedIn: "root" });
    return ServiceB;
}());

export { ServiceB };

这不是我所期望的。当然,当我使用汇总将其转换为systemJS模块时,它会添加其他导入内容,从而破坏了SystemJS映射。

我确实认为我有一种解决方法,可以使用 useFactory 属性添加自己的工厂:

ServiceA.ts

import { Injectable, inject } from "@angular/core";
import { ServiceB } from 'lib-two';

@Injectable({
    providedIn: 'root',
    useFactory: () => {
        return new ServiceA(inject(ServiceB))
    }
})
export class ServiceA {
    constructor(private serviceB: ServiceB) {
    }
}

然后生成了一些可行的代码。

ServiceA.js

import { Injectable, inject } from "@angular/core";
import { ServiceB } from 'lib-two';
import * as i0 from "@angular/core";

var ɵ0 = function () {
    return new ServiceA(inject(ServiceB));
};
var ServiceA = /** @class */ (function () {
    function ServiceA(serviceB) {
        this.serviceB = serviceB;
    }
    ServiceA.decorators = [
        { type: Injectable, args: [{
                    providedIn: 'root',
                    useFactory: ɵ0
                },] }
    ];

    /** @nocollapse */
    ServiceA.ctorParameters = function () { return [
        { type: ServiceB }
    ]; };
    ServiceA.ngInjectableDef = i0.defineInjectable({ factory: ɵ0, token: ServiceA, providedIn: "root" });
    return ServiceA;
}());
export { ServiceA };
export { ɵ0 };

这工作了几天,但是今天我遇到了另一个问题(在一个更复杂的示例中),该问题是由于相同的根本原因造成的,所以我尽力弄清实际情况。

问题

我不明白为什么需要复制导入语句和类型来支持工厂的生成?为什么不能继续使用提供的类型?有没有更好的方法可以使我们做到这一点,而仍然获得相同的结果?

我们需要使用路径,因为我们有npm包,其中包含多个子模块。我们使用路径将编译器指向正确的位置,并确保导入的“符号”与我们对SystemJS映射/加载的约定保持一致。

我刚刚开始我的“ Angular”之旅,所以我假设这只是缺乏知识,但是我认为我不得不问一下,因为我目前无法看到我们平台的前进之路。 / p>

希望有人可以提供帮助!

GitHub repro

Github - Lib One

Github - Lib Two

这已经让我发疯了几天,所以任何帮助/指导将不胜感激!

谢谢。

0 个答案:

没有答案