node.js 新手入门指南

node.js是什么:

       是一个基于Chrome V8引擎的JavaScript环境(ECMAScript+内置模块)

学习方向:

       模块系统(核心模块、自定义模块、第三方模块)+  npm

自从es6问世后,使得JavaScript支持了模块话,第三方模块开始逐渐淘汰。

1、安装

打开Node.js 中文网,选择下载选项,选择匹配你当前电脑的系统版本

2、node初体验

使用node跑JavaScript代码

在当前文件加下面有一个node初体验.js文件,

文件内容为:

node.js 新手入门指南_第1张图片

现在运用node+文件名.js命令运行该文件

node.js 新手入门指南_第2张图片

3、node.js运行环境和chrom浏览器运行环境的区别

相同点:

①都是可以运行js代码的容器,更严格一点说:都可以运行ECMAScript

②要下载安装才能使用

不同点:

①各有不同的API: nodejs运行js时,不能写DOM,BOM,也不能用window对象了

②Nodejs 环境可以去实现后端的功能

③浏览器环境可以去实现前端的功能

4、模块系统-核心模块

使用步骤:

        引入 const fs=require(fs)

        使用

4.1 fs(文件系统模块)

        ①创建file文件夹实例对象.mkdir()

                使用方法:fs.mkdir("路径", 回调函数)

// 1、创建file文件夹
fs.mkdir("./file", function (err) {
  if (err) {
    return console.log("创建文件夹失败,失败原因为:" + err.message);
  }
  console.log("文件夹创建成功");
});

        ②在file文件夹里创建一个new.txt文件实例对象.writeFile()

                使用方法:fs.writeFile("路径", "内容",回调函数)

let a = `node.js的初体验`;
const fs = require("fs");

//2、写入文件
fs.writeFile("./file/new.txt", a, function (err) {
  if (err) {
    return console.log("文件写入失败,错误为:" + err.message);
  }
  console.log("文件写入成功");
});

*注意:如果该文件已存在,则为覆盖

        ③查看file文件夹里new.txt文件实例对象.readFile()

                使用方法:fs.readFile("路径", "编码格式",回调函数)

// 3、读取文件
fs.readFile("./file/new.txt", "utf-8", function (err, data) {
  if (err) {
    return console.log("文件读取失败,错误原因为:" + err);
  }
  console.log(data);
});

4.2 path(路径模块)

引入模块:const path = require('path')

作用:用来处理路径问题:拼接,分析,取后缀名等等。

const path = require('path')
// 拼接html5.jpg的绝对路径
// 1) 找到当前文件夹的绝对路径
console.log(__dirname)
// 2) 加上 html5.jpg
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, 'html5.jpg')
// const filePath = __dirname + '\\html5.jpg'
// 走一步,看一步
console.log(filePath)

fs.readFile(filePath,function(err, data) {
  if(err) {
    console.log(err)
    return
  }
  console.log(data)
})

扩展:__filename__dirname

__filename:获取当前被执行文件的绝对路径

__dirname:获取当前被执行文件的文件夹所在的绝对路径

const fs = require("fs");

let a = fs.readFileSync(`${__dirname}/file/new.txt`, "utf-8");

console.log(a);

5、自定义模块

什么是模块化:

       一个js文件可以引入其他的js文件,能使用引入的js文件的中的变量、数据,这种特性就称为模块化。

模块化的作用:

       使用模块化开发可以很好的解决变量、函数名冲突问题,也能灵活的解决文件依赖问题。

nodejs模块的分类

  • 核心模块
    • 就是nodejs自带的模块,在安装完nodejs之后,就可以随意使用啦。相当于学习js时使用的Array对象。
    • 例:fs, http, querystring, path
    • 全部模块的源代码 node/lib at master · nodejs/node · GitHub
  • 自定义模块
    • 程序员自己写的模块。就相当于我们在学习js时的自定义函数。
  • 第三方模块
    • 其他程序员写好的模块。nodejs生态提供了一个专门的工具npm来管理第三方模块,后面我们会专门讲到。
    • 相当于别人写好的函数或者库。例如我们前面学习的JQuery库,arttemplate等。

自定义模块-基本介绍

目标

掌握自定义模块的使用背景和步骤

背景

我们对代码的封装是以模块(一个独立的.js文件)为单位进行的。一般的做法是实现好某一个功能之后,封装成一个模块,然后在其它文件中使用这个模块。

类比于js自定义函数,自定义模块的使用场景是:

  • 代码需要在项目重用
  • 代码需要提供给他人使用
  • 代码虽然不需要重用,但封装成模块有利于优化代码结构,方便后期维护与扩展

步骤

一共有两步:

  1. 定义模块。就是创建一个js文件, 对外导出我们希望导出的内容。
  2. 使用模块。在需要使用的地方去导入模块文件。

Node.js 中的 CommonJS 的模块化规范

CommonJS 规范

CommonJS 规范中主要规定了以下 3 项内容:

  • 导入其它模块时,统一使用 require() 函数。
  • 每个 .js 文件,都是一个独立的模块,模块内的成员都是私有的。
  • 在每个 JS 模块中,使用 module.exports 向外共享成员。

图示

根目录
├── user.js  # 定义模块
└── test.js  # 引入user.js模块

node.js 新手入门指南_第3张图片

node.js 新手入门指南_第4张图片

