介绍

由于我经常使用 React,所以我在前端接触过 Node.js,但我从未接触过后端。
正常搭建环境的时候,不能使用import语句,变成了require语句,很不方便。
我认为有各种各样的错误,所以如果你能指出它们,我将不胜感激。

执行环境

macOS 蒙特雷 ver12.5.1
MacBook Air(M1,2020)

安装包

首先确保您安装了 Node.js。
如果你想用 Docker 搭建环境,进入容器并执行命令。

终端
node -v
v16.10.0

初始化项目。
你会被问到很多问题,但目前一切都很好。

终端
npm init

确保它看起来像这样:

包.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

安装软件包。
这次我会用yarn,不过npm也可以。
首先,安装typescript
您只需要一个开发环境,所以将其添加到devDependencies

终端
yarn add -D typescript
or
npm install --save-dev typescript

接下来,安装 Node.js 类型定义。
有一个开发环境也很好。
由于 Node.js 主体中没有类型定义,因此除非包含它,否则不会发生类型推断。

终端
yarn add -D @types/node
or
npm install --save-dev @types/node

然后安装ts-node
默认情况下,Node.js 只能运行 JavaScript,不能运行 TypeScript。
通过使用ts-node,您可以直接运行 TypeScript。
查看官方存储库,它是node 命令和tsc 命令的包装器吗?

终端
yarn add -D ts-node
or
npm install --save-dev ts-node

如果您已经完成了这一步,package.json 应该如下所示:

包.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@types/node": "^18.7.14",
    "ts-node": "^10.9.1",
    "typescript": "^4.8.2"
  },
  "author": "",
  "license": "ISC"
}

试着移动

我将编写一个脚本来设置一个简单的服务器。
访问http://localhost:8080 时返回hello world 的服务器。
创建index.ts 并编写以下代码。

索引.ts
import http from "http";

const server = http.createServer((req, res) => {
  res.writeHead(200);
  res.end("hello world");
});

server.listen(8080);

我想让你在这里检查的是类型推断是否有效,因为你已经安装了@types/node
下图是您将鼠标悬停在 http.createServer 上时的样子。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

让我们运行它。
ts-node 安装在本地,不在全局路径中,所以我们使用运行本地包的npx
yarn好像也有类似的功能,但是好像用的不多。我一直无法找到关于这个地区的太多信息。

终端
npx ts-node index.ts

让我们在浏览器中打开它。显示出来了。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

让我们做一个从另一个 ts 文件导入并执行它的测试。
首先,创建sum.ts 并编写以下代码。

sum.ts
const sum = (a: number, b: number) => {
  return a + b;
};

console.log(sum(1, 2));

让我们在导入之前运行它。
我认为它正在工作。

终端
npx ts-node sum.ts
3

让我们导入它并使用它。

索引.ts
import http from "http";
import { sum } from "./sum";

const server = http.createServer((req, res) => {
  const three = sum(1, 2);
  res.writeHead(200);
  res.end(three.toString());
});

server.listen(8080);
终端
npx ts-node index.ts

如果您在浏览器中查看它,您应该能够看到它。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

ESModule 整个项目

正如您目前所看到的,您可以使用 import 语句,所以我认为没有问题。
我从这里猜测,但似乎ts-node 在执行之前将ESModule 格式转换为CommonJS 格式并执行它。
用下面文章的话来说,我们目前使用的是伪 ESModule。

当前状态的问题是无法读取以 ESModule 为前提制作的包。请参阅下面的参考文章。

因此,我想对整个项目进行 ESModule。
我们将参考 TypeScript Docs。

首先创建tsconfig.json

终端
npx tsc -init

根据公式进行设置。

tsconfig.json
{
    "compilerOptions": {
        "module": "nodenext",
    }
}
包.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^18.7.18",
    "ts-node": "^10.9.1",
    "typescript": "^4.8.3"
  },
  "type": "module"
}

对了,在输入package.jsontype的时候,VSCode里出来了下面的补充。
这是笨拙和意译,但它是这样的。
换句话说,我觉得它直到现在都是作为 CommonJS 执行的。

将 type 值设置为 module 将导致包将所有 js 文件视为 ESModules。
如果省略type值或者commonjs,则所有的js文件都被认为是CommonJS。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

此外,TypeScript Docs 指出:

相对导入路径必须有一个完整的扩展名(例如 import "./foo.js" 应该写而不是 import "./foo")。

当我去查看index.ts 时,我收到这样的错误。
需要注意的是,要导入的文件的扩展名必须指定为js。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

js修复了错误。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

我想到目前为止我组织它时可能会是这样。

  • Node.js 通过将 package.json 设置为 type: module 来原生支持 ESM。

  • 但是Node.js不能直接运行typescript,所以我在tsconfig.json中设置编译成ESModule。

让我们检查一下操作。

终端
npx ts-node index.ts

我有一个错误。 ts-node 似乎无法读取 ESModule 格式。

终端
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for 〜以下省略〜

参考ts-node公式,改成这样。

终端
node --loader ts-node/esm ./index.ts

我能够在浏览器中确认操作。

ESModuleかつTypeScriptでNode.jsの環境構築を行う

但是,正如下面的官方描述所述,它是一个实验性功能,似乎在产品版本中已被弃用。
也许你应该运行tsc && node index.js 或类似的东西。

Node 的 ESM 加载器挂钩是实验性的,可能会发生变化。 ts-node 的 ESM 支持尽可能稳定,但依赖于可能会在较新版本的节点中中断的 API。因此,不建议用于生产。

综上所述

我只想要前端熟悉的导入和类型推断,但是花了很多时间和精力。
Node.js 的创建者正在开发一个名为 Deno 的 JS 运行时,它似乎在本地支持 TypeScript 和 ESModule,利用了从 Node.js 中吸取的教训。
不过,考虑到各种库的支持,Node.js 的霸主地位似乎还要持续一段时间。

参考


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308626538.html

相关文章: