Похоже, что Typescript не может разрешить глобальную функцию moment()
при использовании в немодульном контексте.
версия tsc: 2.1.6
момент версии: 2.17.1
Воспроизведение (при условии, что tsc
находится на вашем $PATH
):
$ mkdir repro && cd repro
$ npm i moment
$ echo 'const now = moment();' > test.ts
$ tsc --module none test.ts
test.ts(1,13): error TS2304: Cannot find name 'moment'.
Однако использование типа модуля работает должным образом:
$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js
К сожалению, в моем проекте не используется сборщик или модульная система, поэтому я пока застрял с "module": "none"
.
Моя единственная альтернатива - использовать что-то вроде typings install --save --global dt~moment
?
У меня такая же проблема. Неважно, какой тип модуля вы укажете в tsconfig.json. Я получаю ту же ошибку, что и @rossipedia
Я сообщил о той же проблеме (https://github.com/moment/moment/issues/3663), но, к сожалению, она была просто закрыта без какой-либо реакции.
В итоге я скопировал moment.d.ts
в свой каталог /scripts/app
и реализовал исправление, указанное в https://github.com/moment/moment/issues/3663#issuecomment -273199291
Надеюсь, что в конце концов в moment.d.ts
появится более постоянное исправление.
Я решил это, указав "moduleResolution": "node"
в моем tsconfig. Не уверен, что этот вариант подходит вам, ребята, но, похоже, он помогает.
"moduleResolution": "node"
, к сожалению, не помог мне
@rossipedia Мне тоже.
Не поможет ли добавить export as namespace moment;
в файл moment.d.ts
?
@czb, который, к сожалению, не
Я решил это с помощью пары хаков, о которых другие упоминали, около тонны проблем во многих проектах, в которых есть эта проблема. Просто заверните его в свой собственный файл определения. Это использует Typescript 2.2. Таким образом, я не возьмусь за зависимость, исходящую от npmjs.org, и мне не нужно проверять все это в системе управления версиями.
tsconfig.json
"compilerOptions": {
"target": "ES5",
"moduleResolution": "node",
...
}
moment.custom.d.ts
import * as _moment from 'moment';
export as namespace moment;
export = _moment;
Мне любопытно, почему это не работает, когда этот код добавляется непосредственно в moment.d.ts
? Я не могу не думать, что мы сталкиваемся с какой-то неясной ошибкой разрешения TypeScript, и, к сожалению, tsc
не имеет подробного режима (о котором я знаю), который помог бы точно определить, где что-то идет не так.
Я думаю , что если вы определяете "module": "none"
машинописи не ищет d.ts
файлов под node_modules/moment
папки. По моему опыту, он просматривает только папку node_modules/@types
. Так что в основном есть эти варианты.
moment.d.ts
под node_modules/@types/moment
/// <reference path="./node_modules/moment/moment.d.ts" />
в свой .ts
файлtsc --typeRoots node_modules test.ts
./node_modules/moment/moment.d.ts
в files
раздел tsconfig.json
Вам также необходимо добавить export as namespace moment;
в файл moment.d.ts
.
команде Moment понравятся любые PR, которые исправят это, но оставайтесь совместимыми с TS 1.x.
Мне еще предстоит найти решение, которое вообще работает, но когда я найду, я обязательно добавлю PR
Согласно # 3663 временное исправление, чтобы заставить его работать без какого-либо сборщика ...
Скопируйте moment.d.ts
из node_modules/moment/
в node_modules/@types/moment
Измените export = moment;
в moment.d.ts
на
declare module "moment" {
export = moment;
}
moment.d.ts
в index.d.ts
Просто используйте момент и свой редактор (в моем случае vscode), и tsc не должен жаловаться
+1, пожалуйста, исправьте это
@mtgibbs Куда вы кладете файл moment.custom.d.ts? Требуется ли какая-либо другая конфигурация для вашего приложения, чтобы найти этот файл custom.d.ts?
@elSteeze
Да, я добавляю их в свои tsconfig.json
. Вот очищенный пример:
{
"compilerOptions": {
"target": "ES5",
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types"
]
},
"compileOnSave": true,
"exclude": [
"node_modules",
"./path/to/typings/**/*.d.ts",
"./typings"
],
"include": [
"./path/to/typings/moment.custom.d.ts",
"./path/to/src/**/*.ts"
]
}
@mtgibbs Привет, спасибо, чувак! Оцените быстрый ответ. Я попробую.
@mtgibbs Извините за еще один вопрос, подобный
'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead
Я провел небольшое личное исследование и попытался реализовать решение, переписав moment.custom.d.ts, но, к сожалению, это не устранило мою проблему.
Извините, я не пытаюсь быть одним из тех надоедливых разработчиков, которые заставляют всех остальных отлаживать свой код, я недавний выпускник и новичок в работе со сторонними библиотеками в среде Angular 2.
Вот мой обновленный module.custom.d.ts
declare var moment: any;
declare var module: NodeModule;
interface NodeModule {
id: string;
}
import * as _moment from 'moment';
export as namespace moment;
export = _moment;
Без проблем. Если вы используете Angular 2, у вас должно быть 2.0+ TS. Я не работаю в Angular, поэтому не уверен. Не забудьте вставить все, что вы можете, из своего tsconfig.json, и я посмотрю, когда вернусь к настоящему компьютеру.
Конечно!
Это весь мой файл tsconfig.es5.json в каталоге src моего модуля angular 2, который я создаю.
Кстати я ценю помощь
{
"compilerOptions": {
"declaration": true,
"module": "es2015",
"target": "es5",
"baseUrl": ".",
"stripInternal": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"outDir": "../build",
"rootDir": ".",
"lib": [
"es2015",
"dom"
],
"skipLibCheck": true,
"typeRoots": [
"./node_modules/@types"
]
},
"compileOnSave": true,
"exclude": [
"node_modules",
"./typings/**/*.d.ts",
"./typings"
],
"include": [
"./typings/moment.custom.d.ts",
"./src/**/*.ts"
],
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"skipTemplateCodegen": true,
"flatModuleOutFile": "new-version-library.js",
"flatModuleId": "new-version-library"
},
"files": [
"./index.ts"
]
}
В какой версии TS вы компилируете? Вы должны просто иметь возможность импортировать момент вверху без моего взлома.
@mtgibbs Я использую v2.2, и вот что я подумал. К сожалению, это не работает. Я почти нахожусь на том этапе, когда пишу свою собственную версию функциональности, которую мы берем от momentjs, потому что я не могу заставить это работать.
@elSteeze
Хорошо, возвращаюсь сюда. Я заметил, что вы сказали, что создали собственный module.custom.d.ts
, но затем вы ссылаетесь на мой moment.custom.d.ts
в своем tsconfig.json
. Убедитесь, что вы сделали moment.custom.d.ts
и добавили его в свой компилятор, и ничего лишнего, что вы декларировали. Затем убедитесь, что вы ссылаетесь на него в верхней части файла, в котором хотите его использовать.
/// <reference path="path/to/your/moment.custom.d.ts" />
Это должно позволить вам ссылаться на нее как на глобальную переменную, как в моем первоначальном обходном пути.
Отличное спасибо,
Я изменил свою файловую структуру, чтобы поддерживать ваши пути. Итак, это правильные пути.
Ура, дружище!
Это работает для меня:
// export = moment
в официальном файле moment.d.tsnode_modules/moment/moment.d.ts
в tsconfig.json
Или скопируйте измененный moment.d.ts
в любое место по вашему выбору и добавьте путь к нему в свой tsconfig.json
Я думаю, что основная проблема заключается в том, что при явном использовании "module":"none"
в tsconfig.json у вас не может быть импорта или экспорта верхнего уровня в каких-либо библиотеках (потому что тогда вы используете модули).
вы должны сначала импортировать компонент как
импорт * как момент с «момента»;
это сработало для меня
вы должны сначала импортировать компонент как
импорт * как момент с «момента»;
это сработало для меня
Если вы сделаете это в файле, то разрешение пространства имен для этих файлов будет отключено.
Пожалуйста, ребята +1, чтобы исправить это
Почему бы вам не исправить эту проблему? Это очень важно.
Добавление "module": "commonjs"
в tsconfig.json
исправило это для меня
Но мне нужно использовать "module": "none"
. Commonjs - это не решение.
Я использую TS 3.0.1, теперь это решено? По крайней мере, из коробки не работает.
РЕДАКТИРОВАТЬ , с TS 3.0.1 я мог бы сделать только это:
declare var moment: typeof import("moment");
Ура!
С tsconfig
{
"compilerOptions": {
"module": "none"
"moduleResolution": "node",
// ...
}
}
TS 3.0.1, похоже, решает эту проблему (и он был открыт уже более полутора лет без поддержки)
Привет, россия,
У меня такая же проблема в проекте angular-6. Согласно вашим комментариям, это разрешено в TS 3.0.1, но angular6 CLI не поддерживает TypeScript версии 3.0.1.
Не могли бы вы помочь решить эту проблему?
Встречался ли еще кто-нибудь с пакетом @types/moment
npm, который является просто заглушкой и предлагает вам использовать файл, предоставленный обычным пакетом moment?
... Почему момент должен делать это иначе, чем любой другой пакет? Это причина, по которой существует эта проблема, и разработчики потратили тысячи часов на ее решение.
Конечно, решение @Ciantic работает в TS 3.0.1, но мне не нужно использовать что-то вроде declare var moment: typeof import("moment");
для других пакетов, которые я использую.
Не похоже, что Typescript 3.0.1 исправит эту проблему, похоже, что это просто дает нам обходной путь.
похоже, это просто дает нам обходной путь.
Ага, именно так. Это неприемлемое «исправление».
Прошел всего день, и я только что понял, что обходной путь TS 3.0.1 импортирует только функцию moment
, а не пространство / типы имен. Итак, если вы хотите передать объект момента в функцию, произойдет следующее:
Пожалуйста, откройте эту проблему повторно или лучше: исправьте файл .dts.
Не решение исходной проблемы, но для людей, которые будут искать это позже: указание следующего в tsconfig.json исправило это (машинописный текст 3.3.3 и момент 2.24.0)
{
"compilerOptions": {
"module": "commonjs"
}
}
В последнее время я больше не использую момент, но я рад снова открыть проблему, если она все еще актуальна.
какое решение для этого ??
@nagipogu Для этого нет решения, это проблема для moment.js , пожалуйста, откройте ее в репозитории underscore.js на Github .
У меня проблема с последней версией момента с последней версией TS. Есть ли у кого-нибудь успешное обходное решение?
Все еще не работает, решение для меня было yarn add -W [email protected]
.
Когда я установил последнюю версию момента и заглянул в node_modules / moment / package.json, я увидел это: https://github.com/moment/moment/blob/develop/package.json#L29 - но существующего каталога не было node_modules/moment/ts3.1-typings
, так что неудивительно, что TS не смог его найти. Я думаю, что может быть какая-то ошибка с установочным скриптом (или пакетом) или около того. Да, у нас есть "module": "esnext"
в tsconfig.json.
Для меня это сломалось с 2.25.0:
Я использовал pnpm add [email protected] в качестве временного решения.
Для меня это сломалось с 2.25.0:
Я использовал pnpm add [email protected] в качестве временного решения.
хорошо работать, спасибо
Для меня это сломалось с 2.25.0:
Я использовал pnpm add [email protected] в качестве временного решения.
Здесь же он добавлен в: "dependencies" {"moment": "^ 2.24.0",
} ... вроде работает спасибо.
У меня тоже сработало понижение до 2.24.0. Похоже на регресс в 2.25.0.
2.25.3 устраняет ваши проблемы?
Существует так много разных ситуаций, в которых используется Moment.js, не говоря уже о TS 1.x, TS 2.x, TS 3.x ...
Я не решаюсь вносить изменения, которые нарушат работу какой-либо группы этих пользователей.
Если вы считаете, что документацию можно улучшить, отправьте сообщение на https://github.com/moment/momentjs.com/.
2.25.3 устраняет ваши проблемы?
да.
Откатился на 2.24.0, когда 2.25.1 у меня не удалось в Angular 9. С 2.25.3 он снова вернулся в нужное русло.
Ок, отлично. Я закрою пока.
Пожалуйста, повторно откройте (или откройте новый вопрос), если у вас все еще есть проблемы.
Самый полезный комментарий
+1, пожалуйста, исправьте это