commonjs

这篇具有很好参考价值的文章主要介绍了commonjs。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Commonjs

什么是 CommonJs

  1. CommonJs 是 js 模块化的社区规范

模块化产生的原因

  1. 随着前端页面复杂度的提升,依赖的第三方库的增加,导致的 js 依赖混乱,全局变量的污染,和命名冲突
  2. 单个 js 文件内容太多,导致了维护困难,拆分成为多个文件又会发生第一点描述的问题
  3. v8 引擎的出现,让 js 有了媲美编译型语言的运行速度,大大激励了前端开发者

CommonJS 的使用环境

  1. nodejs 实现了 CommonJS 模块化规范

CommonJs 有哪些规定

  1. 每一个文件就是一个模块
  2. 模块中的变量和函数不会污染全局(解决了全局污染和命名冲突)
  3. 提供给外部使用的内容需要导出
  4. 使用其他模块的内容需要导入 (模块的导入和导出共同解决了 js 依赖混乱的问题)
  5. 模块不会重复加载,模块第一次导入后会将第一次导入的结果缓存,下次导入时,直接使用缓存的结构
  6. 省略一些细碎的内容在下面代码中提及.....

commonJS 语法

  1. 导入
//这是导入一个模块,module.js;commonjs中规定require导入模块时可以省略.js后缀
const module1 = require("./module1");
//如果没有寻找到dir.js文件,而发现了dir路径,则寻找dir路径下package.json 的main属性指定的文件
//如果package.json未指定路径,则触发默认规则 依次查找查找 index.js index.json
const module2 = require("./dir");
//如果require不是相对路径,则会去node_module中寻找该模块,重复module1 和module2 的步骤
//如果没有node_modules 或node_modules 中不存在模块则继续向上级目录寻找node_modules,直到根目录
const module3 = require("module3");
  1. 导出
module.exports = {
  //这里输入导出的内容
};

//这也是导出
exports.a = "a";

//注意 module.exports导出和exports[属性名]导出不可共存
//module.exports会覆盖掉exports导出的内容

简易实现类 nodejs 模块化环境

const fs = require("fs");
const Path = require("path");
const vm = require("vm");
const ModuleStack = [];

function isRootDirectory(path) {
  // Windows 根路径
  const windowsRootDirectory = /^[a-zA-Z]:\\$/;
  // Unix/Linux 根路径/
  const unixRootDirectory = /^\//;

  return windowsRootDirectory.test(path) || unixRootDirectory.test(path);
}

function isRelativeDirectory(path) {
  //匹配 ../ 或者 ./开头的路径
  const relativeDirectory = /^(\.\.\/|\.\/).+/;
  return relativeDirectory.test(path);
}
// 计算node_modules路径
let computePaths = (dirname) => {
  let paths = [];
  let path = dirname;
  let node_modules = "./node_modules";
  while (
    !isRootDirectory(path) ||
    !paths.includes(Path.resolve(path, node_modules))
  ) {
    paths.push(Path.resolve(path, node_modules));
    path = Path.resolve(path, "../");
  }
  return paths;
};

function myRequire(path) {
  let truelyPath;
  if (isRelativeDirectory(path)) {
    // 获取真实路径
    truelyPath = Path.resolve(__dirname, path);
  } else {
    //获取可能的node_modules路径
    let paths = computePaths(__dirname);
    for (const item of paths) {
      truelyPath = Path.resolve(item, path);
      if (fs.existsSync(truelyPath)) {
        break;
      }
    }
    if (!truelyPath) {
      throw new Error("Can't find module " + path);
    }
  }
  // 如果缓存中有,直接返回
  if (myRequire.cache[truelyPath]) {
    return myRequire.cache[truelyPath].exports;
  }
  // 读取文件内容
  const content = fs.readFileSync(path, "utf-8");
  // 包装代码
  const wrapper = [
    "(function (exports, require, module, __filename, __dirname) { \n",
    "\n})",
  ];
  // 拼接代码
  const wrapperContent = wrapper[0] + content + wrapper[1];

  // 获取文件路径和文件名
  let dirname = Path.dirname(truelyPath);
  let filename = truelyPath;
  let parentModule =
    ModuleStack.length > 0 ? ModuleStack[ModuleStack.length - 1] : null;
  // 模块对象
  const Module = {
    id: Object.keys(myRequire.cache).length > 0 ? filename : ".",
    path: dirname,
    exports: {},
    parent: parentModule,
    filename: filename,
    loaded: false,
    children: [],
    paths: computePaths(dirname),
  };
  if (parentModule) {
    parentModule.children.push(Module);
  }
  //模块入栈
  ModuleStack.push(Module);
  // 需要运行的函数
  const moduleScope = vm.runInThisContext(wrapperContent);
  // 运行代码
  moduleScope.call(
    Module.exports,
    Module.exports,
    myRequire,
    Module,
    filename,
    dirname
  );
  // 标记模块已加载
  Module.loaded = true;
  //模块出栈
  ModuleStack.pop();
  // 缓存模块
  myRequire.cache[truelyPath] = Module;
  return Module.exports;
}

