【问题标题】:How to structure a shared npm module for Angular 2/Ionic 2 apps如何为 Angular 2/Ionic 2 应用程序构建一个共享的 npm 模块
【发布时间】:2016-11-12 05:34:34
【问题描述】:

我正在开发几个共享功能的 Ionic 2 实用应用程序,例如身份验证服务和键盘组件,并且自然希望将它们分离到一个共享模块中。该计划是使用npm link 来简化共享模块和应用程序的并发开发。但是,我在尝试构建和运行我的 Ionic 应用程序时遇到了问题,这可能是由于我的共享模块的结构不正确或构建工具配置。

我的共享模块结构如下:

appkit/
    src/
        components/
            Keypad.ts
            index.ts
        pipes/
            PipeA.ts
            PipeB.ts
            index.ts
        services/
            AuthenticationService.ts
            DocumentService.ts
            index.ts
        Appkit.module.ts
        index.ts

    package.json
    tsconfig.json

每个索引文件都有类似的结构,例如src/pipe/index.ts

export { PipeA } from "./PipeA";
export { PipeB } from "./PipeB";

还有根索引src/index.ts

export * from "./Appkit.module";
export * from "./components";
export * from "./pipes";
export * from "./services";

我在 src/Appkit.module.ts 中定义 Angular 2 模块的地方:

import { NgModule, ModuleWithProviders } from "@angular/core";
import { IonicModule } from "ionic-angular";
// Components
import { Keypad } from "./components/Keypad";

// Pipes
import { PipeA } from "./pipes/PipeA";
import { PipeB } from "./pipes/PipeB";

// Services
import { AuthenticationService } from "./services/AuthenticationService";
import { DocumentService } from "./services/DocumentService";

@NgModule({
    imports: [IonicModule],
    declarations: [
        // Components
        Keypad,
        // Pipes
        PipeA,
        PipeB
    ],
    exports: [
        // Components
        Keypad,
        // Pipes
        PipeA,
        PipeB
    ]
})
export class Appkit {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: Appkit,
            providers: [
                AuthenticationService,
                DocumentService
            ]
        };
    }
}

作为构建过程的一部分,我将整个 src 目录复制到 dist/ 并运行 ngc,它似乎完成了所有正确的 AoT 编译。

现在如果我去 Ionic 2 应用程序之一运行 npm link app-kit 然后在 src/app/app.module.ts 添加 Appkit.forRoot() 到导入部分和 npm run build 我得到:

Error: Unexpected value '[object Object]' imported by the module 'AppModule'

Web pack (npm run watch) 设法通过构建,但在运行时产生相同的错误。

我还尝试物理复制共享模块文件夹以检查是否是符号链接问题并得到相同的结果。

如果我在 NgModule 配置中使用提供程序而不是使用 forRoot() 方法,我会收到错误:

Error: Unexpected value 'Appkit' imported by the module 'AppModule'

我不确定我到底哪里出错了,因为我的结构似乎与其他 angular 2 库一致。

【问题讨论】:

  • (1) 您在库中使用的 angular2 版本是否比您在应用程序中使用的版本旧?当那是问题时,我也遇到了同样的错误。 (2) 另外,请确保 *.metadata.json 文件实际存在于您的 node_modules 文件夹中。 (3) 尝试的第三件事是手动复制库包(或运行npm pack)并在应用程序的 package.json 中引用创建的 *.tgz 文件。有时 npm 链接无法按我预期的方式工作。
  • 嗨@Isaac,我进行了快速检查,并且(1)我的angular 2版本在库中是相同的,我将它们列为对等和开发依赖项。 (2) *.metadata.json 文件存在于 node_modules/appkit/dist 目录中,是否需要在 appkit 的根目录下? (3)我试过npm link,把目录复制过来和npm pack,结果都一样。
  • *.metadata.json 文件需要与它们引用的 *.ts 文件位于同一目录中。我没有办法查看您的代码。如果你能分享一个 git repo,我可以看看。
  • @Isaac,感谢您的关注。我创建了一个 git repo github.com/cubicleWar/appkit
  • 我遇到了完全相同的问题,到目前为止一直无法弄清楚为什么它不起作用。我尝试使用会产生相同错误的预制模板:github.com/driftyco/ionic2-module-template

标签: angular ionic2


【解决方案1】:

经过几次修改后,我得到了它。

  1. 在您的自述文件中,您从 nucleus-appkit 导入,但包名为 appkit

  2. 我无法直接从根目录导入,我必须从dist 文件夹导入。例如

import { Appkit } from 'appkit/dist';

  1. 您不应在已发布的包中包含*.ts 文件。就此而言,*.ngfactory.ts 文件也不应该包含在内,但是当我将它们留在其中时它们不会导致任何错误。您想要的文件是:*.js*.js.map*.metadata.json

确保将您的依赖项和 peerDependencies 添加到我的应用程序的 package.json 后,应用程序已编译。

【讨论】:

  • nucleus-appkit 是我刚刚在示例 repo 中将其简化为 appkit 的实际名称。将 /dist 添加到导入后,VS Code 现在不再将其标记为错误,但我仍然收到错误:模块“AppModule”导入的意外值“Appkit”。我还尝试了新的离子安装,结果相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 2017-10-14
  • 1970-01-01
  • 2018-02-09
  • 2017-10-08
  • 2020-01-12
  • 1970-01-01
相关资源
最近更新 更多