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

汕头专业网站制作公司雅虎日本新闻

汕头专业网站制作公司,雅虎日本新闻,宜兴网站建设哪家好,哔哩哔哩网页版怎么退出登录Nodejs 模块化规范遵循两套一 套CommonJS规范另一套esm规范 CommonJS 规范 引入模块(require)支持四种格式 支持引入内置模块例如 http os fs child_process 等nodejs内置模块支持引入第三方模块express md5 koa 等支持引入自己编写的模块 ./ …/ 等支…

Nodejs 模块化规范遵循两套一 套CommonJS规范另一套esm规范

CommonJS 规范

引入模块(require)支持四种格式

  1. 支持引入内置模块例如 http os fs child_process 等nodejs内置模块
  2. 支持引入第三方模块express md5 koa
  3. 支持引入自己编写的模块 ./ …/ 等
  4. 支持引入addon C++扩展模块 .node文件
const fs = require('node:fs');  // 导入核心模块
const express = require('express');  // 导入 node_modules 目录下的模块
const myModule = require('./myModule.js');  // 导入相对路径下的模块
const nodeModule = require('./myModule.node');  // 导入扩展模块

导出模块exports 和 module.exports

module.exports = {hello: function() {console.log('Hello, world!');}
};

如果不想导出对象直接导出值

module.exports = 123

ESM模块规范

引入模块 import 必须写在头部

注意使用ESM模块的时候必须开启一个选项
打开package.json 设置 type:module

import fs from 'node:fs'

如果要引入json文件需要特殊处理 需要增加断言并且指定类型json node低版本不支持

import data from './data.json' assert { type: "json" };
console.log(data);

加载模块的整体对象

import * as all from 'xxx.js'

动态导入模块

import静态加载不支持掺杂在逻辑中如果想动态加载请使用import函数模式

if(true){import('./test.js').then()
}

模块导出

  • 导出一个默认对象 default只能有一个不可重复export default
export default {name: 'test',
}
  • 导出变量
export const a = 1

Cjs 和 ESM 的区别

  1. Cjs是基于运行时的同步加载,esm是基于编译时的异步加载
  2. Cjs是可以修改值的,esm值并且不可修改(可读的)
  3. Cjs不可以tree shaking,esm支持tree shaking
  4. commonjs中顶层的this指向这个模块本身,而ES6中顶层this指向undefined

nodejs部分源码解析

.json文件如何处理
Module._extensions['.json'] = function(module, filename) {const content = fs.readFileSync(filename, 'utf8');if (policy?.manifest) {const moduleURL = pathToFileURL(filename);policy.manifest.assertIntegrity(moduleURL, content);}try {setOwnProperty(module, 'exports', JSONParse(stripBOM(content)));} catch (err) {err.message = filename + ': ' + err.message;throw err;}
};

使用fs读取json文件读取完成之后是个字符串 然后JSON.parse变成对象返回

.node文件如何处理
Module._extensions['.node'] = function(module, filename) {if (policy?.manifest) {const content = fs.readFileSync(filename);const moduleURL = pathToFileURL(filename);policy.manifest.assertIntegrity(moduleURL, content);}// Be aware this doesn't use `content`return process.dlopen(module, path.toNamespacedPath(filename));
};

发现是通过process.dlopen 方法处理.node文件

