# 安装（[name]）

你可以使用[link:https://www.npmjs.com/ npm]以及现代构建工具来安装 three.js ，也可以只需静态主机或是 CDN 来快速上手。对于大多数用户来说，从 npm 安装是最佳选择。

无论你选择哪种方式，请始终保持一致，并注意从相同版本的库中导入所有文件。混合不同来源的文件可能会导致包含重复代码，甚至会以意料之外的方式破坏应用程序，

所有安装 three.js 的方式都依赖于 ES modules（参见 [link:https://eloquentjavascript.net/10_modules.html#h_hF2FmOVxw7 Eloquent JavaScript: ECMAScript Modules]）。ES modules使你能够在最终项目中包含所需库的一小部分。

## 安装自 npm

要安装[link:https://www.npmjs.com/package/three three] 的 npm 模块，请在你的项目文件夹里打开终端窗口，并运行：

`npm install three`

包将会被下载并安装。然后你就可以将它导入你的代码了：

`// 方式 1: 导入整个 three.js核心库 import * as THREE from 'three'; const scene = new THREE.Scene(); // 方式 2: 仅导入你所需要的部分 import { Scene } from 'three'; const scene = new Scene();`

从npm上进行安装的时候，几乎总是使用某种构建工具（[link:https://eloquentjavascript.net/10_modules.html#h_zWTXAU93DC bundling tool]）来将你项目中需要的所有包组合到一个独立的JavaScript软件中。虽然任何现代的 JavaScript 打包器都可以和 three.js 一起使用，但最流行的选择是 [link:https://webpack.js.org/ webpack] 。

并非所有功能都可以通过 three 模块来直接访问（也称为“裸导入”）。three.js 中其它较为流行的部分 —— 如控制器（control）、加载器（loader）以及后期处理效果（post-processing effect） —— 必须从 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 子目录下导入。了解更多信息，请参阅下方的示例。

你可以从 [link:https://eloquentjavascript.net/20_node.html#h_J6hW/SmL/a Eloquent JavaScript: Installing with npm] 来了解更多有关 npm 模块的信息。

## 从CDN或静态主机安装

通过将文件上传到你自己的服务器，或是使用一个已存在的CDN，three.js 便可以不借助任何构建系统来进行使用。由于 three.js 依赖于ES module，因此任何引用它的script标签必须使用type="module"。如下所示：

`<script type="module"> // 通过访问 https://cdn.skypack.dev/three 来查找最新版本。 import * as THREE from 'https://cdn.skypack.dev/three@<version>'; const scene = new THREE.Scene(); </script>`

## 示例

three.js的核心专注于3D引擎最重要的组件。其它很多有用的组件 —— 如控制器（control）、加载器（loader）以及后期处理效果（post-processing effect） —— 是 [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 目录的一部分。它们被称为“示例”，虽然你可以直接将它们拿来使用，但它们也需要重新混合以及定制。这些组件和 three.js 的核心保持同步，而 npm 上类似的第三方包则由不同的作者进行维护，可能不是最新的。

示例无需被单独地安装，但需要被单独地导入。如果 three.js 是使用 npm 来安装的，你可以使用如下代码来加载轨道控制器（[page:OrbitControls]）：

`import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement );`

如果 three.js 安装自一个 CDN ，请使用相同的 CDN 来安装其他组件：

`<script type="module"> // 通过访问 https://cdn.skypack.dev/three 来查找最新版本。 import { OrbitControls } from 'https://cdn.skypack.dev/three@<version>/examples/jsm/controls/OrbitControls.js'; const controls = new OrbitControls( camera, renderer.domElement ); </script>`

所有文件使用相同版本是十分重要的。请勿从不同版本导入不同的示例，也不要使用与 three.js 本身版本不一致的示例。

## 兼容性

### CommonJS 导入

虽然现代的 JavaScript 打包器已经默认支持ES module，然而也有一些较旧的构建工具并不支持。对于这些情况，你或许可以对这些打包器进行配置，让它们能够理解 ES module 。例如，[link:http://browserify.org/ Browserify] 仅需 [link:https://github.com/babel/babelify babelify] 插件。

### Import maps

和从静态主机或CDN来进行安装的方式相比，从npm安装时，导入的路径有所不同。我们意识到，对于使用两种不同方式的用户群体来说，这是一个人体工程学问题。使用构建工具与打包器的开发者更喜欢仅使用单独的包说明符（如'three'）而非相对路径，而examples/目录中的文件使用相对于 three.module.js 的引用并不符合这一期望。对于不使用构建工具的人（用于快速原型、学习或个人参考）来说，或许也会很反感这些相对导入。这些相对导入需要确定目录结构，并且比全局 THREE.* 命名空间更不宽容。

我们希望在 [link:https://github.com/WICG/import-maps import maps] 广泛可用时，能够移除这些相对路径，将它们替换为单独的包说明符，'three'。这更加符合构建工具对npm包的期望，且使得两种用户群体在导入文件时能够编写完全相同的代码。对于更偏向于避免使用构建工具的用户来说，一个简单的 JSON 映射即可将所有的导入都定向到一个 CDN 或是静态文件夹。通过实验，目前你可以通过一个 import map 的 polyfill，来尝试更简洁的导入，如 [link:https://glitch.com/edit/#!/three-import-map?path=index.html import map example] 示例中所示。

### Node.js

Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.