当前位置: 首页 > news >正文

南京集团网站建设不用登录的传奇游戏

南京集团网站建设,不用登录的传奇游戏,施工企业会计核算实务,黄山网站建设jidela了解Node.js Node.js是一个基于ChromeV8引擎的JavaScript运行环境#xff0c;使用了一个事件驱动、非阻塞式I/O模型#xff0c;让JavaScript 运行在服务端的开发平台#xff0c;它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。Node中增添了很…了解Node.js Node.js是一个基于ChromeV8引擎的JavaScript运行环境使用了一个事件驱动、非阻塞式I/O模型让JavaScript 运行在服务端的开发平台它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。Node中增添了很多内置的模块提供各种各样的功能同时也提供许多第三方模块。 模块的问题 为什么要有模块 复杂的前端项目需要做分层处理按照功能、业务、组件拆分成模块 模块化的项目至少有以下优点 便于单元测试便于同事间协作抽离公共方法, 开发快捷按需加载, 性能优秀高内聚低耦合防止变量冲突方便代码项目维护 几种模块化规范 CMD(SeaJS 实现了 CMD)AMD(RequireJS 实现了 AMD)UMD(同时支持 AMD 和 CMD)IIFE 自执行函数CommonJS Node 采用了 CommonJSES Module 规范 (JS 官方的模块化方案) Node中的模块 Node中采用了 CommonJS 规范 实现原理 Node中会读取文件拿到内容实现模块化 Require方法 同步引用 tipsNode中任何js文件都是一个模块每一个文件都是模块 Node中模块类型 内置模块属于核心模块无需安装在项目中不需要相对路径引用 Node自身提供。文件模块程序员自己书写的js文件模块。第三方模块 需要安装 安装之后不用加路径。 Node中内置模块 fs filesystem 操作文件都需要用到这个模块 const path require(path); // 处理路径 const fs require(fs); // file system // // 同步读取 let content fs.readFileSync(path.resolve(__dirname, test.js), utf8); console.log(content);let exists fs.existsSync(path.resolve(__dirname, test1.js)); console.log(exists); path 路径处理 const path require(path); // 处理路径// join / resolve 用的时候可以混用console.log(path.join(a, b, c, .., /))// 根据已经有的路径来解析绝对路径 可以用他来解析配置文件 console.log(path.resolve(a, b, /)); // resolve 不支持/ 会解析成根路径console.log(path.join(__dirname, a)) console.log(path.extname(1.js)) console.log(path.dirname(__dirname)); // 解析父目录 vm 运行代码 字符串如何能变成 JS 执行呢 1.eval eval中的代码执行时的作用域为当前作用域。它可以访问到函数中的局部变量。 let test global scope global.test1 123 function b(){test fn scopeeval(console.log(test)); //local scopenew Function(console.log(test1))() // 123new Function(console.log(test))() //global scope } b() 2.new Function new Function()创建函数时不是引用当前的词法环境而是引用全局环境,Function中的表达式使用的变量要么是传入的参数要么是全局的值 Function可以获取全局变量所以它还是可能会有变量污染的情况出现 function getFn() {let value testlet fn new Function(console.log(value))return fn }getFn()()global.a 100 // 挂在到全局对象global上 new Function(console.log(a))() // 100 3.vm 前面两种方式我们一直强调一个概念那就是变量的污染 VM的特点就是不受环境的影响也可以说他就是一个沙箱环境 在Node中全局变量是在多个模块下共享的所以尽量不要在global中定义属性 所以vm.runInThisContext可以访问到global上的全局变量但是访问不到自定义的变量。而vm.runInNewContext访问不到global也访问不到自定义变量他存在于一个全新的执行上下文 const vm require(vm) global.a 1 // vm.runInThisContext(console.log(a)) vm.runInThisContext(a 100) // 沙箱独立的环境 console.log(a) // 1 vm.runInNewContext(console.log(a)) console.log(a) // a is not defined Node模块化的实现 node中是自带模块化机制的每个文件就是一个单独的模块并且它遵循的是CommonJS规范也就是使用require的方式导入模块通过module.export的方式导出模块。 node模块的运行机制也很简单其实就是在每一个模块外层包裹了一层函数有了函数的包裹就可以实现代码间的作用域隔离。 我们先在一个js文件中直接打印arguments得到的结果如下图所示我们先记住这些参数。 console.log(arguments) // exports, require, module, __filename, __dirname Node中通过modules.export 导出require 引入。其中require依赖node中的fs模块来加载模块文件通过fs.readFile读取到的是一个字符串。 在javascrpt中可以通过eval或者new Function的方式来将一个字符串转换成js代码来运行。但是前面提到过他们都有一个致命的问题就是变量的污染。 实现require模块加载器 首先导入依赖的模块pathfs,vm, 并且创建一个Require函数这个函数接收一个modulePath参数表示要导入的文件路径 const path require(path); const fs require(fs); const vm require(vm); // 定义导入类参数为模块路径 function Require(modulePath) {... } 在Require中获取到模块的绝对路径使用fs加载模块这里读取模块内容使用new Module来抽象使用tryModuleLoad来加载模块内容Module和tryModuleLoad稍后实现Require的返回值应该是模块的内容也就是module.exports。 // 定义导入类参数为模块路径 function Require(modulePath) {// 获取当前要加载的绝对路径let absPathname path.resolve(__dirname, modulePath);// 创建模块新建Module实例const module new Module(absPathname);// 加载当前模块tryModuleLoad(module);// 返回exports对象return module.exports; } Module的实现就是给模块创建一个exports对象tryModuleLoad执行的时候将内容加入到exports中id就是模块的绝对路径。 // 定义模块, 添加文件id标识和exports属性 function Module(id) {this.id id;// 读取到的文件内容会放在exports中this.exports {}; } node模块是运行在一个函数中这里给Module挂载静态属性wrapper里面定义一下这个函数的字符串wrapper是一个数组数组的第一个元素就是函数的参数部分其中有exportsmoduleRequire__dirname__filename, 都是模块中常用的全局变量. 第二个参数就是函数的结束部分。两部分都是字符串使用的时候将他们包裹在模块的字符串外部就可以了。 // 定义包裹模块内容的函数 Module.wrapper [(function(exports, module, Require, __dirname, __filename) {,}) ] _extensions用于针对不同的模块扩展名使用不同的加载方式比如JSON和javascript加载方式肯定是不同的。JSON使用JSON.parse来运行。 javascript使用vm.runInThisContext来运行可以看到fs.readFileSync传入的是module.id也就是Module定义时候id存储的是模块的绝对路径读取到的content是一个字符串使用Module.wrapper来包裹一下就相当于在这个模块外部又包裹了一个函数也就实现了私有作用域。 使用call来执行fn函数第一个参数改变运行的this传入module.exports后面的参数就是函数外面包裹参数exports, module, Require, __dirname, __filename。/ // 定义扩展名不同的扩展名加载方式不同实现js和json Module._extensions {.js(module) {const content fs.readFileSync(module.id, utf8);const fnStr Module.wrapper[0] content Module.wrapper[1];const fn vm.runInThisContext(fnStr);fn.call(module.exports, module.exports, module, Require,__filename,__dirname);},.json(module) {const json fs.readFileSync(module.id, utf8);module.exports JSON.parse(json); // 把文件的结果放在exports属性上} } tryModuleLoad函数接收的是模块对象通过path.extname来获取模块的后缀名然后使用Module._extensions来加载模块。 // 定义模块加载方法 function tryModuleLoad(module) {// 获取扩展名const extension path.extname(module.id);// 通过后缀加载当前模块Module._extensions[extension](module); // 策略模式 } 到此Require加载机制基本就写完了。Require加载模块的时候传入模块名称在Require方法中使用path.resolve(__dirname, modulePath)获取到文件的绝对路径。然后通过new Module实例化的方式创建module对象将模块的绝对路径存储在module的id属性中在module中创建exports属性为一个json对象。 使用tryModuleLoad方法去加载模块tryModuleLoad中使用path.extname获取到文件的扩展名然后根据扩展名来执行对应的模块加载机制。 最终将加载到的模块挂载module.exports中。tryModuleLoad执行完毕之后module.exports已经存在了直接返回就可以了。 接下来我们给模块添加缓存。就是文件加载的时候将文件放入缓存中再去加载模块时先看缓存中是否存在如果存在直接使用如果不存在再去重新加载加载之后再放入缓存。 // 定义导入类参数为模块路径 function Require(modulePath) {// 获取当前要加载的绝对路径let absPathname path.resolve(__dirname, modulePath);// 从缓存中读取如果存在直接返回结果if (Module._cache[absPathname]) {return Module._cache[absPathname].exports;}// 创建模块新建Module实例const module new Module(absPathname);// 添加缓存Module._cache[absPathname] module;// 加载当前模块tryModuleLoad(module);// 返回exports对象return module.exports; } 增加功能省略模块后缀名。 自动给模块添加后缀名实现省略后缀名加载模块其实也就是如果文件没有后缀名的时候遍历一下所有的后缀名看一下文件是否存在。 // 定义导入类参数为模块路径 function Require(modulePath) {// 获取当前要加载的绝对路径let absPathname path.resolve(__dirname, modulePath);// 获取所有后缀名const extNames Object.keys(Module._extensions);let index 0;// 存储原始文件路径const oldPath absPathname;function findExt(absPathname) {if (index extNames.length) {return throw new Error(文件不存在);}try {fs.accessSync(absPathname);return absPathname;} catch(e) {const ext extNames[index];findExt(oldPath ext);}}// 递归追加后缀名判断文件是否存在absPathname findExt(absPathname);// 从缓存中读取如果存在直接返回结果if (Module._cache[absPathname]) {return Module._cache[absPathname].exports;}// 创建模块新建Module实例const module new Module(absPathname);// 添加缓存Module._cache[absPathname] module;// 加载当前模块tryModuleLoad(module);// 返回exports对象return module.exports; } 源代码调试 我们可以通过VSCode 调试Node.js 步骤 创建文件a.js module.exports abc 1.文件test.js let r require(./a)console.log(r) 1.配置debug本质是配置.vscode/launch.json文件而这个文件的本质是能提供多个启动命令入口选择。 一些常见参数如下 program控制启动文件的路径即入口文件name下拉菜单中显示的名称该命令对应的入口名称request分为 launch启动和 attach附加进程已经启动skipFiles指定单步调试跳过的代码runtimeExecutable设置运行时可执行文件默认是 node可以设置成 nodemonts-nodenpm 等 修改launch.jsonskipFiles指定单步调试跳过的代码 将test.js 文件中的require方法所在行前面打断点执行调试进入源码相关入口方法 梳理代码步骤 1.首先进入到进入到require方法Module.prototype.require 2.调试到Module._load 方法中该方法返回module.exportsModule._resolveFilename方法返回处理之后的文件地址将文件改为绝对地址同时如果文件没有后缀就加上文件后缀。 3.这里定义了Module类。id为文件名。此类中定义了exports属性 4.接着调试到module.load 方法该方法中使用了策略模式Module._extensions[extension](this, filename)根据传入的文件后缀名不同调用不同的方法 5.进入到该方法中看到了核心代码读取传入的文件地址参数拿到该文件中的字符串内容执行module._compile 6.此方法中执行wrapSafe方法。将字符串前后添加函数前后缀并用Node中的vm模块中的runInthisContext方法执行字符串便直接执行到了传入文件中的console.log代码行内容。 至此整个Node中实现require方法的整个流程代码已经调试完毕通过对源代码的调试可以帮助我们学习其实现思路代码风格及规范有助于帮助我们实现工具库提升我们的代码思路同时我们知道相关原理也对我们解决日常开发工作中遇到的问题提供帮助。 作者京东物流 乔盼盼 来源京东云开发者社区 自猿其说Tech 转载请注明来源
http://www.sadfv.cn/news/469230/