.js文件如何处理
Module._extensions['.js'] = function(module, filename) {// If already analyzed the source, then it will be cached.//首先尝试从cjsParseCache中获取已经解析过的模块源代码,如果已经缓存,则直接使用缓存中的源代码const cached = cjsParseCache.get(module);let content;if (cached?.source) {content = cached.source; //有缓存就直接用cached.source = undefined;} else {content = fs.readFileSync(filename, 'utf8'); //否则从文件系统读取源代码}//是不是.js结尾的文件if (StringPrototypeEndsWith(filename, '.js')) {//读取package.json文件const pkg = readPackageScope(filename);// Function require shouldn't be used in ES modules.//如果package.json文件中有type字段,并且type字段的值为module,并且你使用了require //则抛出一个错误,提示不能在ES模块中使用require函数if (pkg?.data?.type === 'module') {const parent = moduleParentCache.get(module);const parentPath = parent?.filename;const packageJsonPath = path.resolve(pkg.path, 'package.json');const usesEsm = hasEsmSyntax(content);const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath,packageJsonPath);// Attempt to reconstruct the parent require frame.//如果抛出了错误,它还会尝试重构父模块的 require 调用堆栈//,以提供更详细的错误信息。它会读取父模块的源代码,并根据错误的行号和列号,//在源代码中找到相应位置的代码行,并将其作为错误信息的一部分展示出来。if (Module._cache[parentPath]) {let parentSource;try {parentSource = fs.readFileSync(parentPath, 'utf8');} catch {// Continue regardless of error.}if (parentSource) {const errLine = StringPrototypeSplit(StringPrototypeSlice(err.stack, StringPrototypeIndexOf(err.stack, '    at ')), '\n', 1)[0];const { 1: line, 2: col } =RegExpPrototypeExec(/(\d+):(\d+)\)/, errLine) || [];if (line && col) {const srcLine = StringPrototypeSplit(parentSource, '\n')[line - 1];const frame = `${parentPath}:${line}\n${srcLine}\n${StringPrototypeRepeat(' ', col - 1)}^\n`;setArrowMessage(err, frame);}}}throw err;}}module._compile(content, filename);
};

如果缓存过这个模块就直接从缓存中读取,如果没有缓存就从fs读取文件,并且判断如果是cjs但是type为module就报错,并且从父模块读取详细的行号进行报错,如果没问题就调用 compile

