目录

一拳搞定 Node.js | 如何运行一个 node 项目

本文介绍如何在本地启动 nodejs 项目。

一、前言

最近要搭建自动化运维平台,前后端的生杀大权都随自己定,前端的技术选型了蚂蚁的 ant design pro,于是乎把折腾过的 nodereact 的相关知识记录下。

注意:

  • 本文需要读者具备基础的编程能力以及对计算机网络的基本了解,一些常用术语限于篇幅不再展开。
  • 本文基于 mac 系统开发,如果 win 下有不一致的情况请自行对照相关命令。

二、准备环境

2.1、安装 Node.js

Node.js 发布版本分为 Current 和 LTS 两类,前者每 6 个月迭代一个大版本,快速提供新增功能和问题修复,后者以 30 个月为一个大周期,为生产环境提供稳定依赖。当前 Node.js 最新 LTS 版本为 12.18.2,本文以此版本作为运行环境,可以在官网下载并安装。

安装完成后,在命令行输入 node --version 查看输出是否为 v12.8.2,如果一致,那么安装成功。

另外,有兴趣的读者可以尝试通过 nvm / nvm-windows 管理多个 Node.js 版本,此处不是本文重点不再展开。

我本机的版本:

1$ node -v
2v12.18.2

三、创建 node 项目

3.1 初始化工程

3.1.1 创建并进入项目目录

1mkdir node-sample && cd node-sample

3.1.2 初始化 package.json

 1$ npm init
 2This utility will walk you through creating a package.json file.
 3It only covers the most common items, and tries to guess sensible defaults.
 4
 5See `npm help init` for definitive documentation on these fields
 6and exactly what they do.
 7
 8Use `npm install <pkg>` afterwards to install a package and
 9save it as a dependency in the package.json file.
10
11Press ^C at any time to quit.
12package name: (sample) demo
13version: (1.0.0) 0.1.0
14description: demo node
15entry point: (index.js)
16test command:
17git repository:
18keywords:
19author:
20license: (ISC)
21About to write to /Users/tc/Documents/workspace_2020/node-sample/package.json:
22
23{
24  "name": "demo",
25  "version": "0.1.0",
26  "description": "demo node",
27  "main": "index.js",
28  "scripts": {
29    "test": "echo \"Error: no test specified\" && exit 1"
30  },
31  "author": "",
32  "license": "ISC"
33}
34
35
36Is this OK? (yes) yes

查看生成的文件或目录

1$ ls
2node_modules            package-lock.json       package.json

3.1.3 使用 express

安装 express

1 npm install express

创建目录和文件

1mkdir src
2touch src/server.js

编写 server.js

 1const express = require('express')
 2const app = express()
 3const port = 3000
 4
 5app.get('/', (req, res) => {
 6  res.send('Hello World!')
 7})
 8
 9app.listen(port, () => {
10  console.log(`Example app listening at http://localhost:${port}`)
11})

3.1.4 启动服务

启动

1$ node src/server.js
2Example app listening at http://localhost:3000

请求

请求

停止服务

1control + c

端口是否在使用

1$ lsof -i:3000

3.2、静态资源服务器

3.2.1 创建目录和文件

创建 public 文件夹

1mkdir src

创建 HTML 文件

1touch src/index.html

查看目录

1$ tree -L 1
2.
3├── index.js
4├── node_modules
5├── package-lock.json
6├── package.json
7├── public
8└── src

3.2.2 编写 index.html

1<!doctype html>
2  <html>
3    <head>
4      <meta charset="utf-8" />
5    </head>
6    <body>
7      <h1>It works!</h1>
8    </body>
9  </html>

3.2.3 编写 server.js

 1const express = require('express')
 2const { resolve } = require('path');
 3const { promisify } = require('util');
 4
 5const app = express()
 6const port = parseInt(process.env.PORT || '3000');
 7const publicDir = resolve('public');
 8
 9async function bootstrap() {
10  app.use(express.static(publicDir))
11  await promisify(app.listen.bind(app, port))();
12  console.log(`> Started on port http://localhost:${port}`);
13}
14
15bootstrap();

3.2.4 启动服务

启动

1npm start
2
3> demo@0.1.0 start /Users/tc/Documents/workspace_2020/node-sample
4> node src/server.js
5
6> Started on port http://localhost:3000

请求

请求

四、碰到问题

4.1 端口被占用

配置好 package.json 的 start script 后,启动项目。

 1npm start
 2
 3> demo@0.1.0 start /Users/tc/Documents/workspace_2020/node-sample
 4> node src/server.js
 5
 6events.js:292
 7      throw er; // Unhandled 'error' event
 8      ^
 9
10Error: listen EADDRINUSE: address already in use :::3000
11    at Server.setupListenHandle [as _listen2] (net.js:1313:16)
12    at listenInCluster (net.js:1361:12)
13    at Server.listen (net.js:1447:7)
14    at Function.listen (/Users/tc/Documents/workspace_2020/node-sample/node_modules/express/lib/application.js:618:24)
15    at internal/util.js:297:30
16    at new Promise (<anonymous>)
17    at bound listen (internal/util.js:296:12)
18    at bootstrap (/Users/tc/Documents/workspace_2020/node-sample/src/server.js:15:46)
19    at Object.<anonymous> (/Users/tc/Documents/workspace_2020/node-sample/src/server.js:19:1)
20    at Module._compile (internal/modules/cjs/loader.js:1138:30)
21Emitted 'error' event on Server instance at:
22    at emitErrorNT (net.js:1340:8)
23    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
24  code: 'EADDRINUSE',
25  errno: 'EADDRINUSE',
26  syscall: 'listen',
27  address: '::',
28  port: 3000
29}
30npm ERR! code ELIFECYCLE
31npm ERR! errno 1
32npm ERR! demo@0.1.0 start: `node src/server.js`
33npm ERR! Exit status 1
34npm ERR!
35npm ERR! Failed at the demo@0.1.0 start script.
36npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
37
38npm ERR! A complete log of this run can be found in:
39npm ERR!     /Users/tc/.npm/_logs/2020-11-10T02_13_36_826Z-debug.log

可以看到错误日志的日志文件位置和错误信息,地址已经被占用。

五、参考

https://expressjs.com/en/starter/hello-world.html

https://segmentfault.com/a/1190000023311123