注意

  • module.exports 是固定写法,一般放在文件的最末尾,也只用一次。
  • module.exports表示当前模块要暴露给其它模块的功能。
    • 它可以导出对象,数组,函数等等类型。为了方便组织代码,导出对象的情况比较多。
    • 不必要导出所有函数,对象,数组等。那些没有导出的部分就相当于这个模块的内部变量了。在下图中变量1,函数1,数组就是模块内部的数据,在外部无法别访问到。

node.js 新手入门指南_第5张图片

小结

所谓定义模块,就是新建一个js文件。文件取名时,要注意一下:

  • 一般会用模块名给它命名。类比于核心模块,例如,你的模块叫myModule,则这个js文件最好叫myModule.js
  • 不要与核心模块的名字重复了。就像我们定义变量不要与核心关键字重名,你自己定义的模块也不要叫fs.js,因为nodejs有一个核心模块就叫fs.js。
  • 要记得导出模块

自定义模块-实操

假设在工作中我们自己定义了一些工具方法, 而这些工具方法是可以在其他项目中使用的。此时我们就可以采用自定义模块的方式来处理。

素材

以下是一个对时间进行格式化的函数

const formatDate = (dateTime) => {
  const date = new Date(dateTime) // 转换成Data();
  const y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate()
  d = d < 10 ? ('0' + d) : d
  return [y,m,d].join('-')
}

这个函数如何才能被复用呢?

我们以此为基础,开始做自定义模块的动作

思路

根目录
├── tool.js # 把我们要用到的公共方法 封装在这个文件中 
└── test.js # 测试tool.js中封装的方法

操作

定义模块

// 方法定义在这里
const formatDate = (dateTime) => {
  const date = new Date(dateTime) // 转换成Data();
  const y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate()
  d = d < 10 ? ('0' + d) : d
  return [y,m,d].join('-')
}

// 通过module.exports来导出模块
module.exports = {
  formatDate
};

记得要导出模块: 在文件尾部,使用module.exports来导出模块。

导入模块

完成了模块定义之后,我们就可以在另一个文件中使用这个模块了。

基本步骤是:

1. 导入模块;格式:const 模块名 = require('./模块路径')

2. 先打出来看看;

当一个模块被成功引入之后,就可以类比使用核心模块的过程一样去使用它们了。

下面是示例代码:

// test.js
// 1. 导入模块
// 注意这里使用的是相对路径。可省略.js.
const tool = require('./tool.js');

// 在使用之前请先打印出来看看
console.log(tool);

// 2. 使用模块中的方法
console.log(tool.formatDate(Date.now()))

注意:

  • 使用require语句引入你定义好的模块
  • 这里必须使用相对路径的格式去引入自定义模块。"./" 也不能省略。

练习

将如下的方法补充到上面封装的tool.js中,并导出使用

//tools.js
const relativeTime = (oldTime) => {
  const t = new Date(oldTime)
  // Date.now():现在的时间戳(毫秒)
  // t.getTime():旧时间的时间戳(毫秒)

  const diff = Date.now() - t.getTime() // 相隔多少毫秒
  // Math.floor 向下取整: 1.7年 ---> 1年前
  const year = Math.floor(diff / (1000 * 3600 * 24 * 365))
  if (year) {
    return `${year}年前`
  }
  const month = Math.floor(diff / (1000 * 3600 * 24 * 30))
  if (month) {
    return `${month}月前`
  }
  const day = Math.floor(diff / (1000 * 3600 * 24))
  if (day) {
    return `${day}天前`
  }
  const hour = Math.floor(diff / (1000 * 3600))
  if (hour) {
    return `${hour}小时前`
  }
  const minute = Math.floor(diff / (1000 * 60))
  if (minute) {
    return `${minute}分钟前`
  } else {
    return '刚刚'
  }
}

导出模块的两种方式

目标

了解两种导出的方式(难点,不是重点)

导出模块有两种方式

参考

  • exports
  • module.exports

// 定义方法,常量
const myPI = 3.14
const add = (a,b) => a + b;

// 导出,两种方法任意都可以
// 方法一:
exports.myPI = myPI
exports.add = add

// 方法二:
module.exports.myPI = myPI
module.exports.add = add

// 方法二(变形)
module.exports  = {
    myPI,
    add
}

在阅读其它人的代码时,可能会遇到这两种不同的写法。所以我们还是有必要了解一下的。

cookie模块,body-parser模块,arry-flatten模块中的导出均采用不同的方式。

两个对象的关系

  • 初始exports和module.exports是指向同一块内存区域,其内容都是一个空对象。(exports是module.exports的别名)即:

exports === module.exports // 输出是 true

所以下面两种写法的效果是一样的:

 // 写法1 mymodule.js
 exports.f = function(){ }
 exports.pi = 3.1415926


 // 写法2 mymodule.js
 module.exports.f = function(){ }
 module.exports.pi = 3.1415926

  • 在定义模块时:
    如果直接给exports对象赋值(例如:exports={a:1,b:2}),此时,exports就不会再指向module.exports,而转而指向这个新对象,此时,exports与module.exports不是同一个对象。

在引入某模块时:以该模块代码中module.exports指向的内容为准。

图示

node.js 新手入门指南_第6张图片

node.js 新手入门指南_第7张图片

node.js 新手入门指南_第8张图片

node.js 新手入门指南_第9张图片

结论

在导出模块过程中,建议只用一种方式(建议直接使用module.exports)

*npm见下一章

你可能感兴趣的:(node.js)