Создайте библиотеку TypeScript и используйте ее из Node.js с ES6 и TypeScript - PullRequest
0 голосов
/ 25 января 2019

Я хочу создать библиотеку TypeScript в качестве частного пакета npm, который можно использовать в Node.js (включая 6.x) с использованием ES6 с поддержкой @types и TypeScript.

Цель библиотеки -расширить тип Request с express и предоставить дополнительные свойства.

Я создал новый проект Node.js и добавил его tsconfig.json:

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "sourceMap": true,
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "types": ["mocha"]
  }
}

Это соответствующие частиpackage.json:

{
  "name": "@myscope/my-lib",
  "main": "dist",
  "scripts": {
    "build": "rm -rf ./dist && ./node_modules/.bin/tsc",
    "test": "./node_modules/.bin/mocha test"
  },
  "private": true,
  "dependencies": {
    "joi": "11.4.0"
  },
  "devDependencies":  {
    "mocha": "^5.2.0",
    "express": "^4.16.4",
    "@types/express": "^4.16.1",
    "@types/joi": "^14.3.0",
    "@types/mocha": "^5.2.5",
    "typescript": "^3.2.4"
  }
}

Моя структура папок такая:

- dist
- src
  - http
  - security
- test

Я создал новый файл TypeScript AuthenticatedRequest.ts в src/http:

import {Request} from "express";
import {UserReference} from "../security/UserReference";

export interface AuthenticatedRequest extends Request {
  user: UserReference
}

src/security содержит UserReference.ts:

import {Claim} from "./Claim";

export interface UserReference {
  claims: Claim[];
}

и Claim.ts:

import {IClaim} from "./IClaim";

export class Claim implements IClaim {
  type: string;
  value: string;

  constructor(type: string, value: string) {
    this.type = type;
    this.value = value;
  }
}

IClaim.ts выглядит следующим образом:

export interface IClaim {
  type: string,
  value: string
}

В test я создал AuthenticatedRequestTests.js (обычный ES6, здесь нет TypeScript для завершения кода проверки и использования из ES6):

'use strict';

const assert = require('assert');
const Claim = require("../dist/security/Claim").Claim;

describe('req', () => {
  it('should ', done => {
    /** @type {AuthenticatedRequest} */
    const req = {};
    req.user = { claims: [new Claim('tenantId', '123')] };
    assert.equal(req.user.claims[ 0 ].type, 'tenantId');
    assert.equal(req.user.claims[ 0 ].value, '123');
    return done();
  });
});

Теперь у меня есть несколько вопросов:

  • Это ожидаемый способ TypeScript для решения этой проблемы?
  • Можно ли просто использовать require("../dist/security/Claim"); вместо require("../dist/security/Claim").Claim;?
  • вместо использования этого jsdoc государственных деятелейt /** @type {AuthenticatedRequest} */ Я хотел бы использовать /** @type {myLib.http.AuthenticatedRequest} */

Я также создал локальный тестовый проект для интеграции и установил свою библиотеку через npm link.

Но вместо использования

const Claim = require("@scope/my-lib/security/Claim").Claim; Мне нужно использовать

const Claim = require("@scope/my-lib/dist/security/Claim").Claim;

Как мне избавиться от имени папки dist здесь?

Также, используяjsdoc комментарий для AuthenticatedRequest в проекте тестирования интеграции, я получаю ошибку, что тип не может быть найден:

enter image description here

1 Ответ

0 голосов
/ 27 января 2019

package.json

  • Должно быть поле с именем types (или typings), сообщающее потребителям вашей библиотеки, где находятся определения типов для вашего проекта. Если они сгенерированы TypeScript и сохранены в dist/index.d.ts, то это путь, который следует использовать.

    "types": "./dist/index.d.ts"

  • Там должно быть поле с именем files, содержащее массив файлов / каталогов, которые будут доставлены вашим конечным пользователям.

Выполнение тестов

  • Это ожидаемый способ TypeScript решить эту проблему?

    Если вы используете TypeScript для разработки своей библиотеки, нет причин не использовать TypeScript для своих тестов. Существуют совместимые с TypeScript тестовые тесты (ts-jest раньше был популярен, и теперь Jest способен понимать TypeScript из коробки).

  • Можно ли просто использовать require("../dist/security/Claim"); вместо require("../dist/security/Claim").Claim;?

    С TypeScript возможны несколько видов синтаксиса. Вы можете экспортировать Claim используя экспорт по умолчанию и сделать:

    import Claim from "../dist/security/Claim";
    

    или

    const Claim = require("../dist/security/Claim");
    
  • Вместо использования этого оператора jsdoc /** @type {AuthenticatedRequest} */ Я хотел бы использовать /** @type {myLib.http.AuthenticatedRequest} */.

    Вам потребуется тип импорта . Они выглядят так:

    /**
     * @type {import('path/to/AuthenticatedRequest')}
     */
    const req {}
    

    Путь может быть относительным или абсолютным. Если вы хотите обрабатывать локальную кодовую базу так, как если бы она была установлена ​​из npm, вы можете создать еще один файл package.json в своем тестовом каталоге и использовать относительный путь для разрешения вашего библиотечного модуля.

    "dependencies": {
      "my-library": "../path/to/the/root"
    }
    
  • Также, используя комментарий jsdoc для AuthenticatedRequest в проекте тестирования интеграции, я получаю сообщение об ошибке, что тип не может быть найден:

    Это также решается типами импорта. Если тип не входит в глобальную область, его необходимо импортировать, прежде чем использовать. Вместо этого используйте import('path/to/AuthenticatedRequest').


Есть несколько вещей, которые происходят. Если бы вы могли создать общедоступное хранилище для демонстрации своих проблем, я уверен, что нам было бы легче помочь вам решить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...