Node.js 是一个开源和跨平台的运行时环境,也是一个非常流行的构建应用程序的工具。它运行在 V8 JavaScript 引擎上,这使得它具有高性能。它于 2009 年发布,从那时起它越来越受欢迎。优点之一是它使用 JavaScript 编程语言,这意味着服务器端和客户端应用程序可以使用相同的编程语言。在 Node.js 平台上运行的流行框架很少,最流行的是 Express。在本教程中,我将使用 Express 框架。
当 TypeScript 语言发布时,出现了巨大的积极变化。TypeScript 是一种基于 JavaScript 的语言,使用 TypeScript 的一些优点是:
- 类型检查。
- 在编写代码时更容易发现错误。
- 带有 IntelliSense 的非凡工具。
- TypeScript 支持接口。
- 完全支持 SOLID 原则。
将代码从 JavaScript 迁移到 TypeScript 并不难,我强烈建议在 Node.js 项目中使用 TypeScript。
创建一个快速项目。
我们将从一个新项目开始。使用命令初始化 npm:
npm init -y
上述命令将生成 npm 安装包所需的 package.json 文件。然后安装 Express 和 TypeScript 的依赖项。
npm install --save express
npm install --save-dev typescript ts-node @types/node @types/express
这些是使用 TypeScript 运行 Express 应用程序需要安装的所有依赖项。安装完成后 package.json 文件应该是这样的。
{
"name": "nodejs-typescript",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"@types/express": "^4.17.12",
"@types/node": "^15.6.2",
"ts-node": "^10.0.0",
"typescript": "^4.3.2"
}
}
为了运行 TypeScript 代码,还需要完成一个额外的步骤。Typescript 需要一个配置文件。我们需要创建一个名为 tsconfig.json 的文件,该文件将放置在根目录中。使用命令生成 tsconfig.json 文件:
npx tsc --init
将创建一个名为 tsconfig.json 的文件,其中包含 TypeScript 的配置。新创建的文件包含很多配置,但我们只考虑其中的一小部分。
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./",
"baseUrl": "./",
"esModuleInterop": true
}
}
target:指定项目中应该使用哪个 ECMAScript 版本。可用版本为 ES3(默认)、ES5、ES2015、ES2016、ES2017、ES2018、ES2019、ES2020 或 ESNEXT。
module:指定在生成的 JavaScript 代码中使用哪个模块管理器。可用选项包括 none、commonjs、amd、system、umd、es2015、es2020 或 ESNext。最常见的模块管理器和默认的模块管理器是 commonjs。
outDir:指定构建后输出 JavaScript 代码的位置。
rootDir:指定 TypeScript 文件所在的位置。
baseUrl:指定在应用程序中包含文件时的相对路径。
esModuleInterop:该选项默认为true;它控制 CommonJS 和 ES 模块之间的互操作性。它通过为所有导入创建命名空间对象来做到这一点。
创建应用程序文件
创建一个名为 src 的文件夹,其中将放置应用程序文件,然后在该文件夹内创建一个名为server.ts
. 文件server.ts
将是应用程序的起点。
import express from 'express';
import { Request, Response } from 'express';
const app = express();
app.get('/', (req: Request, res: Response) => {
res.send('Application works!');
});
app.listen(3000, () => {
console.log('Application started on port 3000!');
});
现在我们准备开始并构建我们的项目。我们将在 package.json 文件中添加用于启动和构建应用程序的脚本。将您的 package.json 脚本对象更改为如下所示:
"scripts": {
"start": "ts-node ./src/server.ts",
"start:prod": "npm run build && node ./dist/src/server.js",
"build": "npx tsc"
},
构建应用程序非常简单。我们需要运行命令npm run build
。TypeScript 将考虑 tsconfig.json 文件进行配置。之前我们设置"outDir": "./dist",
了配置,这意味着 TypeScript 将在 dist 文件夹中构建应用程序。
我们可以使用命令运行应用程序:
npm run start
或只是npm start
(发展)- npm run start:prod(生产)
启动应用程序后,我们可以http://localhost:3000
在任何浏览器中访问,除了我们看到Application works!
.
Nodemon
Nodemon 是一个被广泛使用的工具,它可以跟踪更改并自动重新启动应用程序。如果我们不使用 Nodemon,那么在每次更改之后,我们都必须停止应用程序并再次运行它。
我们可以使用以下命令安装 Nodemon:
npm install --save-dev nodemon
在根目录中创建 nodemon.json 配置文件。
{
"ignore": [".git", "node_modules", "dist"],
"watch": ["./src"], // <- files inside folder to watch
"exec": "npm start", // <- command that will be executed when nodemon starts
"ext": "ts" // <- files to watch
}
当然删除评论。在 package.json 脚本中为 nodemon 添加额外的脚本。
"start:nodemon": "./node_modules/nodemon/bin/nodemon.js",
现在我们可以使用 command 开始观察应用程序了npm run start:nodemon
。更改文件夹内的任何 TypeScript 文件后,应用程序将重新启动src
。
使用更漂亮的 ESLint
Eslint 是一个用于 JavaScript/TypeScript 的 linter,它可以在你的代码中发现问题。我无法想象不使用 ESLint 来编写 TypeScript 代码。以前我将 TSLint 用于 TypeScript,但现在它已被弃用,应该改用 ESLint。我推荐使用的附加包与 ESLint 一起使用更漂亮。
注意:Prettier 也可用于自动格式化您的代码(我更喜欢),但我们不会在本教程中介绍它。
安装依赖项:
npm install --save-dev eslint eslint-config-prettier eslint-plugin-prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier
ESLint 也使用配置文件。为此,在根目录中创建 .eslintrc.json 文件。我们可以根据需要安排规则。
{
"root": true,
"ignorePatterns": [],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json"],
"createDefaultProgram": true
},
"extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
"rules": {
"max-len": "off",
"no-underscore-dangle": "off",
"arrow-body-style": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/restrict-template-expressions": "warn",
"jsdoc/newline-after-description": "off"
}
}
]
}
如果我们需要忽略 ESLint 的任何文件夹/文件,则在根目录中添加 .eslintignore 文件并进行配置。出于演示目的,我添加了包含内容的文件。
/dist
现在 ESLint 将忽略 dist 文件夹中的所有文件。
我们还为 prettier 添加了插件,因此当 prettier 配置未格式化某些内容时,linter 会告诉我们。在根目录中添加.pretterrc
文件并根据您的需要进行调整。我的配置看起来像:
{
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 130
}
现在我们可以查看我们的代码中是否有任何错误/警告。如果需要,重新启动您的 IDE。
包起来
在本教程中,我们介绍了如何从头开始使用带有 TypeScript 语言的 Node.js 项目。我们还介绍了如何构建和运行应用程序。Nodemon 用于在代码发生更改时重新启动应用程序。最后,我们使用 ESLint 启用了 linter,并将其与 prettier 一起配置为我们的需求。
原文: https://dev.to/admirnisic/create-new-node-js-application-with-express-typescript-nodemon-and-eslint-f2l
补充: 使用babel在TypeScript中导入绝对路径
使用 Node 开发项目。当你看到类似的路径时../../../../../../models/post,你能猜出文件在哪里吗?
可以使用babel实现导入绝对路径 @/modes/post
安装
npm install @babel/cli @babel/core @babel/node @babel/preset-env @babel/preset-typescript babel-loader babel-plugin-module-resolver -save-dev
修改
package.json
这里有两种运行方式,第一种用tsc编译,第二种是用babel编译。tsc是微软官方typescript编绎器,语法上与babel略有差别。 比如这里的build就是使用babel编译器编译ts文件
"scripts": {
"dev": "nodemon",
"build": "babel src --out-dir dist --copy-files --extensions '.ts,.js'",
...
},
运行时输入 npm run dev/ yarn run dev 即可
nodemon.json
tsc编译器: 先用tsc将ts编译到dist目录,再通过babel-node再次编译js文件
{
"ignore": [".git", "node_modules", "dist"],
"watch": ["./src"],
"exec": "tsc && babel-node dist/app.js",
"ext": "ts"
}
babel编译器:只编译一次
{
"ignore": [".git", "node_modules", "dist"],
"watch": ["./src"],
"exec": "babel-node --extensions \".ts\" src/app.ts",
"ext": "ts"
}
.babelrc
使用babel编译器时,工作目录是src
{
"presets": [
"@babel/preset-typescript",
"@babel/preset-env"
],
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"@": "./src",
}
}]
],
}
使用tsc编译器时,"@babel/preset-typescript" 不需要引入,工作目录是dist
{
"presets": [
"@babel/preset-env"
],
"plugins": [
["module-resolver", {
"root": ["./dist"],
"alias": {
"@": "./dist",
}
}]
],
}
tsconfig.json
让vscode编译器能跳转到@/*的模块
{
"compilerOptions": {
"module": "ES2020", /* Specify what module code is generated. */
"rootDir": "./src", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
"paths": {
"@/*": [ "./*" ]
},
}
}
使用
@/ 就代表 src 文档夹,代码中可使用绝对路径import
import('@/home/home.controller');
import { app } from '@/app';