Spec-Zone.ru › TypeScript 5.1

Глобальный: Плагин

UMD

Модуль UMD — это модуль, который можно использовать как модуль (через импорт) или как глобальную переменную (при выполнении в среде без загрузчика модулей). Многие популярные библиотеки, такие как Moment.js, написаны таким образом. Например, в Node.js или с использованием RequireJS, вы бы написали:

import moment = require("moment");
console.log(moment.format());

в то время как в обычной среде браузера вы бы написали:

console.log(moment.format());

Идентификация библиотеки UMD

Модули UMD проверяют наличие среды загрузчика модулей. Это легко распознаваемый шаблон, который выглядит примерно так:

(function (root, factory) {
    if (typeof define === "function" && define.amd) {
        define(["libName"], factory);
    } else if (typeof module === "object" && module.exports) {
        module.exports = factory(require("libName"));
    } else {
        root.returnExports = factory(root.libName);
    }
}(this, function (b) {

Если вы видите проверки на typeof define, typeof window, или typeof module в коде библиотеки, особенно в начале файла, это, практически всегда, библиотека UMD.

Документация для библиотек UMD также часто демонстрирует пример «Использование в Node.js», показывающий require, и пример «Использование в браузере», показывающий использование тега <script> для загрузки скрипта.

Примеры библиотек UMD

Большинство популярных библиотек сейчас доступны как пакеты UMD. Примеры включают jQuery, Moment.js, lodash и многие другие.

Шаблон

Доступны три шаблона для модулей, module.d.ts, module-class.d.ts и module-function.d.ts.

Используйте module-function.d.ts, если ваш модуль можно вызывать как функцию:

var x = require("foo");
// Note: calling 'x' as a function
var y = x(42);

Обязательно прочтите примечание «Влияние ES6 на сигнатуры вызова модулей».

Используйте module-class.d.ts, если ваш модуль можно создать, используя new:

var x = require("bar");
// Note: using 'new' operator on the imported variable
var y = new x("hello");

То же самое примечание относится и к этим модулям.

Если ваш модуль не вызываемый или не создаваемый, используйте файл module.d.ts.

Модульный плагин или UMD плагин

Модульный плагин изменяет форму другого модуля (либо UMD, либо модуля). Например, в Moment.js, moment-range добавляет новый range метод к объекту moment.

Для целей написания файла объявления вы напишете тот же код, независимо от того, является ли изменяемый модуль обычным модулем или модулем UMD.

Шаблон

Используйте шаблон module-plugin.d.ts.

Глобальный плагин

Глобальный плагин — это глобальный код, который изменяет форму какой-либо глобальной переменной. Как и модули, изменяющие глобальную область, это может вызвать конфликт во время выполнения.

Например, некоторые библиотеки добавляют новые функции к Array.prototype или String.prototype.

Идентификация глобальных плагинов

Глобальные плагины, как правило, легко идентифицируются по их документации.

Вы увидите примеры, похожие на этот:

var x = "hello, world";
// Creates new methods on built-in types
console.log(x.startsWithHello());

var y = [1, 2, 3];
// Creates new methods on built-in types
console.log(y.reverseAndSort());

Шаблон

Используйте шаблон global-plugin.d.ts.

Модули, изменяющие глобальную область

Модуль, изменяющий глобальную область, изменяет существующие значения в глобальной области видимости при их импорте. Например, может существовать библиотека, которая добавляет новые члены к String.prototype при импорте. Этот шаблон несколько опасен из-за возможности конфликтов во время выполнения, но мы по-прежнему можем написать файл объявления для него.

Идентификация модулей, изменяющих глобальную область

Модули, изменяющие глобальную область, как правило, легко идентифицируются по их документации. В целом, они похожи на глобальные плагины, но требуют вызова require для активации их эффектов.

Вы можете увидеть документацию, похожую на эту:

// 'require' call that doesn't use its return value
var unused = require("magic-string-time");
/* or */
require("magic-string-time");

var x = "hello, world";
// Creates new methods on built-in types
console.log(x.startsWithHello());

var y = [1, 2, 3];
// Creates new methods on built-in types
console.log(y.reverseAndSort());

Шаблон

Используйте шаблон global-modifying-module.d.ts.

Использование зависимостей

Существует несколько типов зависимостей, которые может иметь ваша библиотека. Этот раздел показывает, как импортировать их в файл объявления.

Зависимости от глобальных библиотек

Если ваша библиотека зависит от глобальной библиотеки, используйте директиву /// <reference types="..." />:

/// <reference types="someLib" />

function getThing(): someLib.thing;

Зависимости от модулей

Если ваша библиотека зависит от модуля, используйте оператор import:

import * as moment from "moment";

function getThing(): moment;

Зависимости от библиотек UMD

Из глобальной библиотеки

Если ваша глобальная библиотека зависит от модуля UMD, используйте директиву /// <reference types:

/// <reference types="moment" />

function getThing(): moment;

Из модуля или библиотеки UMD

Если ваш модуль или библиотека UMD зависит от библиотеки UMD, используйте оператор import:

import * as someLib from "someLib";

Не используйте директиву /// <reference для объявления зависимости от библиотеки UMD!

Примечания

Предотвращение конфликтов имен

Обратите внимание, что при написании файла глобального объявления можно определить множество типов в глобальной области. Мы настоятельно не рекомендуем это, так как это приводит к возможным неразрешимым конфликтам имен, когда в проекте много файлов объявления.

Простое правило — объявлять типы только пространствами имен, определяемыми глобальной переменной библиотеки. Например, если библиотека определяет глобальное значение «cats», вы должны написать

declare namespace cats {
  interface KittySettings {}
}

Но не

// at top-level
interface CatsKittySettings {}

Это руководство также гарантирует, что библиотеку можно перевести в UMD без нарушения работы пользователей файла объявления.

Влияние ES6 на плагины модулей

Некоторые плагины добавляют или изменяют экспорты верхнего уровня в существующих модулях. Хотя это законно в CommonJS и других загрузчиках, модули ES6 считаются неизменяемыми, и этот шаблон не будет возможен. Поскольку TypeScript не зависит от загрузчика, нет проверки этого правила во время компиляции, но разработчики, планирующие перейти на загрузчик модулей ES6, должны быть об этом осведомлены.

Влияние ES6 на сигнатуры вызова модулей

Многие популярные библиотеки, такие как Express, экспортируют себя как вызываемую функцию при импорте. Например, типичное использование Express выглядит так:

import exp = require("express");
var app = exp();

В загрузчиках модулей ES6 верхнеуровневый объект (здесь импортированный как exp) может иметь только свойства; верхнеуровневый объект модуля никогда не является вызываемым. Наиболее распространенное решение в этом случае — определить экспорт default для вызываемого/создаваемого объекта; некоторые утилиты загрузчика модулей автоматически распознают эту ситуацию и заменят верхнеуровневый объект на экспорт default.

Структура файла библиотеки

Структура ваших файлов объявления должна соответствовать структуре библиотеки.

Библиотека может состоять из нескольких модулей, таких как

myLib
  +---- index.js
  +---- foo.js
  +---- bar
         +---- index.js
         +---- baz.js

Эти модули можно импортировать как

var a = require("myLib");
var b = require("myLib/foo");
var c = require("myLib/bar");
var d = require("myLib/bar/baz");

Таким образом, ваши файлы объявления должны быть

@types/myLib
  +---- index.d.ts
  +---- foo.d.ts
  +---- bar
         +---- index.d.ts
         +---- baz.d.ts
// Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
// Project: [~THE PROJECT NAME~]
// Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

/*~ This template shows how to write a global plugin. */

/*~ Write a declaration for the original type and add new members.
 *~ For example, this adds a 'toBinaryString' method with overloads to
 *~ the built-in number type.
 */
interface Number {
  toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string;

  toBinaryString(
    callback: MyLibrary.BinaryFormatCallback,
    opts?: MyLibrary.BinaryFormatOptions
  ): string;
}

/*~ If you need to declare several types, place them inside a namespace
 *~ to avoid adding too many things to the global namespace.
 */
declare namespace MyLibrary {
  type BinaryFormatCallback = (n: number) => string;
  interface BinaryFormatOptions {
    prefix?: string;
    padding: number;
  }
}

© 2012-2023 Microsoft
Licensed under the Apache License, Version 2.0.
https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-plugin-d-ts.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API