美文网首页
第六届360前端星计划_Node.js 基础入门

第六届360前端星计划_Node.js 基础入门

作者: lhang_91ad | 来源:发表于2020-04-10 15:48 被阅读0次

    正则的三个应用场景

    主讲人

    • 李喆明
    • 360前端技术专家
    • 奇舞团

    从5各方面介绍

    1. 什么是 Node.js
    2. Node.js 基础
    3. NPM
    4. 基于 Node.js 的 Web 开发
    5. Node.js 的调试

    1.什么是 Node.js
    基于jsv8引擎的js运行时
    以js区别:

    • 基于异步 I/O 相关接口
    • 基于 node_modules 和 require 的模块依赖
    • 提供 C++ addon API 与系统交互
      语法一样,提供的接口的差别
    1. Node.js 可以干什么
    • Web 服务端:Web Server、爬虫
    • CLI 命令行脚本:webpack
    • GUI 客户端软件:VSCode、网易云音乐
    • 树莓派IoT, 图像处理, 实时通讯,加密货币...
      例:
      nodejs爬虫
    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();
    })();
    
    1. Node.js 基础
      nodejs 脚本运行
    node index.js
    

    读写文件

    const fs = require('fs');
    fs.readFile('test.txt', (err, data) => {
        console.log(data);
    });//异步操作
    console.log('read file content');
    

    模块
    主要有

    • 内置模块:编译进 Node 中,例如 http fs net process path 等
    • 文件模块:原生模块之外的模块,和文件(夹)一一对应的形式
      使用内部文件
    const fs = require('fs');
    fs.readFile('a.text', (err, buffer) => {
      console.log(buffer);
    })
    const {readFile} = require('fs');
    readFile('a.txt', (err, buffer) => {
      console.log(buffer);
    })
    

    使用文件模块

    var circle = require('./circle.js');
    console.log('半径为4的圆面积是:' + circle.area(4));
    

    定义模块

    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_modules文件依次查找
    

    模块类型

    • .js
    • .json
    • .node (使用c++形式写完之后,使用node gulp 编译成的二进制文件)
    • .ejs node 新出的基于esmodule 形式 相应的 cjs commonjs导入导出

    模块路径查找

    • 绝对路径
    • 相对路径
    • 和当前路径处理为绝对路径
    • 模块/文件夹
    • 原生模块,直接读取缓存
      +[$NODE_PATH, ~/.node_modules, ./node_modules, ../node_modules, ...]
    • 解析 package.json,查找 main 属性,没有则使用 index.js
    • 如果未找到,则报错

    js模块解析

    const circle = require('./circle.js');
    
    
    + require 并不是全局变量
    + 定义的变量 circle 会污染其他文件么?
    
    • 通过 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 包管理器


      image.png

      npm最多

    包管理

    • 一个package.json文件应该存在于包顶级目录下
    • 二进制文件应该包含在bin目录下
    • JavaScript代码应该包含在lib目录下
    • 文档应该在doc目录下
    • 单元测试应该在test目录下
      例:
      npm init -y
    {
      "name": "star-plan",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
    

    meta 信息:

    • main:定义 入口文件
    • npm scripts :运行脚本
    1. dependencies
    2. devDependencies
    3. peerDependencies
    4. bundledDependencies
    5. optionalDependencies
    dependencies": {
        "accepts": "^1.2.2",
        "content-disposition": "~0.5.0",
        "cookies": "~0.7.0",
        "debug": "*",
        "delegates": "^1.0.0",
        "escape-html": "~1.0.1",
        "fresh": "^0.5.2",
        "only": "0.0.2",
        "parseurl": "^1.3.0",
        "statuses": "^1.2.0",
        "type-is": "^1.5.5",
        "vary": "^1.0.0"
    * ^ ~区别:
    ^ 可以中版本小版本更新
    ~小版本跟新
    *所有更新到最新
    不带
    其他形式:
    + 1.0.0 Must match version exactly
    + >1.0.0 Must be greater than version
    + >=1.0.0 <1.0.0 <=1.0.0
    + ~1.0.0 "Approximately equivalent to version"
    + ^1.0.0 "Compatible with version" 
    + 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
    + * Matches any version
    + version1 - version2 Same as >=version1 <=version2.
    
    • bin 指定key-value 在系统中创建alias 直接执行属性名对应文件
    • registry 原代理
      semver version : 版本信息,
      依次:
    • 小版本修复,bug更新
    • 种版本 特性的增加
    • 大版本整体重构
      npm问题(现在被github收购)
    1. 速度问题 官网在国内不好

    2. 安全问题
      解决:

      • 查看源码看 Star
      • https://snyk.io/ 外部的检测服务
      • npm audit (快速检测漏洞)
    3. 基于 Node.js 的Web 开发
      用到http模块

    const http = require("http")
    const server = http.createServer((req, res) => {
      res.end('Hello World');
    });
    server.listen(3000);
    

    koa框架

    const Koa = require('koa');
    const app = new Koa();
    
    // response
    app.use(ctx => {
      ctx.body = 'Hello Koa';
    });
    
    app.listen(3000);
    module.exports = class Application extends Emitter {
      ...
    
      listen() {
        debug('listen');
        const server = http.createServer(this.callback());
        return server.listen.apply(server, arguments);
      }
    
      use(fn) {
        this.middleware.push(fn);
        return this;
      }
    
      callback() {
        const fn = compose(this.middleware);
    
        if (!this.listeners('error').length) this.on('error', this.onerror);
    
        const handleRequest = (req, res) => {
          res.statusCode = 404;
          const ctx = this.createContext(req, res);
          const onerror = err => ctx.onerror(err);
          const handleResponse = () => respond(ctx);
          onFinished(res, onerror);
          return fn(ctx).then(handleResponse).catch(onerror);
        };
    
        return handleRequest;
      }
    
      createContext(req, res) {
        const context = Object.create(this.context);
        const request = context.request = Object.create(this.request);
        const response = context.response = Object.create(this.response);
        context.app = request.app = response.app = this;
        context.req = request.req = response.req = req;
        context.res = request.res = response.res = res;
        request.ctx = response.ctx = context;
        request.response = response;
        response.request = request;
        context.originalUrl = request.originalUrl = req.url;
        context.cookies = new Cookies(req, res, {
          keys: this.keys,
          secure: request.secure
        });
        request.ip = request.ips[0] || req.socket.remoteAddress || '';
        context.accept = request.accept = accepts(req);
        context.state = {};
        return context;
      }
    }
    

    中间件繁多,质量参差不齐,选择困难

    • 逻辑分层
    • 路由处理
    • 数据解析、校验
    • 权限校验
    • Session、Cache
    • 数据库、Redis
    • 安全
    • ...

    Koa 无规范约束,不利于企业级团队开发

    thinkjs:

    基于koa 进行企业级封装 thinkjs

    ├─src //源码
    │  ├─bootstrap 用户启动脚本
    │  ├─config //配置文件
    │  │  ├─config.js
    │  │  └─adapter.js //日志等
    │  ├─controller 路由
    │  │  ├─index.js //对应着controller 参数和权限
    │  ├─logic //
    │  │  ├─index.js
    │  └─model 数据库操作
    ├─view 模板文件
    │  ├─index_index.html
    └─www 静态资源
    │  └─static
    │     ├─css
    │     ├─img
    │     └─js
    ├─development.js 启动文件
    ├─production.js启动文件
    ├─package.json
    
    // src/controller/index.js
    export default class extends think.Controller {
      indexAction() {
        return this.display();
      }
    }
    
    // view/index_index.html
    <h3>Hello World</h3>
    

    统一目录
    模块统一 模范快速开发,和学习成本小
    TODO项目实战

    1. 功能列表
    • TODO List 的页面
    • API
      • 获取 TOO 列表
      • 增加 TODO
      • 删除 TODO
      • 更新 TODO 状态
    1. 数据表设计
    CREATE TABLE `todo` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `desc` varchar(255) NOT NULL DEFAULT '',
      `status` tinyint(11) NOT NULL DEFAULT '0' COMMENT '0 是未完成,1是已完成',
      `createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    1. 安装 thinkjs
    npm install -g think-cli
    
    创建项目
    $ thinkjs new todo
    $ cd todo
    $ npm install
    

    相关文章

      网友评论

          本文标题:第六届360前端星计划_Node.js 基础入门

          本文链接:https://www.haomeiwen.com/subject/arrrmhtx.html