2016-09-01 3 views
1

Я пытаюсь написать lib в Typcript, который я хочу использовать в других проектах машинописных или JS. Все остальные проекты выполняются в браузерах.ошибка TS2306: '... index.d.ts' не является модулем

Проект Mycriptcript lib имеет несколько файлов, и каждый файл представляет собой компонент React с 1 интерфейсом класса и 1-2 (компонент + реквизит + состояние для тех, кто знаком с React).

Я хочу, чтобы моя библиотека компонентов была импортирована в качестве модуля AMD другими проектами, и я хочу, чтобы весь скомпилированный JS-код был связан в один файл как часть процесса сборки библиотеки.

До сих пор мне удалось настроить все, чтобы моя библиотека компилировалась. Я создал компилятор со следующими параметрами: jsx: "react", declaration: true, module: "amd"

Сгенерированный код Lib выглядит следующим образом:

define("epb-widget/WidgetItemNav", ["require", "exports", "react"], function (require, exports, React) { 
    "use strict"; 
    exports.WidgetItemNav = ...; 
}); 
define("epb-widget/WidgetItemInfo", ["require", "exports", "react"], function (require, exports, React) { 
    "use strict"; 
    exports.WidgetItemInfo = ...; 
}); 
define("epb-widget/WidgetItem", ["require", "exports", "react", "epb-widget/WidgetItemNav", "epb-widget/WidgetItemInfo"], function (require, exports, React, WidgetItemNav_1, WidgetItemInfo_1) { 
    "use strict"; 
    exports.WidgetItem = ...; 
}); 
define("epb-widget/WidgetOptions", ["require", "exports", "react"], function (require, exports, React) { 
    "use strict"; 
    exports.WidgetOptions = ...; 
}); 
define("epb-widget/Widget", ["require", "exports", "react", "epb-widget/WidgetItem", "epb-widget/WidgetOptions"], function (require, exports, React, WidgetItem_1, WidgetOptions_1) { 
    "use strict"; 
    exports.Widget = ...; 
}); 
define("epb-widget", ["require", "exports", "epb-widget/Widget", "epb-widget/WidgetItem", "epb-widget/WidgetItemInfo", "epb-widget/WidgetItemNav", "epb-widget/WidgetOptions"], function (require, exports, Widget_1, WidgetItem_2, WidgetItemInfo_2, WidgetItemNav_2, WidgetOptions_2) { 
    "use strict"; 
    exports.Widget = Widget_1.Widget; 
    exports.WidgetItem = WidgetItem_2.WidgetItem; 
    exports.WidgetItemInfo = WidgetItemInfo_2.WidgetItemInfo; 
    exports.WidgetItemNav = WidgetItemNav_2.WidgetItemNav; 
    exports.WidgetOptions = WidgetOptions_2.WidgetOptions; 
}); 

Это много модулей AMD, на мой вкус, но я могу жить с этим. Сгенерированный код выглядит так, как будто он будет работать хорошо.

Сформированный .d.ts файл выглядит следующим образом:

declare module "epb-widget/WidgetItemNav" { 
    import * as React from "react"; 
    export interface WidgetItemNavProps { 
     ... 
    } 
    export class WidgetItemNav extends React.Component<WidgetItemNavProps, void> { 
     ... 
    } 
} 
declare module "epb-widget/WidgetItemInfo" { 
    export interface WidgetItemInfoProps { 
     ... 
    } 
    export const WidgetItemInfo: (props: WidgetItemInfoProps) => JSX.Element; 
} 
declare module "epb-widget/WidgetItem" { 
    export interface WidgetItemProps { 
     ... 
    } 
    export const WidgetItem: (props: WidgetItemProps) => JSX.Element; 
} 
declare module "epb-widget/WidgetOptions" { 
    import * as React from "react"; 
    export interface WidgetOptionsProps { 
     ... 
    } 
    export interface WidgetOptionsState { 
     ... 
    } 
    export class WidgetOptions extends React.Component<WidgetOptionsProps, WidgetOptionsState> { 
     ... 
    } 
} 
declare module "epb-widget/Widget" { 
    import * as React from "react"; 
    import { WidgetItemProps } from "epb-widget/WidgetItem"; 
    export interface WidgetProps { 
     ... 
    } 
    export interface WidgetState { 
     ... 
    } 
    export class Widget extends React.Component<WidgetProps, WidgetState> { 
     ... 
    } 
} 
declare module "epb-widget" { 
    export { Widget, WidgetProps } from "epb-widget/Widget"; 
    export { WidgetItem, WidgetItemProps } from "epb-widget/WidgetItem"; 
    export { WidgetItemInfo, WidgetItemInfoProps } from "epb-widget/WidgetItemInfo"; 
    export { WidgetItemNav, WidgetItemNavProps } from "epb-widget/WidgetItemNav"; 
    export { WidgetOptions, WidgetOptionsProps } from "epb-widget/WidgetOptions"; 
} 

