前端培训-中级阶段(46)- CommonJS 规范,模块化思想及操作

简介: 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

Node 应用由模块组成,采用 CommonJS 模块规范。


每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。


// 导出 addX
module.exports.addX = 1;
// 导入模块
example = require('./example.js');
console.log(example.addX)


commonjs 模块规范



特点


  • 所有代码运行在模块作用域,不会污染全局作用域。


  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。


  • 模块加载的顺序,按照其在代码中出现的顺序。


  • CommonJS 规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。


module对象


Node内部提供一个 Module 构建函数。所有模块都是Module的实例。每个模块内部,都有一个module对象,代表当前模块。它有以下属性。


  • module.id 模块的识别符,通常是带有绝对路径的模块文件名。


  • module.filename 模块的文件名,带有绝对路径。


  • module.loaded 返回一个布尔值,表示模块是否已经完成加载。


  • module.parent 返回一个对象,表示调用该模块的模块。


if (!module.parent) {
    // ran with `node something.js`
    app.listen(8088, function() {
        console.log('app listening on port 8088');
    })
} else {
    // used with `require('/.something.js')`
    module.exports = app;
}


  • module.children 返回一个数组,表示该模块要用到的其他模块。


  • module.exports 表示模块对外输出的值。


AMD 模块规范



CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。


由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。


AMD规范使用define方法定义模块,下面就是一个例子:


define(['package/lib'], function(lib){
  function foo(){
    lib.log('hello world!');
  }
  return {
    foo: foo
  };
});


AMD规范允许输出的模块兼容CommonJS规范,这时define方法需要写成下面这样:


define(function (require, exports, module){
  var someModule = require("someModule");
  var anotherModule = require("anotherModule");
  someModule.doTehAwesome();
  anotherModule.doMoarAwesome();
  exports.asplode = function (){
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
  };
});


ESM 模块规范



「 ESM 」 全称 ECMAScript modules,基本主流的浏览器版本都以已经支持。主要用于浏览器原生支持模块化,<script src="index.js" type="module"></script>

ESM 使用实时绑定逻辑,两个模块都指向内存中的相同位置。这意味着,当导出模块更改值时,该更改将显示在导入模块中。


这不同于 CommonJS 模块,在 CommonJS 中,整个导出对象在导出时被复制。这意味着 CommonJS 模块导出的任何值(例如数字)都是副本,如果 CommonJS 模块导出模块以后更改了该值,则导入模块将看不到该更改。


ESM 如何工作


  1. 浏览器会构建一个依赖关系图。


  1. 通过指定一个入口文件(<script src="index.js" type="module"></script>),然后从这个文件开始,通过其中的 import 语句,查找其他代码。


  1. 通过指定的文件路径, 浏览器就找到了目标代码文件。 但是浏览器并不能直接使用这些文件,它需要解析所有这些文件,以将它们转换为称为模块记录的数据结构。


  1. 模块记录 转换为 模块实例模块实例, 实际上是 「 代码 」(指令列表)与「 状态」(所有变量的值)的组合。


ESM 动态路径


因为 ESM 的特性,正常情况下是不能使用变量作为路径


// commonjs 其实是同步的,会挂起主线程去加载文件,
// 因为 commonjs 主要用于 node,从本地磁盘加载资源是很快的。
require(`${publicPath}/count.js`);
// 因为 ESM 规范是先静默分析资源去下载,所以其实在这里时变量还没有执行
import count from `${publicPath}/count.js`;
// 但是有时候又希望有这样功能,这个时候我们可以使用import动态导入功能,会启动一个新的加载过程。
import(`${path}/count.js`)


node 中使用


  1. 碰到这种兼容性的,上 babel 就 OK


  1. 社区(Node 14)尝试解决此问题的一种方法是使用 .mjs 扩展。使用该扩展名告诉Node,“此文件是一个模块”。


总结



名称 导入关键词 导出关键词 规范来源&备注
CommonJS、CJS require('path') module.exports NodeJS、同步、加载本地资源同步很快的然后马上执行
ESM、MJS import a from 'path'import() exportexport default 浏览器、异步、因为网络因素不可靠会在所有资源都加载完成才执行


  1. module.exports.foo = 'bar' 命名导出
    module.exports = 'baz' 默认导出。


  1. export const sum = (x, y) => x + y; 命名导出
    export default (x, y) => x + y; 默认导出


相关文章
|
1月前
|
缓存 前端开发
前端代码整洁与规范之CSS篇
【4月更文挑战第2天】 前端代码整洁与规范之CSS篇
66 4
|
25天前
|
前端开发 JavaScript API
前端代码书写规范
前端代码规范提升项目可维护性和团队协作效率。关注项目命名清晰简洁、一致性,组件命名使用驼峰式且具描述性。JS遵循4空格缩进,分号结束语句,CSS按逻辑排序,HTML注重语义化。注释要功能性、文档化且简洁。遵循规范能减少错误,增强团队沟通。
86 3
|
5天前
|
缓存 JavaScript 前端开发
前端小白也能懂:ES模块和CommonJS的那些事
【6月更文挑战第1天】在JavaScript的世界中,模块化是构建大型应用的关键。ES模块(ESM)和CommonJS是两种主流的模块系统,它们各自有着不同的特性和使用场景。你了解它们的区别吗?
19 2
|
26天前
|
缓存 JavaScript 前端开发
前端 JS 经典:CommonJs 规范
前端 JS 经典:CommonJs 规范
26 0
|
29天前
|
JavaScript 前端开发
前端 JS 经典:ES6 和 CommonJs 用法
前端 JS 经典:ES6 和 CommonJs 用法
23 0
|
1月前
|
前端开发
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
|
1月前
|
前端开发 JavaScript 安全
【Web 前端】怎么实现Module模块化?
【5月更文挑战第1天】【Web 前端】怎么实现Module模块化?
|
1月前
|
JavaScript 前端开发 开发者
【Web 前端】如何操作DOM元素?
【4月更文挑战第22天】【Web 前端】如何操作DOM元素?
|
1月前
|
JavaScript 前端开发 开发者
【Web 前端】JS模块化有哪些?
【4月更文挑战第22天】【Web 前端】JS模块化有哪些?
|
1月前
|
存储 缓存 JavaScript
【Web 前端】JS哪些操作会造成内存泄露?
【4月更文挑战第22天】【Web 前端】JS哪些操作会造成内存泄露?