编程崽

登录

一叶在编程苦海沉沦的扁舟之上,我是那只激情自射的崽

Node 开发环境配置

Node 开发环境配置

nodemon文档:https://github.com/remy/nodemon

Babel文档:https://babeljs.io/docs/en/

前端开发流行的 react 和 vue,因为脚手架的存在,可以直接使用 ES6语法,修改文件后页面还自动热更新,非常嗨皮。

而刚刚进行 node 开发时,基本上手就写,没有了脚手架,没有了编译服务,ES6 的 import/export 模块化引入的写法也不能用,写完代码保存后服务也不会自动热更新,非常不方便。

下面就开始使用工具来解决。

Node对ES6的支持和ES模块化导入的支持

在我看来,Node 几乎完全的支持ES6的语法和功能了。

此外,Node 默认使用的导入导出形式是 CommonJS,默认是不支持ES模块化导入的,也就是不支持 import/export 的写法,但也可以原生支持。

方式一:(推荐)在 package.json 中添加 "type": "module"

如题,在 package.json 中添加 "type": "module" 后,此项目的导入导出方式变为 ES 的 import/export 的形式,且无法再使用 CommonJS 写法了。

并且,导入 js 文件时,需要把路径写全,包括后缀名,必须和浏览器引入一个 js 时一样,这是唯一的缺点。

方式二:把 .js 格式后缀名改为 .cjs 或 .mjs

可以不添加 "type": "module",而是修改所有 js 文件的后缀名,且引入文件时也需要写全后缀名。

当后缀名是 .cjs 时,node 系统会认为此文件是 CommonJS 的模块文件。

当后缀名是 .mjs 时,node 系统会认为此文件是 ES 的模块文件。

优先级高于 "type": "module"

使用 nodemon 来支持热更新

nodemon文档:https://github.com/remy/nodemon

1. 安装 nodemon

sh 复制代码
npm i -D nodemon

2. 修改 package.json 中的指令

diff 复制代码
{
  "scripts": {
-    "start": "node ./bin/www.js"
+    "dev": "nodemon ./bin/www.js"
  }
}

之后,启动程序的指令改为 npm run dev,此服务支持热更新,./bin/www.js 和这个文件引入的文件,一旦发生修改并保存,就会直接自动重启服务。

使用 Babel

Babel文档:https://babeljs.io/docs/en/

其实平时使用,node 几乎已经不再需要 Babel 了,但也可以用。

使用 Babel 后有几个好处:

  1. 使用最新的 ES 语法,这个倒没有太大必要,常用的新语法 node 已经支持的足够了。
  2. 可以不用再在 package.json 中添加 "type": "module" 来让node 支持 ES 的模块化,且使用 ES 模块化引入 js 时,不用再连后缀名也写全了。

1. 安装 babel 相关的依赖(4个)。

sh 复制代码
npm i -D @babel/cli @babel/core @babel/node @babel/preset-env

2. 添加 babel 配置文件

在项目根目录,也就是 package.json 的同级目录,创建文件 .babelrc,内容如下:

json 复制代码
{
  "presets": [
    ["@babel/preset-env", {"targets": {
      // 编译后需要支持的 node 版本,类型:string | "current" | true
      // 此处建议填写具体某个 node 版本的次版本号
      // https://babeljs.io/docs/en/options#targets
      "node": "14.0"
    }}]
  ]
}

这个配置是指 babel 在编译时,要使用 @babel/preset-env 这个配置,要转译为 node 的语法。

如果没有这个 babel 的配置文件,你就会发现即使使用 babel 处理了代码,代码实际一点变化也没有,不会被编译。

3. 修改启动文件格式和启动指令

比如我们本来要启动的文件是 ./bin/www,那需要先把 ./bin/www 文件更名为 ./bin/www.js

然后修改 package.json 文件中的启动指令:

diff 复制代码
{
  "scripts": {
-    "start": "node ./bin/www"
+    "dev": "babel-node ./bin/www.js"
-    如果使用了 nodemon,则使用下面这条
+    "dev": "nodemon --exec babel-node ./bin/www.js"
  }
}

之后使用 npm dev 指令启动 node 服务后,./bin/www.js 和所有这个文件引入的 js 文件中,都可以使用 ES6 的功能和语法,babel-node 都会自动转译为 node 支持的语法再执行。

注意:babel-node 只适用于开发时,上线后需要先编译出文件后再启动,这个后面解决。

此外,如果没有使用 nodemon,那么当我们修改文件后,我们仍然需要重新 npm run dev。

线上环境需要先使用 babel 编译

上面说 babel-node 只适用于开发时,下面就说明一下线上环境时如何操作。

在 package.json 文件中添加编译指令

diff 复制代码
{
  "scripts": {
+    "start": "node ./dist/bin/www.js",
+    "build": "rm -rf ./dist && babel ./bin -d dist/bin && babel ./src -d dist/src --copy-files",
    "dev": "nodemon --exec babel-node ./bin/www.js",
  }
}

build 指令中,-d 是 --out-dir 的缩写,是设定编译的导出目录

--copy-files 是指,遇到不支持的文件类型,直接原样复制倒目标目录,比如 json 类型的文件,如果没有这个参数,json 文件会因为不被读取而丢失。

上面的 build 指令,就是使用 babel 把项目整个编译输出为文件,放在 ./dist 文件夹中。

start 指令则是正常使用 node 启动编译后的文件。

最好也把 dist 文件夹添加到 .gitignore 文件中。

之后如果需要上线,需要:

  1. 把项目提交并推送。
  2. 在服务器拉取项目,进入到项目文件夹,执行 npm install 更新依赖。
  3. 执行 npm run build 编译项目到 ./dist 文件夹。
  4. 然后可以使用 pm2 这种 node 服务启动工具,启动 npm start,项目就可以正常运行了。