myRequire.cache = Object.create(null);

模块化的意义

  1. 解决在模块化出现之前的js依赖混乱,全局污染命名冲突的问题
  2. 模块化的出现让js代码可以拆分为多个模块共同协作,单个js文件过长的问题,降低了维护难度。
  3. 模块化的出现让js开发大型项目出现了可能

ps:当前内容为学习commonjs理解,内容正确性请谨慎甄别。文章来源地址https://www.toymoban.com/news/detail-854939.html

到了这里,关于commonjs的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端10年进化 Node.js、模块化、CommonJS、AMD、CMD、Webpack、Vue-cli、Electron-vue

    模块化的概念在软件开发领域已经存在很长时间,但在 JavaScript 中的模块化发展相对较晚。以下是对您提出的问题的回答: 提出时间:JavaScript 中的模块化概念相对较早地提出于 CommonJS 规范。CommonJS 是一种 JavaScript 模块化规范,最早在 2009 年由 Ryan Dahl 和其他社区成

    2024年02月11日
    浏览(79)
  • 什么是模块化?为什么要进行模块化开发?

    模块化是一种软件开发的设计模式,它将一个大型的软件系统划分成多个独立的模块,每个模块都有自己的功能和接口,并且能够与其他模块独立地工作。  先来一段八股文 模块化开发可以带来以下好处: 提高代码的复用性:模块化可以将代码划分成可重用的部分,降低代

    2023年04月12日
    浏览(59)
  • 【FPGA/IC】什么是模块化设计?

    FPGA/IC设计中根据模块层次的不同有两种基本的设计方法: 自下而上 方法对设计进行逐次划分的过程是从基本单元出发的,设计树最末枝上的单元是已经设计好的基本单元,或者其他项目开发好的单元或者IP。该方法先对底层的功能块进行分析,然后使用这些模块来搭建规模

    2024年03月19日
    浏览(51)
  • CommonJs规范和ES 模块系统

    CommonJS 是一种模块化规范,用于在 JavaScript 应用程序中组织和管理代码的模块。它定义了模块的导入和导出机制,使得开发者可以将代码分割成可复用的模块,并在不同的文件中引用和使用这些模块。 CommonJS 规范有以下几个主要 特点 和 用途 : 模块化组织代码 :CommonJS 允许

    2024年02月12日
    浏览(40)
  • 008Node.js模块、自定义模块和CommonJs

    CommonJS API定义很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极目标是提供一个类似Python,Ruby和Java标 准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后这些应用可以运行在不同的JavaScript解释器和不同的主机环境中。在兼容

    2024年04月13日
    浏览(39)
  • 如何在Vue中进行单元测试?什么是Vue的模块化开发?

    在Vue中进行单元测试可以提高代码的可维护性和可读性,同时也能够帮助开发者更快地找到代码中的问题和潜在的错误。下面是一些在Vue中进行单元测试的步骤: 安装单元测试工具 首先需要安装一个单元测试工具,例如Jest或Mocha。可以使用npm或yarn进行安装。 创建测试文件

    2024年02月12日
    浏览(42)
  • 【ES6】CommonJS模块和ES6模块

    在JavaScript中,模块是一种将功能代码组织成逻辑单元的方式,以便在其他项目中重复使用。有两种主要的模块系统:CommonJS和ES6。 1、CommonJS 在CommonJS中,我们使用require来引入模块,使用module.exports来导出模块。 下面是一个简单的例子: 然后,在另一个文件中,我们可以使用

    2024年02月09日
    浏览(49)
  • 前端面试:【前端工程化】CommonJS 与 ES6 模块

    嗨,亲爱的前端开发者!在现代Web开发中,模块化是构建可维护和可扩展应用程序的关键。本文将深入探讨两种主要的JavaScript模块系统:CommonJS 和 ES6 模块,以帮助你了解它们的工作原理、用法以及如何选择合适的模块系统。 1. CommonJS: 用途: CommonJS 是一种模块系统,最初

    2024年02月11日
    浏览(55)
  • 模块化与单片化优缺点解析:为什么单片链仍是 DeFi 协议的最好选择?

    目前模块化区块链热度不减,其诞生的原因源自于单片链的局限和缺陷。  什么是」模块化「? 在软件工程开发中,」模块化「是指将代码进行解耦, 使每个模块的功能独立, 模块之间的耦合程度低, 达到模块复用的目的。  模块化的本质是一种任务分工,不同的模块组合成的程

    2023年04月09日
    浏览(40)
  • CommonJS 和 ES6 Module:一场模块规范的对决(上)

    🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入

    2024年01月23日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包