美文网首页
Node相关知识

Node相关知识

作者: 我叫Aliya但是被占用了 | 来源:发表于2019-06-17 00:14 被阅读0次

    使用commonjs规范:直接使用module.exports导出模块,require导入
    global下常用属性有:process、buffer、setImmediate等

    文件皆模块,所以this属性是{}(不是global)
    __dirname,__filename => 当前目录,文件绝对路径

    process

    • version
    • platform
    • nextTick 优先于promise.then
    • cwd() 当前执行命令的目录(非文件所在目录)的绝对路径。使用chdir(dir)可以修改
    • env 用户传入的环境变量
      export/set NODE_ENV=dev && node xxx.js
    • argv 用户传入的执行参数
      一个数组,[node所在目录,项目执行入口,...用户参数]

    commander 一个处理命令行参数的包

    var cmd = require('commander');
    cmd.command('myorder <param>')
       .option('-mo,-myorder', '我自己定义的命令')
       .action(() => {})
    cmd.parse(process.argv) // {prot: 3000}
    

    commonjs

    文件皆模块,直接使用module.exports导出模块,require导入

    实现逻辑:

    1. 一个名为require的方法,1个字符串入参
    2. 取绝对路径
    3. 取文件内容
    4. 根据后缀执行不同方法
    5. .js方法的:创建闭包 => vm.runInThisContext => 执行
    6. 添加缓存
    let path = require('path')
    let fs = require('fs')
    let vm = require('vm')    // 虚拟机模块
    
    function MyModule(dir) { 
      this.exports = {} 
      this.static_dir = dir
      this.ext = null
      this.file_content = null
    
      this.getStaticPath(dir)     // 取文件绝对路径
      this.getContent()           // 取文件内容
    }
    
    MyModule.prototype.getStaticPath = function (dir) {
      this.static_dir = path.resolve(__dirname, dir)    // 取文件绝对路径
      this.ext = path.extname(dir)                      // 取文件扩展名
    }
    
    MyModule.prototype.getContent = function () {
      if (this.ext) {
        this.file_content = this.readFile(this.static_dir)
      } else {
        Object.keys(MyModule.CodeHandler).forEach(key => {
          this.file_content = this.readFile(this.static_dir + key)
          if (this.file_content) {
            this.ext = key
            return false
          }
        })
      }
    }
    
    MyModule.prototype.readFile = function (dir) {
      try {
        return fs.readFileSync(dir, 'utf8')
      } catch {
        return null
      }
    }
    
    MyModule.prototype.compileCode = function () {
      if (!this.file_content) throw new Error('文件不存在')
      // 检查缓存
      if (!MyModule._cache[this.static_dir]) {
        MyModule._cache[this.static_dir] = MyModule.CodeHandler[this.ext].call(this)
      }
      return MyModule._cache[this.static_dir]
    }
    
    MyModule._cache = {}    // 缓存
    MyModule.CodeHandler = {
      '.json': function () {
        let json = JSON.parse(this.file_content)
        delete this.file_content
        return json
      },
      '.js': function () {
        // 闭包
        let true_module = `(function (module, exports, req, __dirname, __filename) { 
          ${this.file_content} 
        })`;
        delete this.file_content
    
        vm.runInThisContext(true_module)    // 无污染的eval
          // 不用call,引入文件中的this会指向global
          // 指向this.exports, 当不使用module.exports导出时,把文件内this.xxx的内容返回
          //(就像 node require 一样)
          .call(this.exports, this, this.exports, req, __dirname, __filename)
        return this.exports
      }
    }
    
    function req (dir) {
      return new MyModule(dir).compileCode()
    }
    
    
    
    let temp1 = req('./temp/runcode-node.js')
    console.log(temp1)
    console.log('-------------------------')
    let temp2 = req('./temp/runcode-node.js')
    console.log(temp2)
    console.log('-------------------------')
    let temp = require('./temp/runcode-node.js')
    console.log(temp)
    
    // ./temp/runcode-node.js
    this.b = 88
    let a = { say: 'yes, you got me', t: new Date() }
    console.log( process.argv, __filename, this, exports, '~~~')  //Object.keys( process),
    
    module.exports = a
    exports = this.b
    

    inquirer

    const inquirer = require('inquirer')
    const questions = [
      {
        type : "input",
        name : "sender.email",
        message : "Sender's email address - "
      },
      {
        type : "input",
        name : "sender.name",
        message : "Sender's name - "
      },
      {
        type: 'list',
        message: '请选择一种水果:',
        name: 'fruit',
        choices: [
            "Apple",
            "Pear",
            "Banana"
        ]
      }
    ]
    inquirer.prompt(questions).then(function (answers) {
        console.log(answers)
    })
    
    image.png

    Node Event Loop

    每个类型都有自己的队列,主栈执行完后,依次执行

    1. timer 定时器
    2. pending callback 错误?
    3. idle prepare 内部调用?
    4. poil 轮寻
    5. check 检查 -> go 1, start over
    6. close callbacks

    .
    .
    .
    .
    left knowledge points for me
    调度打点、webpack调试
    .

    相关文章

      网友评论

          本文标题:Node相关知识

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