前端星-09:nodejs基础入门上+下

221 阅读4分钟

主讲:李喆明

什么是nodejs?

基于chrome的v8 js引擎的一个js运行时。

与js有什么区别?

  • 基于异步 I/O 相关接口
  • 基于 node_modules 和 require 的模块依赖
  • 提供 C++ addon API 与系统交互

nodejs可以干什么?

  • Web 服务端:Web Server、爬虫
  • CLI 命令行脚本:webpack
  • GUI 客户端软件:VSCode、网易云音乐
  • IoT, 图像处理, 实时通讯,加密货币...

比如实现爬虫:

//爬取豆瓣上关于电影的信息
const puppeteer = require('puppeteer');
const url = 'https://movie.douban.com/subject/26794435';

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url);
  const film = await page.evaluate(() => {
    const title = $('h1 > span:first-child').text();
    const poster = $('#mainpic img').attr('src');
    const desc = $('span[property="v:summary"]').text().trim();
    return {title, poster, desc};
  });

  console.log(JSON.stringify(film, null, '  '));
  await browser.close();
})();

node基础使用?

  1. hello world,直接js文件中console.log('hello world'),然后命令行用node执行该文件。
  2. 文件读取
//使用内置模块fs
const fs = require('fs');
fs.readFile('test.txt', (err, data) => {
    console.log(data);
});
console.log('read file content');
  1. 模块
  • 内置模块:编译进 Node 中,例如 http fs net process path 等
  • 文件模块:原生模块之外的模块,和文件(夹)一一对应
// app.js
var circle = require('./circle.js');
console.log('半径为4的圆面积是:' + circle.area(4));
  • 模块定义:使用exports暴露
// circle.js
const pi = Math.PI;
exports.area = function (r) {
    return pi * r * r;
};
exports.circumference = function (r) {
    return 2 * pi * r;
};
  • 模块加载
// 加载绝对路径文件
require('/foo/bar/a.js');

// 加载相对路径文件
require('../a.js');

// 加载无后缀的文件
require('../a');

// 加载外部模块
require('pkg-name');
  • 模块路径查找
    • 绝对路径
    • 相对路径
      • 和当前路径处理为绝对路径
    • 模块/文件夹
      • 原生模块,直接读取缓存
      • [$NODE_PATH, ~/.node_modules,
      • ./node_modules, ../node_modules, ...]
      • 解析 package.json,查找 main 属性,没有则使用 index.js
      • 如果未找到,则报错
  • 模块类型
    • .js
    • .json
    • .node
    • .mjs
  • 模块解析
    • 通过 fs.readFileSync 同步拿到文件内容
    • 对内容进行包装
    (function (exports, require, module, __filename, __dirname) {
        var circle = require('./circle.js');
        console.log('The area is ' + circle.area(4));
    });
    
    • 通过 vm.runInThisContext 执行
    • 获取 module 对象的值作为模块的返回值
  • 模块缓存
    • 模块加载后会将返回值缓存起来
    • 下次加载时直接读取缓存结果,避免文件 I/O 和解析时间
    • 导出对象缓存在 Module._cache 对象上

npm ? node包管理器

  1. 包管理规范
  • 一个package.json文件应该存在于包顶级目录下
  • 二进制文件应该包含在bin目录下
  • JavaScript代码应该包含在lib目录下
  • 文档应该在doc目录下
  • 单元测试应该在test目录下
  1. npm初始化结构
//package.json
{
  "name": "star-plan",    //项目名称
  "version": "1.0.0",     //版本,分别为大版本.中版本.小版本
  "description": "",      //描述
  "main": "index.js",     //入口文件
  "scripts": {            //执行命令行封装名称
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"       
}

3.包依赖

"dependencies": {
    "accepts": "^1.2.2",
    "content-disposition": "~0.5.0",
    "cookies": "~0.7.0",
    "debug": "*",
    ...
  },
  • 1.0.0只有版本号表示只能准确匹配该版本
  • ^大版本准确匹配,中版本和小版本可接受更新
  • ~接受小版本的更新
  • *接受任意版本更新
  1. npm的问题?
  • 速度问题
  • 安全问题:投毒事件、模块被删导致依赖模块安装不上的问题
    • npm audit快速检测模块漏洞

node开发web服务?

  1. web服务创建
const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello World');
});
server.listen(3000);
  1. koa:一个基于Promise、async以及await的nodeJS的web框架

特性:中间件,洋葱模型

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);

Koa缺点:无规范约束,不利于团队开发;中间件繁多,质量参差不齐,选择困难

  1. think.js:一个快速、简单的基于MVC和面向对象的轻量级Node.js开发框架

结构

├─src
│  ├─bootstrap
│  ├─config
│  │  ├─config.js
│  │  └─adapter.js
│  ├─controller                     //控制器,一个 url 对应一个controller下的 action
│  │  ├─index.js
│  ├─logic                         //逻辑处理。每个操作执行前可以先进行逻辑校验
│  │  ├─index.js
│  └─model                          //模型。数据库相关操作。
├─view                              //视图目录,存放对应的模版文件
│  ├─index_index.html
└─www
│  └─static                      //存放一些静态资源文件
│     ├─css
│     ├─img
│     └─js
├─development.js
├─production.js
├─package.json

项目练手:

  1. 框架搭建:使用think.js脚手架
  2. api设计
  • RESTful接口规范
    • 每个 API 都对应一种资源或资源集合
    • 使用 HTTP Method 来表示对资源的动作
    • 使用 HTTP Status Code 来表示资源操作结果
  1. 路由配置
// src/config/router.js
module.exports = [
  ['/ticket/:id?', 'rest'], // 配置 RESTful API 路由
]
  1. 数据库配置
// src/config/adapter.js
exports.model = {
  type: 'mysql',
  common: {
    logConnect: isDev,
    logSql: isDev,
    logger: msg => think.logger.info(msg)
  },
  mysql: {
    handle: mysql,
    database: 'todo',
    prefix: '',
    encoding: 'utf8',
    host: '127.0.0.1',
    port: '',
    user: 'root',
    password: 'root',
    dateStrings: true
  }
};

5.数据校验

  • 提供了 Logic 机制转门用来支持数据校验
  • 文件和 Action 与 Controller 一一对应

6.数据库操作

  • 封装了 think.Model 类
  • 提供增删改查等操作
  • 支持关联模型查询
  • 自动分析数据表字段类型
  • 自动数据安全过滤

nodejs的调试

  • 日志调试:内容中通过console.log输出
  • 断点调试:使用工具单步调试
    • node --inspect
      • NodeJS 6.3+ 使用 node --inspect 参数启动可以在 Chrome 浏览器中调试,在 chrome://inspect 中可以发现你的项目并启动 devtool
    • vscode
    • ndb

Node 开发角色转换?

  • 前端
    • 跟浏览器打交道,兼容性问题
    • 组件化
    • 加载速度、JS 执行性能、渲染性能
    • 错误监控
    • XSS、CSRF 等安全漏洞
  • 服务端
    • 数据库、Redis 等周边服务
    • 性能、内存泄露、CPU、机器管理
    • 服务监控、错误监控、流量监控、报警
    • SQL注入、目录遍历等安全漏洞