使用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导入
实现逻辑:
- 一个名为require的方法,1个字符串入参
- 取绝对路径
- 取文件内容
- 根据后缀执行不同方法
- .js方法的:创建闭包 => vm.runInThisContext => 执行
- 添加缓存
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)
})
Node Event Loop
每个类型都有自己的队列,主栈执行完后,依次执行
- timer 定时器
- pending callback 错误?
- idle prepare 内部调用?
- poil 轮寻
- check 检查 -> go 1, start over
- close callbacks
.
.
.
.
left knowledge points for me
调度打点、webpack调试
.