Skip to content

01

第一天 初识 Node

统计信息:字数 8046 阅读17分钟

00.学习目标

Nodejs 是什么,可以做什么,组成部分

常见模块功能:fs 读写操作文件;path 处理路径;http 实现基本 web 服务器

01.浏览器中的JavaScript运行环境

浏览器:可以解析 JS 语法,包括核心语法(变量函数数据类型)+ webAPI(DOM+ BOM)

每个浏览器内置了 DOM BOM 的 API,所以可以使用对应的方法

运行环境:代码正常运行需要的必要环境;V8 引擎负责解析和执行 JS 代码。浏览器运行环境提供了内置 API,所以API只能在浏览器中调用,在 nodeJS 中没有。

02.什么是 Node.js

NodeJS 中的 JS = 基本的 JS 语法 + 内置 API(fs path http 等)

浏览器是JS执行的前端运行环境;NodeJS是JS执行的后端运行环境,所以nodeJS 中无法使用 BOM DOM 等浏览器内置API语法

用途:NodeJS 提供了底层API的调用,对应的就是浏览器。具体的业务逻辑主要由各种框架的功能完成:例如使用 express koa egg 构建web后端应用;使用 electron 构建 APP(跨平台使用)等nodeJS 可以使用原生的 API 完成业务,类似浏览器直接更改DOM,实际上复杂的功能使用框架性能更好。

如何学习nodejs:JS基本语法 + 内置API(fs http)+ 常用第三放框架(experss mysql)

03.安装Node.js

不同操作系统下载不同的安装包。版本号中偶数的是稳定版,奇数的是测试版,企业级使用偶数版本。

04.使用Node运行JS代码

直接使用 node + 文件路径即可运行,或者输入 node 进入交互式界面中单行输入JS代码。

05.fs-读取文件内容

fs 是文件操作

const fs = require('fs');

fs.readFile(path, options, callback);
fs.writeFile(path, content, [option], callback);
  • Path 文件的路径
  • options,可选,通常表示文件编码格式 utf8
  • content 文件内容(通常是字符串或者array buffer)
  • callback 异步操作文件后的回调函数(第一个参数是错误对象,第二个是操作的结果)如果读取成功,err 对象是 null,datastring 是读取的文件内容;如果读取失败,err 是错误对象,dataString 是 undefined

实例

const fs = require('fs');

fs.readFile('./1.txt', 'utf8', function (err, dataStr) {
  if (err) {
    console.log(err.message);
    return;
  }
  console.log(dataStr);
});

06.fs-写入文件内容

const fs = require('fs');

fs.writeFile('./1.txt', 'hello world', function (err) {
  if (err) {
    console.log(err.message);
  }
});

07.fs-整理成绩的案例

先分析程序的思路,然后再写代码

问题:一个成绩txt文件中,所有的分割不正确,需要正确的换行和符号。

  1. 读取文件内容
  2. 规范化格式
  3. 写入新文件
const fs = require('fs');

fs.readFile('./result.txt', 'utf8', function(err, dataStr) {
  if (err) {
    console.log(err.message);
    return;
  }
  const arr = dataStr.split(' ');
  const arrNew = arr.map(item => {
    return item.replace('=', ':');
  });
  const newRes = arrNew.join('\n');
  fs.writeFile('./result-new.txt', newRes, function(err, dataStr) {
    if (err) {
      console.log(err.message);
      return;
    }
    console.log('write file success');
  })
})

08.fs-处理路径问题

相对路径的问题:上面的案例中,我们使用拼接字符串的方式,组成需要读取写入的文件路径。如果在 cmd 中另一个路径中执行脚本,那么相对路径可能不正确,无法执行,所以不使用相对路径。

绝对路径的问题:使用绝对路径,可以在各种路径下执行正确。但是当某个文件名更改后,绝对路径不会自动变化,这样代码可维护性不好。从一个机器到另一个机器,代码实用性很差,所以不适用绝对路径。

所以我们使用 __dirname 表示当前文件的路径,这样可以避免上面的问题

09.path-使用path模块处理路径

