因为要看React, 之前花了点时间把JavaScript的ES6复习了一下, 其实ES6的内容就是让JS变得更像一门标准语言了, 不再有很多莫名其妙的地方, 还是很好掌握的, 至于什么数组参数和解构, 也都是Java里早就见过的玩意了, 不过一般还是尽量少用.

不过node我没有仔细看过,只有在前端工程化的时候, 把node当成一个基础环境, 核心不是node, 而是通过node下载的webpack等工具, 这次借着机会好好把node看一下吧.

这次是Udemy上的视频The Complete Node.Js Developer Course (3rd Edition), 在这里可以免费下载.

  1. 安装node.js
  2. 第一个简单的node程序
  3. 模块化的node – 文件系统的简单例子
  4. 模块化的node – 导入自己编写的js文件
  5. 模块化的node – npm
  6. 本地包与全局包

安装node.js

安装Node如果不是为了装那些需要C/C++编译的工具, 安装还是挺简单的. 到官网下载node, 不管是linux还是windows都比较容易, 下载回来安装即可.

之后在命令行中输入 node -v ,如果显示出来版本号, 说明就安装成功了, 视频里让我装vs code, 我就还是用webstorm好了. 另外发现视频里还是8.12版本, 有点老了, 后来出了更新, 是10.15.3版本, .

正常情况下, JS的宿主是浏览器, 也就是浏览器同时是JS的解释引擎, 加上给JS提供了基于事件的单线程处理和异步调用, 很多时候JS的一些内容是浏览器的内部API来实现的.

node.js实际上是一个独立于浏览器之外的JS引擎, 基于Chrome的V8引擎, 也是目前最好的JS引擎. 所以可以直接用node来运行js文件.

当然, 因为其独立于浏览器, 所以API与普通的JS不同, 没有很多关于浏览器的操作, 但是作为一个编程语言环境, 提供了很多诸如系统调用等API, 这是浏览器中的JS做不到的.

目前使用的12.18.3 LTS 版的node的文档..

第一个简单的node程序

编写一个超级短的js文件, 比如叫做hello.js:

console.log("Hello world!")

然后到终端里, 就像Python运行py文件一样, 使用node来运行:

node hello.js

就会在控制台中打印出Hello world!, 当然, 由于node被从浏览器环境中剥离出来, 一些操作DOM的东西就无法在node中实现, 反而普通编程语言附带的文件系统库等, 倒是可以在node中使用, 而在浏览器里, 是绝对不要想直接访问文件系统的.

模块化的node – 文件系统的简单例子

既然是一个JS解释器, 类似Python, 除了有内置的函数, 也就是不需要导入其他模块的内容, 比如上一节写的console对象, 其他还有很多包可以导入.

node的文档中可以看到很多内容, 其中每一个内容其实都是一个包, 点进去后在例子中可以看到使用require()函数来导入包.

require()函数就类似于很多其他语言的import, 只不过比较特别的是导入的内容用一个变量存放, 其实是一个对象, 然后调用这个对象的各种方法来完成工作.

先来看一个最常用的文件系统相关的包, 文档在这里, 其中提到The fs module provides an API for interacting with the file system in a manner closely modeled around standard POSIX functions. 可见基本上就是基于POSIX系统调用来编写的函数.

写一个最简单的app.js, 导入语法是:

const fs = require('fs');

之后有几个最简单的函数:

//新建文件并写入内容
fs.writeFileSync('notes.txt', 'This file is created by Node.js');
//在文件尾部追加内容
fs.appendFileSync('notes.txt', '\nThis is append');

这可以完成一个最基本的文本文件的读写, 格式都是UTF-8编码的.

模块化的node – 导入自己编写的js文件

除了库之外, 自然也需要导入自己编写的模块. 这里就需要了解Node.js的导出规则了, 并不像其他语言导入包, 实际上Node.js需要在被导入的文件或者包内设置特殊的被导入内容才行, 只有设置了被导出内容的东西, 才可以被导出.

编写一个utils.js如下:

const name = "Minkopig";

module.exports = name;

注意第二行, 这是node的固定写法, module.exports后边的就是该模块可以导出的部分.

每个JS文件在node中都由单独的scope, 像很多语言一样, 导入一个js模块实际上也是先运行那个文件, 之后再进行可以导入的部分.

修改app.js如下:

const name = require('./utils');

console.log(name)

运行之后为如下:

utils.js is loaded
Minkopig

可见先运行了被导入的JS文件, 然后从其中获取了导出的name. 有了这个就可以知道, 导出的东西不一定是一个变量, 可以是一个对象等等, 很复杂.

模块化的node – npm

npm就不多说了, 就是Node.js的包管理器, 类似于Python与pip的关系. npm的官方网站是:https://www.npmjs.com/.

如果在webstorm中启动一个node项目, 会立刻相当于在目录之下运行npm init, 会创建一个package.json文件, 标志着这个目录已经变成了一个node项目.

然后具体安装就可以使用 npm install 包名 来进行安装, 被安装的东西会位于目录内的 node_modules目录中, 同时还会生成一个 package-lock.json, 记录这个项目实际使用的包的版本.

这里安装了两个包, 一个是validator, 一个是chalk.

本地包与全局包

像刚才一样, 直接安装的包位于当前的项目目录下, 这种包叫做本地包, 也就是只有当前项目可以使用.

如果想安装全局包, 则需要使用另外的命令, 也就是在安装本地包的命令中加上一个参数 -g:

这里以安装nodemon为例:

npm install nodemon@2.0.4 -g

这其中红色的部分就是指定版本的方法, 最后的橙色-g就是全局变量的参数.

安装之后, 在终端中使用nodemon来启动app.js, 而不是通过IDE来启动app.js. 然后就可以发现:

[nodemon] 2.0.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
Yay for orange colored text!
Underlined reddish color
Bold gray!
[nodemon] clean exit - waiting for changes before restart

nodemon就会在后台自动监测所有js文件的变动, 然后重新执行:

[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
Yay for orange colored text!
Underlined reddish color
[nodemon] clean exit - waiting for changes before restart

而且不仅可以检测app.js的变化, 还可以检测app.js所导入的其他模块. 这样对于编写一些持续性的应用就很方便. 在webstorm中, 编辑完之后必须按下Ctrl+S才可以触发nodemon的自动更新.

之后就是和普通的编程语言一样了, 先学一下基础的IO(更基础的语句就不用看了), 之后是各种包的使用, 最后搭建一个APP. 接下来就是基础了.