【问题标题】:Correctly writing and importing custom node modules正确编写和导入自定义节点模块
【发布时间】:2017-01-21 03:36:17
【问题描述】:

编辑

不是一个 TypeScript 问题,而是一个最佳实践问题。 TypeScript 中的示例,但实际上,这里的问题是我如何正确地从组成模块的多个文件中公开多个导出,以及如何正确导入它们。


编辑 2

还是有问题

所以,在我的 Module2 的索引中,我有这个:

export * from "./queryFilter";

在 Module1 user.ts 我使用导入它

import { queryFilter as QueryFilter } from "Module2";
(...)
var User = {...}
User.getById = (userId: string) => {
...
}
export { User }

我的 Module1 的 index.ts 我将它导出为 export * from "./model/user";

然后,在我的主项目中,我使用导入它

import * as Schema from "Module1";
var User = Schema.User;

但是,每当我尝试调用 User.getById 时,都会引发错误: Debug: internal, implementation, error TypeError: Uncaught error: Cannot read property 'getByEmail' of undefined

从这种方法来看,我做错了什么???


我有史以来第一次编写几个节点模块,但我确实对正确声明/使用它有一些疑问。

所以我正在创建一个需要另一个自定义模块的模块,我们称它们为 Module1 和 Module2。

因此,主应用程序需要 Module1,但 Module1 也需要 Module2。

现在,在 Module2 上,我有一堆文件,我在每个文件上都导出了我需要的内容。这是一个示例:

模块 2 - Utils.ts:

"use strict"
const RandomString = require("randomstring");

let randomString = (numCharacters: number) => {
    return RandomString.generate({
        length: numCharacters,
        capitalization: 'uppercase',
        charset: 'alphanumeric'
    });
}

module.exports.randomString = randomString;

模块 2 - queryFilter.ts:

"use strict"

export default class QueryFilter {
    name: string;
    op: string;
    value: any;
    scope: string;

    constructor(name: string, op: string, value: any, scope: string) {
        this.name = name;
        this.op = op;
        this.value = value;
        this.scope = scope;
    }

    public static GetConditionQuery(filters: QueryFilter[], params: string[]) {
        (...)
    }

    public static queryComparator(value1: any, value2: any, operator: string): any {
        (...)
    }
}

在 Module1 上,我将 Module2 添加到 package.json,所以当我想使用 QueryFilter 时,例如,我需要这样:

Module1 - Class.ts:

import { QueryFilter } = require("Module2").queryFilter;

现在我的问题是,从我的 Module2 中的每个文件中导出单个项目并以这种方式使用它就足够了吗?或者我应该有一个index 可以从 Module2 导出每个文件,以便 Module1 可以看到它们?

类似的东西:

模块 2 - index.ts:

export "./utils"
export "./queryFilter"
(...)

这样做的正确方法是什么?我完全是新手,我读过的文档并没有对此有所了解..

最好的问候

【问题讨论】:

  • @Darkrum 感谢您的有用回答,因为这确实是 TS 和 JS 之间差异的最糟糕的例子之一
  • 有人必须为此提供一个明确的指南......我现在没有时间,但你可以检查this开始(框架是你的模块2)和this
  • 感谢@BrunoGrieder。这本身不是一个 TypeScript 问题。它是用 TypeScript 编写的,但这里的问题是如何将多个文件中的一堆声明导出暴露到单个 import/require 调用中。
  • 请注意,除了您的import = require 之外,您的export 语法实际上正是ES6 中使用的语法。将import { QueryFilter } = require('Module2').queryFilter 更改为import { queryFilter as QueryFilter } from 'Module2',您就有了 ES6 语法。
  • @BrunoGrieder 我做到了。我已经在重构了。我喜欢在将答案标记为已接受之前进行测试;)

标签: javascript node.js typescript node-modules


【解决方案1】:

根据您的最后一条评论,这是用于创建模块/库的“打字稿解决方案”。对于“纯” ES6,解决方案类似; Typescript 中的打字只是增加了一点难度。

假设您编写一个包含多个文件的模块/库:

func1.ts

export func1(param1: number): string { ... }

func2.ts

export func2(): number { ....}

创建一个 index.ts 来重新导出模块/lib 中有趣的部分

export * from './func1'
export * from './func2'
....

显然,您可以选择(重新)导出并仅公开部分代码,例如export { thisFunc, thatClass } from './anotheFile'

使用declarationscommonjs标志编译模块,并确保package.jsonmain指向index.js,而typings入口指向生成的index.d.ts

现在可以使用 ES6 样式导入语法从 Javascript 或 Typescript 使用此模块/库

import { func1, func2 } from 'mymodule'

如果是 Typescript,这两个函数的类型也会自动导入。

【讨论】:

  • 不知何故,这仍然不起作用。我添加了第二个编辑,其中包含“流程”和错误消息。
  • 该方法看起来不错,但是看起来应该是import { QueryFilter } from "Module2"; in user.ts
猜你喜欢
  • 1970-01-01
  • 2020-08-24
  • 2018-09-16
  • 2018-07-04
  • 2020-01-20
  • 2015-03-07
  • 2021-04-28
  • 2016-02-09
  • 2021-02-20
相关资源
最近更新 更多