【问题标题】:How to include modules in client side in typescript projects?如何在打字稿项目中包含客户端的模块?
【发布时间】:2022-01-16 00:11:09
【问题描述】:

我正在为客户端 javascript 代码制作一个打字稿项目。

在我使用 typescript 之前,我导入了一个这样的模块(这是 es6 中的 vanilla js)

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 文件中。

我该如何解决这个问题?

谢谢

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": [

    ]
}

【问题讨论】:

  • 您的项目结构是什么样的?你有 package.json 吗?一个 tsconfig.json?
  • 你是怎么编译的?很有可能,您需要编译 AND 捆绑,以便您的捆绑器将 NPM 依赖项捆绑到已编译的代码中。
  • 我已经添加了我的项目结构和tsconfig。
  • 你能包含你的 package.json 吗?您还应该尝试重新启动 ts 服务器 stackoverflow.com/questions/64454845/…

标签: javascript node.js typescript npm


【解决方案1】:

这假设您正在使用 TypeScript 编译注定要在浏览器中使用的隔离 ES 模块,加载在 HTML 标记中,例如 <script type="module" src="myCompiledModule.js">。从您的问题详细信息来看,情况似乎是这样。

虽然不完全简单,但实现起来相对简单:

为了让编译器满意,请确保你已经安装了typescript@types/three

npm install typescript @types/three

然后,将此path mapping 添加到您的./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/**/*"
  ]
}

现在,您将在使用说明符 "https://threejs.org/build/three.module.js" 导入的模块中拥有正确的 THREE 类型。例如,当我输入 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);

【讨论】:

    【解决方案2】:

    为了在客户端使用它,需要一个捆绑器。

    我建议使用 webpack 或 snowpack。 Snowpack 是新的,具有许多非常酷的功能。

    【讨论】:

    • 如果你能解释一下,如何使用像 webpack 这样的构建器,它如何将 TS 转换为 JS,然后提供给客户端,那就太好了。一些链接也会有所帮助。谢谢。
    【解决方案3】:

    使用 NPM 安装的包通常位于 node_modules 文件夹中。这意味着您可以通过它的相对路径访问该库:

    import * as THREE from './node_modules/tree/build/three.module.js';
    

    【讨论】:

    • node_modules 文件夹并未从客户端公开。它不在dist 文件夹中。
    • 那么你需要一个打包工具,比如 webpack。捆绑器会将所有必需的依赖项编译到一个文件中,然后可以将其导入到您的 html 中,就像任何其他 javascript 文件一样。 Webpack 是一个非常流行的,并且有很多关于它的教程。祝你好运!
    • 对于webpack,我已经可以使用tsc编译了,那么ts-loader的用途是什么?
    • tsc 会将单个文件从 TS 编译为 JS。 ts-loader 将允许您将 ts 文件导入 ts,然后将它们全部编译到一个文件中。
    猜你喜欢
    • 2020-01-31
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2016-05-06
    相关资源
    最近更新 更多