相关文章:

  • 山西品牌网站建设建网站 京公网安
  • 网站建设七大步骤平江县网站建设
  • 最流行网站开发工具wordpress发布模块
  • 做网站毕业实训报告企业网站php模板
  • 用织梦做房产网站成都最好的设计院
  • 一个做特卖的网站全网网络营销系统
  • 做网站要买什么wordpress律师模板
  • 网站建设综合实践 教材网页原型设计模板
  • 自己做网站送外卖金山区做网站吗
  • 建设网站需要几个人完成温州人才网招聘网官网
  • 网站开发的费用申请有哪些网站建设企业
  • 网站制作用什么软件网页设计工作室
  • 绍兴易网网站开发wordpress 文章 作者
  • 多配色创意metro风格企业网站织梦模板整一个新网站要怎么做seo
  • 上海娱乐场所最新规定seo 首页
  • 帮人网站开发维护违法wordpress文章语音插件
  • 购物节优惠卷网站怎么做拼多多一件代发免费货源
  • dede网站模板页在什么文件夹国内网站用django做的
  • 外贸建个网站多少钱wordpress招商
  • 前端做网站使用的软件工具网站正在建设中的素材动图
  • app开发与网站建设难度网上做网站网站代理
  • 广州大型网站建设公司门户网站建设信息化项目背景
  • 东莞营销型手机网站建设wordpress设置cdn
  • 作网站流程如何申请企业邮箱注册
  • 西宁网站设计制作做企业网站域名
  • 图书大厦网站建设报告河南建设工程协会网站
  • 网站建设html代码如何添加星速浏览器
  • 网站建设 万网 域名wordpress发卡
  • 展示类网站cms网页视频怎么下载下来
  • 广告网站海外seo是什么