image.png
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。

① 基于 Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用
② 基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用
③ 基于 restify 框架(http://restify.com/),可以快速构建 API 接口项目
④ 读写和操作数据库、创建实用的命令行工具辅助前端开发、etc…

1 基本命令

1.1 查看版本

  1. node -v

1.2 执行指定js文件

  1. node 1.\ 测试.js

node 文件路径

2 文件模块

2.1 导入文件模块

  1. const fs = require('fs')

2.2 读取文件

  1. fs.readFile(path[, options], callback)
  • 参数1:必选参数,字符串,表示文件的路径。
  • 参数2:可选参数,字符串, 表示以什么编码格式来读取文件。
  • 参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果。
  1. const fs = require('fs')
  2. fs.readFile('./files/q.txt', 'utf8', function (err, dataStr) {
  3. console.log(err);
  4. console.log('-------');
  5. console.log(dataStr);
  6. })

没有异常err 为 null
image.png
错误结果:
image.png

判断读取文件失败输出错误结果:

  1. const fs = require('fs')
  2. fs.readFile('./files/q1.txt', 'utf8', function (err, dataStr) {
  3. if (err) {
  4. return console.log(err.message);
  5. }
  6. console.log(dataStr);
  7. })

image.png

2.3 写入文件

  1. fs.writeFile(file, data[, options], callback)
  • 参数1:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径。
  • 参数2:必选参数,表示要写入的内容。
  • 参数3:可选参数,表示以什么格式写入文件内容,默认值是 utf8。
  • 参数4:必选参数,文件写入完成后的回调函数。
  1. const fs = require('fs')
  2. fs.writeFile('./files/2.txt', 'hello nodejs', err => {
  3. if(err) {
  4. return console.log(err.message);
  5. }
  6. console.log(err);
  7. })

image.png
同读取一样,若是无异常, err为null

注意:

  • fs.writeFile() 方法只能用来创建文件,不能用来创建路径。
  • 且它默认写入方式是w,会将之前原有的内容覆盖掉

    3 path路径模块

3.1 路径动态拼接问题

开头的相对路径时,很容易出现路径动态拼接错误的问题。
代码在运行的时候,会以执行 node 命令时所处的目录,动态拼接出被操作文件的完整路径。

  1. console.log(__dirname + '/xxxx');

image.png

3.2 路径拼接方法—join

用来将多个路径片段拼接成一个完整的路径字符串

  1. path.join([...paths])
  • …paths 路径片段的序列
  • 返回值:

../ 会抵消一层路径

  1. const path = require('path')
  2. const self_path = path.join(__dirname, './files/1.txt')
  3. console.log(self_path);

image.png

3.3 获取文件名—basename

可以从一个文件路径中,获取到文件的名称部分

  1. path.basename(path[, ext])
  • path 必选参数,表示一个路径的字符串
  • ext 可选参数,表示文件扩展名
  • 返回: 表示路径中的最后一部分
  1. const path = require('path')
  2. var p = 'a/b/c/index.js'
  3. console.log(path.basename(p));
  4. console.log(path.basename(p, '.js'));

image.png

3.4 获取扩展名—extname

可以获取路径中的扩展名部分

  1. path.extname(path)

path 必选参数,表示一个路径的字符串
返回: 返回得到的扩展名字符串

  1. const path = require('path')
  2. var p = 'a/b/c/index.js'
  3. console.log(path.extname(p));

image.png

3.5 综合运用

目标抽出html里面的style标签和script标签的内容分别放入其他文件中

1 创建正则表达

  1. const fs = require('fs')
  2. const path = require('path')
  3. // 匹配<style></style>和<script></script>标签内容
  4. const regStyle = /<style>[\s\S]*<\/style>/;
  5. const regScript = /<script>[\s\S]*<\/script>/;

\S匹配非空字符串
[] 表示有一系列字符可供选择,只要匹配其中一个就可以了
*表示任意次

2 读取与写入

  1. fs.readFile(path.join(__dirname, './index.html'), 'utf8', (err, result) => {
  2. if (err) return console.log(err.message);
  3. resolve(result, '<style>', '</style>', regStyle, './clock/index.css');
  4. resolve(result, '<script>', '</script>', regScript, './clock/index.js');
  5. resolveHTML(result);
  6. })
  7. // 抽出css和js
  8. function resolve(result, relc1, relc2, reg, target_path) {
  9. var str = reg.exec(result);
  10. // 去除首尾style标签
  11. var newCSS = str[0].replace(relc1, '').replace(relc2, '');
  12. // 写入文件中
  13. fs.writeFile(path.join(__dirname, target_path), newCSS, err => {
  14. if (err) return console.log(err.message);
  15. console.log('write file success');
  16. })
  17. }
  18. // 去掉内联的css和js
  19. function resolveHTML(params) {
  20. const newHTML = params
  21. .replace(regStyle, '<link rel="stylesheet" href="./clock/index.css">')
  22. .replace(regScript, '<script src="./clock/index.js"></script>');
  23. fs.writeFile(path.join(__dirname, './index.html'), newHTML, err => {
  24. if (err) return console.log(err.message);
  25. console.log('write file success');
  26. })
  27. }

4 http模块

image.png
可以说一台服务器可以开启多个web网站服务,只是端口号不同

4.1 创建web服务器

① 导入 http 模块

  1. const http = require('http')

② 创建 web 服务器实例

  1. const server = http.createServer()

③ 为服务器实例绑定 request 事件,监听客户端的请求

  1. server.on('request', (req, res)=>{
  2. console.log('have people come in');
  3. })

④ 启动服务器

  1. server.listen(80, () => {
  2. console.log('start the server');
  3. })

4.2 请求对象与响应对象

  1. const http = require('http')
  2. const server = http.createServer()
  3. server.on('request', (req, res) => {
  4. const str = `请求url${req.url}, 请求类型:${req.method}`;
  5. res.setHeader('Content-Type', 'text/html; charset=utf-8')
  6. res.end(str)
  7. })
  8. server.listen(80, () => {
  9. console.log('http://localhost');
  10. })

image.png

4.3 解决响应中文乱码

需要手动设置内容的编码格式

  1. res.setHeader('Content-Type', 'text/html; charset=utf-8')

4.4 动态响应案例

  1. const http = require('http')
  2. const server = http.createServer()
  3. server.on('request', (req, res) => {
  4. const url = req.url; // 获取请求url地址
  5. let content = '<h1>404 你所访问资源已被冲入厕所</h1>'
  6. if (url === '/' || url === '/index.html') {
  7. content = '<h1>首页</h1>'
  8. }
  9. res.setHeader('Content-Type', 'text/html; charset=utf-8')
  10. res.end(content)
  11. })
  12. server.listen(80, () => {
  13. console.log('http://localhost');
  14. })

image.png

4.4 访问静态网页

image.png

  1. const fs = require('fs')
  2. const http = require('http')
  3. const path = require('path')
  4. const server = http.createServer();
  5. server.on('request', (req, res) => {
  6. let content = '<h1>404 你所访问资源已被冲入厕所</h1>';
  7. let fpath = ''
  8. if (req.url === '/') {
  9. fpath = path.join(__dirname, './index.html');
  10. } else {
  11. fpath = path.join(__dirname, req.url)
  12. }
  13. fs.readFile(fpath, 'utf8', (err, data) => {
  14. if (err) {
  15. res.setHeader('Content-Type', 'text/html; charset=utf-8');
  16. return res.end(content);
  17. }
  18. res.end(data);
  19. })
  20. })
  21. server.listen(80, () => {
  22. console.log('start http://localhost');
  23. })

image.png

5 模块化

模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。

把代码进行模块化拆分的好处:
① 提高了代码的复用性
② 提高了代码的可维护性
③ 可以实现按需加载

5.1 引入模块问题

使用 require() 方法加载其它模块时,会执行被加载模块中的代码。
文件 12.模块引入.js:

  1. // 将被引入模块
  2. console.log('12');

导入模块的文件

  1. const x = require('./12.模块引入')
  2. console.log(x);

image.png

5.2 模块作用域

在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。

好处是为了防止全局变量污染。

不同于浏览器,导入文件所含的全局变量都在window对象中,容易造成覆盖即全局变量污染。

5.3 module对象

每个 .js 自定义模块中都有一个 module 对象,它里面存储了和当前模块有关的信息

  1. console.log(module)

image.png

5.4 共享模块成员

在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。
外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。

  1. var a = 10
  2. function sayHi(params) {
  3. console.log('hello world');
  4. }
  5. module.exports.a = a;
  6. module.exports.sayHi = sayHi
  1. const x = require('./14 module对象')
  2. console.log(x);
  3. x.sayHi()

image.png

require() 模块时,得到的永远是 module.exports 指向的对象

module.exports 可以不用写module

为了防止混乱,不要在同一个模块中同时使用 exports 和 module.exports
image.png
默认情况下,exports 和 module.exports 指向同一个对象。
最终共享的结果,还是以 module.exports 指向的对象为准。

5.5 CommonJS规范

CommonJS 规定了模块的特性和各模块之间如何相互依赖。

CommonJS 规定:
① 每个模块内部,module 变量代表当前模块。
② module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
③ 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。