NodeJS 基础:安装使用&模块化

224 阅读3分钟

文本将介绍 Node.js 的安装以及基本知识,包括 Node.js 如何运行 JS 代码,Node.js 与浏览器上 API 的区别,以及 Node.js 中如何应用模块化,同时深入探讨模块在两种数据暴露两种方式上的区别。

Node.js 介绍

Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.

Node.js 是一个开源的,跨平台的 JavaScript 运行环境,它能够让开发者创建服务端,web应用,命令行工具以及脚本。

官网:nodejs.org/en

安装 Node.js

  1. 进入官网下载页:nodejs.org/en/download
  2. 下载安装包,安装Node.js

  1. 等待安装,直到安装成功

  1. 验证是否完成安装
node -v
  1. 出现以下信息即代表 node.js 安装成功
v20.12.0

Node.js 运行 js 文件

Node.js 是一个 JS 运行环境,因此可以通过 Node.js 提供的命令运行 JS 代码。

  1. 创建一个index.js文件,并在其中编写 JS 代码
console.log('hello nodejs');
  1. 在终端输入命令node <file name>,运行指定的 js 文件
node index.js
hello nodejs

Node.js API

Node.js 除了使用 ECMAScript 核心语法,还主要使用以下 Node API。

  • fsutil
  • httpurl
  • console,定时器
  • path,......
// 顶级对象
console.log(global);
console.log(globalThis);

// 定时器
setTimeout(() => {
  console.log('hello');
}, 0);

在 Node.js 中不能使用 DOM,BOM 及其他浏览器提供的 Web API。如下代码在 Node.js 环境中都会报错。

// BOM
console.log(window);

// DOM
console.log(document);

// Ajax
const xhr = new XMLHttpRequest();

Node.js 模块化

模块化可以将复杂的程序按照一定规范拆分成多个文件,其中拆分出的每一个文件即是一个模块;模块的内部数据是私有的,但是模块可以通过暴露内部数据以提供给外部模块使用。

模块化有以下好处:

  • 减少命名冲突,各个模块的同名变量不会冲突
  • 高复用性,模块只需引入就可以用于多个外部模块
  • 高维护性,对程序的某个模块升级而不会影响其他模块

模块暴露数据的方式有:

  • module.exports
  • exports

模块在导入时:

  • 通过require导入指定路径的模块。
  • 如果导入的是文件,可以导入 JS 文件或 JSON 文件,文件扩展名可以省略。
  • 如果导入的是目录,会检查目录下package.json文件中main属性的文件是否存在,如果存在则导入此模块;如果没有则检查是否存在index.jsindex.json,如果存在则引入此模块,没有则报错。

module.exports

  1. 使用module.exports导出定义的模块
function fn() {
    console.log('world');
}
module.exports = fn;
  1. 使用require导入模块
const my = require('./my');
my();

exports

  1. 使用exports导出定义的模块
function hello() {
    console.log('world');
}
exports.hello = hello;
  1. 使用require导入模块
const my = require('./my');
my.hello();

module.exports/exports区别

nodejs中使用require引入模块,它实际引入的只是module.exports ,而不是exports

那为什么exports也能够暴露数据?

虽然module.exportsexports都可以用于暴露数据,实际上它们都同时指向一块空的内存空间;

它们之间的关系是:module.exports = exports = {}

因此当通过exports.的方式也就是给对象添加属性或方法,就可以通过module.exports获取;

但是如果直接使用exports =赋值的形式暴露数据,由于更改了引用,此时就不同于module.exports所指向的内存地址,所以当引入模块后也访问不到要暴露的数据,因为暴露的数据来源于module.exports

通过代码验证module.exportsexports指向同一块内存空间:

console.log(module.exports === exports); // true