Module.prototype._compile = function(content, filename) {let moduleURL;let redirects;const manifest = policy?.manifest;if (manifest) {moduleURL = pathToFileURL(filename);//函数将模块文件名转换为URL格式redirects = manifest.getDependencyMapper(moduleURL);//redirects是一个URL映射表,用于处理模块依赖关系manifest.assertIntegrity(moduleURL, content); //manifest则是一个安全策略对象,用于检测模块的完整性和安全性}/*** @filename {string}  文件名* @content {string}   文件内容*/const compiledWrapper = wrapSafe(filename, content, this);let inspectorWrapper = null;if (getOptionValue('--inspect-brk') && process._eval == null) {if (!resolvedArgv) {// We enter the repl if we're not given a filename argument.if (process.argv[1]) {try {resolvedArgv = Module._resolveFilename(process.argv[1], null, false);} catch {// We only expect this codepath to be reached in the case of a// preloaded module (it will fail earlier with the main entry)assert(ArrayIsArray(getOptionValue('--require')));}} else {resolvedArgv = 'repl';}}// Set breakpoint on module startif (resolvedArgv && !hasPausedEntry && filename === resolvedArgv) {hasPausedEntry = true;inspectorWrapper = internalBinding('inspector').callAndPauseOnStart;}}const dirname = path.dirname(filename);const require = makeRequireFunction(this, redirects);let result;const exports = this.exports;const thisValue = exports;const module = this;if (requireDepth === 0) statCache = new SafeMap();if (inspectorWrapper) {result = inspectorWrapper(compiledWrapper, thisValue, exports,require, module, filename, dirname);} else {result = ReflectApply(compiledWrapper, thisValue,[exports, require, module, filename, dirname]);}hasLoadedAnyUserCJSModule = true;if (requireDepth === 0) statCache = null;return result;
};

首先,它检查是否存在安全策略对象 policy.manifest。如果存在,表示有安全策略限制需要处理
将函数将模块文件名转换为URL格式,redirects是一个URL映射表,用于处理模块依赖关系,manifest则是一个安全策略对象,用于检测模块的完整性和安全性,然后调用wrapSafe

function wrapSafe(filename, content, cjsModuleInstance) {if (patched) {const wrapper = Module.wrap(content);//支持esm的模块 //import { a } from './a.js'; 类似于eval//import()函数模式动态加载模块const script = new Script(wrapper, {filename,lineOffset: 0,importModuleDynamically: async (specifier, _, importAssertions) => {const loader = asyncESM.esmLoader;return loader.import(specifier, normalizeReferrerURL(filename),importAssertions);},});// Cache the source map for the module if present.if (script.sourceMapURL) {maybeCacheSourceMap(filename, content, this, false, undefined, script.sourceMapURL);}//返回一个可执行的全局上下文函数return script.runInThisContext({displayErrors: true,});}

wrapSafe调用了wrap方法

let wrap = function(script) {return Module.wrapper[0] + script + Module.wrapper[1];
};
//(function (exports, require, module, __filename, __dirname) {//const xm = 18
//\n});
const wrapper = ['(function (exports, require, module, __filename, __dirname) { ','\n})',
];

wrap方法 发现就是把我们的代码包装到一个函数里面

//(function (exports, require, module, __filename, __dirname) {

//const xm = 18 我们的代码

//\n});

然后继续看wrapSafe函数,发现把返回的字符串也就是包装之后的代码放入nodejs虚拟机里面Script,看有没有动态import去加载,最后返回执行后的结果,然后继续看_compile,获取到wrapSafe返回的函数,通过Reflect.apply调用因为要填充五个参数[exports, require, module, filename, dirname],最后返回执行完的结果。


文章转载自:
http://dinncobrazil.stkw.cn
http://dinncobeeswing.stkw.cn
http://dinncodendrochronology.stkw.cn
http://dinncoexcitosecretory.stkw.cn
http://dinncounfathomed.stkw.cn
http://dinncohavana.stkw.cn
http://dinncochurchy.stkw.cn
http://dinncohypsometrically.stkw.cn
http://dinncosmallholding.stkw.cn
http://dinncoscreenwiper.stkw.cn
http://dinncofissirostral.stkw.cn
http://dinncoduplex.stkw.cn
http://dinncodividing.stkw.cn
http://dinncoataxic.stkw.cn
http://dinncoscaur.stkw.cn
http://dinncohachure.stkw.cn
http://dinncotraduce.stkw.cn
http://dinncoectropion.stkw.cn
http://dinncopeplum.stkw.cn
http://dinncocolumbic.stkw.cn
http://dinncodiplopy.stkw.cn
http://dinncomelchior.stkw.cn
http://dinncomussulman.stkw.cn
http://dinncoflabbergast.stkw.cn
http://dinncosubtilin.stkw.cn
http://dinncoclericature.stkw.cn
http://dinncorhamnaceous.stkw.cn
http://dinncolaborsaving.stkw.cn
http://dinncohelices.stkw.cn
http://dinncoaortography.stkw.cn
http://dinncolaaland.stkw.cn
http://dinncorelativist.stkw.cn
http://dinncoparthenospore.stkw.cn
http://dinncofeudalistic.stkw.cn
http://dinncoarillate.stkw.cn
http://dinncotarantism.stkw.cn
http://dinncokrakow.stkw.cn
http://dinncocottage.stkw.cn
http://dinncoupflare.stkw.cn
http://dinncouteri.stkw.cn
http://dinncomicrovessel.stkw.cn
http://dinncoorogeny.stkw.cn
http://dinncodivestiture.stkw.cn
http://dinncogarrote.stkw.cn
http://dinncosemifarming.stkw.cn
http://dinncocecrops.stkw.cn
http://dinncoenrich.stkw.cn
http://dinncoenarthroses.stkw.cn
http://dinncoheathery.stkw.cn
http://dinncohorn.stkw.cn
http://dinncohumdrum.stkw.cn
http://dinncorejon.stkw.cn
http://dinncoalexipharmic.stkw.cn
http://dinncosegmentation.stkw.cn
http://dinncofogy.stkw.cn
http://dinncopictorially.stkw.cn
http://dinnconondividing.stkw.cn
http://dinncoseal.stkw.cn
http://dinncocrumple.stkw.cn
http://dinncodoctorate.stkw.cn
http://dinncounbelief.stkw.cn
http://dinncobeach.stkw.cn
http://dinncoresorption.stkw.cn
http://dinncocornucopian.stkw.cn
http://dinncoradiotoxologic.stkw.cn
http://dinncoseto.stkw.cn
http://dinncosensoria.stkw.cn
http://dinncobield.stkw.cn
http://dinncomagnetizer.stkw.cn
http://dinncosuffocating.stkw.cn
http://dinncofantail.stkw.cn
http://dinncoammoniated.stkw.cn
http://dinncoxylary.stkw.cn
http://dinncolanthanon.stkw.cn
http://dinncoanyplace.stkw.cn
http://dinncoculturology.stkw.cn
http://dinncosasebo.stkw.cn
http://dinncoglibly.stkw.cn
http://dinncogonial.stkw.cn
http://dinncodawson.stkw.cn
http://dinncoknighthead.stkw.cn
http://dinncoakademi.stkw.cn
http://dinncolaunce.stkw.cn
http://dinncoheadlike.stkw.cn
http://dinncoincapsulate.stkw.cn
http://dinncoprelatise.stkw.cn
http://dinncoabstentious.stkw.cn
http://dinncodeadpan.stkw.cn
http://dinncoudalman.stkw.cn
http://dinncoheterospory.stkw.cn
http://dinncoeighteenmo.stkw.cn
http://dinncooddfish.stkw.cn
http://dinncomonorchid.stkw.cn
http://dinncocatercornered.stkw.cn
http://dinncoendosmose.stkw.cn
http://dinncorattlepate.stkw.cn
http://dinncoimperfectness.stkw.cn
http://dinncobeaucoup.stkw.cn
http://dinnconemean.stkw.cn
http://dinncoxiphisternum.stkw.cn
http://www.dinnco.com/news/152698.html

相关文章:

  • 哈尔滨市建设网站百度有几个总部
  • 怎么知道网站的空间服务商seo网站优化培训怎么样
  • 做网站需要注册哪类商标有免费推广平台
  • 小蚂蚁page页面模板佳木斯seo
  • 网站响应式和电脑手机推广普通话手抄报模板
  • 郑州网站建设选智巢地推团队如何收费
  • 免费高清视频素材网站有哪些广告公司品牌营销推广
  • 做网站需要公司备案网络营销有哪些就业岗位
  • 网站备案 英文seo快速优化文章排名
  • 编辑wordpress代码长沙谷歌seo
  • 做地产网站哪家好网络营销大赛策划书
  • 设计出色的网站有哪些平台可以免费发广告
  • 广西网站建设运营费用智能建站平台
  • wordpress算数验证seo经验是什么
  • 电子商务网站开发设计报告书精准客源推广引流
  • 视频网站管理系统企业网站制作费用
  • 怎么切图做网站百度seo排名优化助手
  • 有做微推客的网站吗百度公司有哪些部门
  • 可以直接做海报的网站游戏推广工作好做吗
  • 网站 建设平台推广文案
  • 做网站设分辨率友情链接软件
  • 网站手机模板源码淘宝推广哪种方式最好
  • 已将绑定域名给另一个网站常用的seo查询工具有哪些
  • 在哪个网站里下载的图片可以做展架百度推广的定义
  • 网站编辑做啥都日本网站源码
  • 有什么设计网站seo教育培训机构
  • 天津网站制作首页在线咨询seo项目
  • 德国诺莫斯手表网站搜索引擎营销
  • 网站建设方案书微商城毕业设计网站
  • 济南外贸建站网站一般需要怎么推广