因为上面的问题,path 模块可以处理各种路径问题,以后路径拼接的操作必须使用 path。

  • path.join() 将多个路径片段,拼接成一个完整的字符串(包括各种相对绝对路径)
  • path.basename(path, [ext]) 从路径字符串中解析文件名, ext 是文件扩展名,可选
  • path.extname(path) 获取路径中扩展名部分,返回字符串

实例

const path = require('path');

console.log(path.join('/a', '/b/c', '../../', './d', 'e')); // /a/d/e
console.log(path.join(__dirname), './1.txt');

path.basename('./test/1.txt'); // 1.txt
path.basename('./test/1.txt', '.txt'); // 1 第二个参数会去掉后缀名
path.extname('./test/1.txt'); // .txt 返回值中包括后缀名和点

10.时钟案例-分析需求&读取文件内容

需求:有一个前端文件 HTML,其中包括了 css 和 JS 标签。我们需要把 css 和 JS 部分单独写成外部文件,并导入到 HTML 文件中,原来的功能正常使用。

默认只有一个 style 和 script 标签。

算法:

  1. 使用 fs 读取 HTML 文件
  2. 使用正则表达式匹配 style 和 script 标签,获取 css 和 JS 部分
  3. 使用 fs 写入 index.css index.js index.html 文件

代码实现

const fs = require('fs');
const path = require('path');

const regStyle = /<style>[\s\S]*<\/style>/;
const regScript = /<script>[\s\S]*<\/script>/;
// 注:\s 表示空白字符,\S 表示非空白字符,[\s\S] 表示任意字符,* 表示任意多个

fs.readFile(path.join(__dirname, './index.html'), 'utf8', (err, dataStr) => {
  if (err) {
    console.log(err.message);
    return;
  }
  resolveCSS(dataStr);
  resolveJS(dataStr);
  resolveHTML(dataStr);
});

11.时钟案例-处理CSS、JS、HTML

处理 css,把 css 写入外部文件 index.css

function resolveCSS(htmlStr) {
  const res = regStyle.exec(htmlStr)[0];
  const newCSS = res.replace('<style>', '').replace('</style>', '');
  fs.writeFile(path.join(__dirname, './index.css'), newCSS, (err) => {
    if (err) {
      logger.err(err.message);
      return 
    }
    console.log('add css file success')
  })
}
exec 说明
// 附录:Reg.exec(string) 检索字符串中正则表达式的匹配
// 返回值 arr:一个数组,如果为找到返回 null
// arr[0] 与正则表达式匹配的文本(如果有)
// arr[1] 与正则表达式的第1个子表达式匹配的文本(如果有)
// arr[2] 与正则表达式的第2个子表达式匹配的文本(如果有),以此类推
// arr.index 匹配文本的第一个字符的位置
// arr.input 是被检索的字符串 string
// 一般情况下(非全局的Regexp) Regexp.exec(string) 和 String.match(regexp) 返回值相同

处理JS,把 js 写入外部文件 index.js

function resolveJS(htmlStr) {
  const res = regScript.exec(htmlStr)[0];
  const newJS = res.replace('<script>', '').replace('</script>', '');
  fs.writeFile(path.join(__dirname, './index.js'), newJS, (err) => {
    if (err) {
      logger.err(err.maeeage);
      return;
    }
    console.log('write js success');
  })
}

处理 HTML,去掉原来的 style 和 js 部分,然后引入 link 和 script 新标签

function resolveHTML(htmlStr) {
  const newHTML = htmlStr
    .replace(regCSS, '<link ref="stylesheet" href="./index.css"></link>')
    .replace(regScript, '<script src="./index.js"></script>');
  fs.writeFile(path.join(__dirname, './index.html'), newHTML, (err) => {
    if (err) {
      logger.error(err.message);
      return;
    }
    console.log('write html success');
  })
}

12.时钟案例-时钟案例的两个注意点

fs.writeFile() 只能创建文件,不能创建文件夹(创建路径),所以通常先检查路径是否存在,如果不存在先创建文件夹,然后再写入文件。

fs.writeFile() 默认会覆盖文件内容(新的内容把旧的内容覆盖),如果设置追加模式,需要参阅 options 的具体配置。


Last update: November 9, 2024