Опять же, это выглядит вполне разумным. И все это выводилось непосредственно компилятором Typcript.

Наконец, эта библиотека является модулем НПМ и его package.json выглядит следующим образом

{ 
    "name": "epb-widget", 
    "version": "1.0.0", 
    "description": "...", 
    "main": "./dist/index.js", 
    "typings": "./dist/index", 
    "globalDependencies": {...}, 
    "devDependencies": {...} 
} 

Но вот проблема

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

Я просто пытаюсь импортировать классы, как это:

import {Widget, WidgetProps, WidgetItem} from "epb-widget"; 

но машинопись компилятор выдает следующее сообщение об ошибке

error TS2656: Exported external package typings file '.../node_modules/epb-widget/dist/index.d.ts' is not a module. Please contact the package author to update the package definition. 

Я честно не могу понять, что я должен сделать здесь. index.d.ts был создан tsc, и я не уверен, почему тот самый tsc не может его использовать в другом проекте.

+1

Сформированный .d.ts выглядит как определения внешнего модуля, что не является ожидаемым для файлов описаний, на которые указывает параметр 'typings'. Я делаю это успешно с 'commonjs'; Это проблема «amd»? Что вы создали .d.ts, если вы выбрали «commonjs»? –

+0

Хмм, я не должен использовать параметр «typings» в 'package.json' библиотеки? – LordOfThePigs

+0

Да. Я бы так подумал. В зависимых проектах попробуйте использовать сгенерированные .d.ts в качестве внешних файлов типизации, как вы бы сделали с «чистой» библиотекой js –

ответ

4

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

  • создать index.ts что Реэкспорт определения выставлены в библиотеке, например,

    export * from './API' 
    export * from './Decorators' 
    ... 
    
  • компилировать файлы библиотеки с --declaration флагом, чтобы автоматически генерировать типизации

  • добавить typings запись в package.json указывающий на генерируемой index.d.ts файл

Чтобы использовать библиотеку:

  • оставьте его в node_modules папки, как и любой другой библиотеки
  • просто import * as mylib from 'mylib': он будет автоматически импортировать все экспортируемые ОПРЕДЕЛЕНИЯ и в типизации

Этот процесс отлично работает с commonjs и от того, что я понимаю, с systemjs тоже. Я не знаю, о amd, и ваши сгенерированные типизации выглядят весьма отличается от моего:

Сформированный index.d.ts обычно выглядит

export * from './API'; 
export * from './Decorators'; 
... 

и файл API.d.ts обычно выглядят как

import * as stream from 'stream'; 
import * as net from 'net'; 
import * as url from 'url'; 
export interface Factory { 
    end(): Promise<void>; 
} 
export interface ChannelFactory extends Factory { 
    getChannel(name: string, closeListener?:() => void): Promise<Channel>; 
    existsChannel(name: string): Promise<boolean>; 
} 
.... 
+0

По-видимому, проблема в том, что он отлично работает, поскольку вы НЕ комбинируете объявления типа в один файл (т. е. если вы используете '--outDir', он работает, если вы используете' --out', это не так. Из нескольких тестов, которые я сделал сегодня, и из предоставленных вами ссылок, кажется, что лучший способ правильно упаковать все - сделать 2 прохода по TS-коду. 1-й проход генерирует JS-код, упакованный в один файл. Второй проход генерирует определения типов в виде отдельных файлов. Тогда все счастливы. – LordOfThePigs

+0

Полезно знать! ... и рад, что у вас есть решение. –

Смежные вопросы