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文件中,所有的分割不正确,需要正确的换行和符号。
- 读取文件内容
- 规范化格式
- 写入新文件
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 标签。
算法:
- 使用 fs 读取 HTML 文件
- 使用正则表达式匹配 style 和 script 标签,获取 css 和 JS 部分
- 使用 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')
})
}
// 附录: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 的具体配置。