Я новичок в React и TypeScript и пытаюсь создать самый минимальный пример приложения, которое можно скомпилировать и разместить на чистом веб-сервере разработки IIS. Я сталкиваюсь с этой ошибкой при компиляции с помощью команды tsc:
PS C:\inetpub\wwwroot\TypeScriptReactTest> tsc
test.ts:1:24 — ошибка TS2307: невозможно найти модуль «реагировать» или соответствующие ему объявления типов.
1 импорт * как React из «реагировать»;
Я использую TypeScript 5.5.2 и React+ReactDOM 18.2. Сценарии реагирования загружаются в мой HTML через CDN, а не на локальную ссылку. (Мне нужно, чтобы подход CDN работал, поскольку мы оцениваем переход новой разработки на React, поэтому производительность является проблемой, и все распространенные библиотеки необходимо загружать через CDN, если это возможно.)
В моем приложении есть только эти 3 файла:
тест.ц:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
const sHelloPrefix: string = "Hello,";
class HelloComponent extends React.Component {
render() {
return React.createElement("div", null, `${sHelloPrefix} ${this.props.toWhat}`);
}
}
document.addEventListener("DOMContentLoaded", () => {
const oReactRoot = ReactDOM.createRoot(document.getElementById("app"));
oReactRoot.render(React.createElement(HelloComponent, {toWhat: "World! (from TS)"}));
});
тест.html:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title>TypeScript/React test</title>
</head>
<body>
<div id = "app"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js" integrity = "sha512-m7nhpWHotpucPI37I4lPovL28Bm2BhAMV8poF3F8Z9oOEZ3jlxGzkgvG0EMt1mVL1xydr1erlBbmN90js/ssUw= = " crossorigin = "anonymous" referrerpolicy = "no-referrer"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js" integrity = "sha512-I5GJQRKGdj2miDs8ComgARfiAQiZJo/43YasH22qtweoG+YRXLTDYegxC/vPgw/ERxRzww/F4l4+8UiMmI20sw= = " crossorigin = "anonymous" referrerpolicy = "no-referrer"></script>
<script src = "test.js"></script>
</body>
</html>
tsconfig.json:
{
"compilerOptions": {
"target": "es2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noEmitOnError": true
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.js"
]
}
Вещи, которые я пробовал:
Я установил аналогичное приложение по адресу https://jsfiddle.net/noj206zp/2/ оно работает, но я не понимаю почему. Он не импортирует React нигде в файле .ts, поэтому я думаю, что JSFiddle творит какую-то магию в фоновом режиме, чего я не делаю в своем локальном приложении IIS.
для вашего файла tsconfig попробуйте ниже:
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "react",
"noEmitOnError": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": [
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules",
"**/*.js"
]
}
если вышеперечисленное не работает, добавьте - globals.d.ts в корневом каталоге (это объявляет React и ReactDOM как глобальные переменные)
declare var React: typeof import('react');
declare var ReactDOM: typeof import('react-dom');
затем запустите tsc для компиляции файла, а также убедитесь, что ваш test.html правильно включает скомпилированный файл JavaScript. Думаю, это должно сработать, дайте мне знать!
Переход на предоставленный tsconfig.json не сработал. (Получена та же ошибка при запуске tsc.) Также не помогло изменение моих строк «import *» на предоставленные вами строки «declare var». Можете ли вы объяснить, где я могу взять упомянутый вами файл global.d.ts?
нет-нет, не меняйте строку import *, чтобы объявить var. я сказал создать globals.d.ts и код ниже. объявить var React: typeof import('react'); объявить var ReactDOM: typeof import('react-dom');
Понятно, хорошо, я создал в корне файл global.d.ts с этими двумя строками, но запуск tsc все равно дает ту же ошибку. Сможете ли вы продублировать мое приложение и попробовать его в своей локальной среде, чтобы воспроизвести мою ошибку? (Это всего лишь три файла, которые я перечислил в своем вопросе.) Я не думаю, что вам нужен IIS. Любой веб-сервер подойдет.
Я решил проблему, установив реакции, реакции-дом и соответствующие пакеты @types для каждого из них в корне проекта с помощью npm. Затем я сократил файл tsconfig.json до минимума, необходимого для успешной компиляции. По какой-то причине мне также пришлось удалить элемент {props.toWhat}, но я думаю, что это не связано:
npm install [email protected]
npm install [email protected]
npm install @types/[email protected]
npm install @types/[email protected]
test.ts
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
const sHelloPrefix: string = "Hello,";
class HelloComponent extends React.Component {
render() {
return React.createElement("div", null, `${sHelloPrefix} World`);
}
}
document.addEventListener("DOMContentLoaded", () => {
const oReactRoot = ReactDOM.createRoot(document.getElementById("app")!);
oReactRoot.render(React.createElement(HelloComponent, null));
});
тест.html:
Никаких изменений, как и в вопросе выше.
tsconfig.json:
{
"compilerOptions": {
"target": "es2020",
"moduleResolution": "node",
"strict": true,
"noEmitOnError": true
},
"include": [
"**/*.ts"
]
}
TypeScript теперь успешно компилирует test.ts в test.js. Но теперь у меня другая ошибка. Мой браузер выдает «Uncaught SyntaxError: объявления импорта могут появляться только на верхнем уровне модуля» при загрузке страницы. Я думаю, это потому, что TypeScript предполагает, что мое приложение будет работать в среде, поддерживающей модули, но браузеру это не нравится. Добавление type="module" к тегу устраняет эту ошибку, но вызывает новую: Uncaught TypeError: Спецификатор «реагировать» был пустым спецификатором, но не был переназначен ни на что. Спецификаторы относительных модулей должны начинаться с «./», «../» или «/»..
Поскольку эти ошибки отличаются от моего исходного вопроса, я отмечу этот ответ и рассмотрю возможность публикации нового вопроса, если не смогу их решить.
Почему вы устанавливаете реакцию и реакцию-дом в качестве зависимостей разработки? Вы также можете попробовать добавить свойство
types
в свой файлtsconfig
и конкретно перечислить модули типовreact-dom
иreact
в этом массиве.