前端培训-中级阶段(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; 默认导出


相关文章
|
11月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
381 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
前端开发 JavaScript 开发工具
前端规范
前端规范
|
前端开发 测试技术
如何从零到一建立前端规范
【10月更文挑战第6天】
274 2
|
JavaScript 前端开发 Java
VUE学习四:前端模块化,ES6和ES5如何实现模块化
这篇文章介绍了前端模块化的概念,以及如何在ES6和ES5中实现模块化,包括ES6模块化的基本用法、默认导出与混合导出、重命名export和import,以及ES6之前如何通过函数闭包和CommonJS规范实现模块化。
470 0
VUE学习四:前端模块化,ES6和ES5如何实现模块化
|
前端开发 JavaScript 开发者
深入解析前端开发中的模块化与组件化实践
【10月更文挑战第5天】深入解析前端开发中的模块化与组件化实践
342 1
|
监控 前端开发 开发者
前端代码规范 - 日志打印规范
前端代码规范 - 日志打印规范
|
缓存 JavaScript 前端开发
|
前端开发 JavaScript
前端必会的JavaScript模块化
【8月更文挑战第3天】JavaScript模块化
138 1
|
前端开发
前端代码书写规范
【8月更文挑战第15天】前端代码书写规范
560 0
|
缓存 JavaScript 前端开发
前端小白也能懂:ES模块和CommonJS的那些事
【6月更文挑战第1天】在JavaScript的世界中,模块化是构建大型应用的关键。ES模块(ESM)和CommonJS是两种主流的模块系统,它们各自有着不同的特性和使用场景。你了解它们的区别吗?
757 2

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
  • 10
    【面试题】20个常见的前端算法题,你全都会吗?
  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    521
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    195
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    192
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    147
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    252
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    365
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    160
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    96
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    162
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    228