Ошибка машинописного текста TS2307: не удается найти модуль «реагировать» при попытке импорта без использования node.js?

Я новичок в 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.

Почему вы устанавливаете реакцию и реакцию-дом в качестве зависимостей разработки? Вы также можете попробовать добавить свойство types в свой файл tsconfig и конкретно перечислить модули типов react-dom и react в этом массиве.

Andrew 30.06.2024 21:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
1
97
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

для вашего файла 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?

Jordan Rieger 30.06.2024 21:00

нет-нет, не меняйте строку import *, чтобы объявить var. я сказал создать globals.d.ts и код ниже. объявить var React: typeof import('react'); объявить var ReactDOM: typeof import('react-dom');

ishaan 30.06.2024 21:03

Понятно, хорошо, я создал в корне файл global.d.ts с этими двумя строками, но запуск tsc все равно дает ту же ошибку. Сможете ли вы продублировать мое приложение и попробовать его в своей локальной среде, чтобы воспроизвести мою ошибку? (Это всего лишь три файла, которые я перечислил в своем вопросе.) Я не думаю, что вам нужен IIS. Любой веб-сервер подойдет.

Jordan Rieger 30.06.2024 21:14
Ответ принят как подходящий

Я решил проблему, установив реакции, реакции-дом и соответствующие пакеты @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: Спецификатор «реагировать» был пустым спецификатором, но не был переназначен ни на что. Спецификаторы относительных модулей должны начинаться с «./», «../» или «/»..

Поскольку эти ошибки отличаются от моего исходного вопроса, я отмечу этот ответ и рассмотрю возможность публикации нового вопроса, если не смогу их решить.

Другие вопросы по теме