Я делаю проект машинописного текста для кода javascript на стороне клиента.

До того, как я использовал typescript, я импортировал такой модуль (это vanilla js в es6).

import * as THREE from 'https://threejs.org/build/three.module.js';

Но с машинописным текстом я установил модуль с npm install, а затем импортировал его следующим образом

import * as THREE from 'three';

Проблема в том, что когда я затем запускаю скомпилированный код js, я получаю эту ошибку браузера js:

Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".

Так как import * as THREE from 'three'; теперь находится в скомпилированных файлах js.

Как я могу это исправить?

Благодарность

enter image description here

Tsconfig.json

{
    "compilerOptions": {
        "outDir": "dist/",
        "rootDir": "./src",
        "sourceMap": false,
        "noImplicitAny": true,
        "moduleResolution": "Node",
        "resolveJsonModule": true,
        "module": "ESNext",
        "target": "ESNext",
        "lib": [
            "ESNext", "DOM"
        ],
        "allowJs": false,
        "alwaysStrict": true,
        "typeRoots": [
            "node_modules/@types"
        ]
    },
    "include": [
        "src/",
        "src/**/*.json"
    ],
    "exclude": [

    ]
}
-1
omega 16 Янв 2022 в 03:11
Как выглядит структура вашего проекта? У вас есть package.json? tsconfig.json?
 – 
mowwwalker
16 Янв 2022 в 03:13
Как вы его составляете? Скорее всего, вам нужно скомпилировать И связать, так что ваш сборщик буквально свяжет зависимости NPM в скомпилированный код.
 – 
Terry
16 Янв 2022 в 03:14
Я добавил свою структуру проекта и tsconfig.
 – 
omega
16 Янв 2022 в 03:18
Можете ли вы включить свой package.json? Вам также следует попробовать перезапустить сервер ts stackoverflow. com/questions/64454845/…
 – 
mowwwalker
16 Янв 2022 в 03:46

3 ответа

Чтобы использовать это на стороне клиента, потребуется упаковщик.

Я предлагаю webpack или snowpack. Snowpack является новым и имеет много очень интересных функций.

0
Rxan 16 Янв 2022 в 04:59
Было бы хорошо, если бы вы объяснили, как использовать такой конструктор, как webpack, как он транспилирует TS в JS, который обслуживается клиентам. Некоторые ссылки также будут полезны. Спасибо.
 – 
Animir
16 Янв 2022 в 05:43

Это предполагает, что вы используете TypeScript для компиляции изолированных модулей ES, предназначенных для использования в браузере, загруженных в теги HTML, такие как <script type="module" src="myCompiledModule.js">. Судя по деталям вашего вопроса, похоже, что это так.

Хотя это и не совсем просто, сделать это относительно просто:

Чтобы удовлетворить компилятор, убедитесь, что вы установили и typescript, и @types/three:

npm install typescript @types/three

Затем добавьте в ./tsconfig.json:

{
  ...
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "https://threejs.org/build/three.module.js": ["node_modules/@types/three"]
    },
    ...
  },
  ...
}

Вот полная конфигурация, которую я использую для проверки:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "https://threejs.org/build/three.module.js": ["node_modules/@types/three"]
    },
    "esModuleInterop": true,
    "exactOptionalPropertyTypes": true,
    "isolatedModules": true,
    "lib": [
      "esnext",
      "dom",
      "dom.iterable"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noUncheckedIndexedAccess": true,
    "outDir": "dist",
    "strict": true,
    "target": "esnext",
    "useUnknownInCatchVariables": true
  },
  "include": [
    "./src/**/*"
  ]
}

Теперь у вас будут правильные типы для THREE в модулях, куда он импортируется с помощью спецификатора "https://threejs.org/build/three.module.js". Например, когда я набираю THREE.Mesh, TypeScript IntelliSense показывает мне, что это такой тип:

class Mesh<TGeometry extends THREE.BufferGeometry = THREE.BufferGeometry, TMaterial extends THREE.Material | THREE.Material[] = THREE.Material | THREE.Material[]>

Вот пример модуля в моем тесте:

./src/index.ts:

import * as THREE from 'https://threejs.org/build/three.module.js';
console.log(THREE);

Теперь, когда вы скомпилируете свой проект с помощью tsc, вы получите этот вывод, который является допустимым модулем ECMAScript и будет использовать модуль «три», импортированный из размещенного URL-адреса:

./dist/index.js:

import * as THREE from 'https://threejs.org/build/three.module.js';
console.log(THREE);

0
jsejcksn 16 Янв 2022 в 10:58

Пакет, установленный с NPM, обычно находится в папке node_modules. Это означает, что вы можете получить доступ к библиотеке по ее относительному пути:

import * as THREE from './node_modules/tree/build/three.module.js';
-2
Nicolas 16 Янв 2022 в 03:18
Но папка node_modules не отображается со стороны клиента. Его нет в папке dist.
 – 
omega
16 Янв 2022 в 03:19
Тогда вам понадобится упаковщик, например webpack. Упаковщик скомпилирует все необходимые зависимости в один файл, который затем можно будет импортировать в ваш html, как и любой другой файл javascript. Webpack очень популярен, и по нему есть множество руководств. Удачи !
 – 
Nicolas
16 Янв 2022 в 03:21
Для веб-пакета я уже могу скомпилировать с помощью tsc, так какова цель ts-loader?
 – 
omega
16 Янв 2022 в 03:24
tsc скомпилирует отдельные файлы из TS в JS. ts-loader позволит вам импортировать ts-файл в ts, а затем скомпилировать их все в один файл.
 – 
Nicolas
16 Янв 2022 в 03:26