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

工程化实战内功修炼测试题(二)

工程化实战内功修炼测试题(二)

ES6模块化

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

/** 定义模块 math.js /
var basicNum = 0;
var add = function (a, b) {
    return a + b;
};
export { basicNum, add };
/ 引用模块 **/
import { basicNum, add } from './math';
function test(ele) {
    ele.textContent = add(99 + basicNum);
}

如上例所示,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.js
export default function () {
  console.log('foo');
}

// import-default.js
import customName from './export-default';
customName(); // 'foo'

模块默认输出, 其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

ES6 模块与 CommonJS 模块的差异

  1. CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用
  2. CommonJS 模块是运行时加载,ES6 模块是编译时输出接口

CommonJS 模块是运行时加载:
CommonJS 模块就像是你把文件放到箱子里,打开箱子时它才会运行。只有当你实际使用 require() 时,模块才会加载并执行。因此,模块的 exports 只有在模块执行时才会创建和输出。

通俗例子:你拿到一本书,翻开它时才开始阅读内容,内容是等你打开后才展现的。

ES6 模块是编译时输出接口:
ES6 模块的情况则不同,它是静态的,在代码解析阶段就已经知道你在导出什么。模块之间的依赖和接口会在编译时就决定,甚至可以进行一些优化(如 tree shaking)。你导出的每个值都事先确定好了,不需要等到运行时。

通俗例子:就像你提前就知道一本书的目录,甚至可以提前知道每章的内容,不需要等到你开始阅读时再去解析。

下面重点解释第一个差异,我们还是举上面那个CommonJS模块的加载机制例子:

// lib.js
export let counter = 3;
export function incCounter() {
  counter++;
}
// main.js
import { counter, incCounter } from './lib';
console.log(counter); // 3
incCounter();
console.log(counter); // 4

ES6 模块的运行机制与 CommonJS 不一样。ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

ES6实现

简单来说就一句话:使用Babel将ES6编译为ES5代码,使用Browserify编译打包js。

  1. 定义package.json文件
 {
   "name" : "es6-babel-browserify",
   "version" : "1.0.0"
 }
  1. 安装babel-cli, babel-preset-es2015和browserify
npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev
  1. 定义.babelrc文件
  {
    "presets": ["es2015"]
  }
  1. 定义模块代码
//module1.js文件
// 分别暴露
export function foo() {
  console.log('foo() module1')
}
export function bar() {
  console.log('bar() module1')
}
//module2.js文件
// 统一暴露
function fun1() {
  console.log('fun1() module2')
}
function fun2() {
  console.log('fun2() module2')
}
export { fun1, fun2 }

//module3.js文件
// 默认暴露 可以暴露任意数据类项,暴露什么数据,接收到就是什么数据
export default () => {
  console.log('默认暴露')
}

// app.js文件
import { foo, bar } from './module1'
import { fun1, fun2 } from './module2'
import module3 from './module3'
foo()
bar()
fun1()
fun2()
module3()
  1. 编译并在index.html中引入
  • 使用Babel将ES6编译为ES5代码(但包含CommonJS语法) : babel js/src -d js/lib
  • 使用Browserify编译js : browserify js/lib/app.js -o js/lib/bundle.js
    然后在index.html文件中引入
 <script type="text/javascript" src="js/lib/bundle.js"></script> 

最后得到如下结果:

foo() module1
bar() module1
fun1() module2
fun2() module2
默认暴露
  1. 引入第三方库
    首先安装依赖npm install jquery@1,然后在app.js文件中引入
//app.js文件
import { foo, bar } from './module1'
import { fun1, fun2 } from './module2'
import module3 from './module3'
import $ from 'jquery'

foo()
bar()
fun1()
fun2()
module3()
$('body').css('background', 'green')

UMD(Universal Module Definition)

是一种 javascript 通用模块定义规范,让你的模块能在javascript所有运行环境中发挥作用
意味着要同时满足CommonJS, AMD, CMD的标准,以下为实现:

(function(root, factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        console.log('是commonjs模块规范,nodejs环境')
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        console.log('是AMD模块规范,如require.js')
        define(factory)
    } else if (typeof define === 'function' && define.cmd) {
        console.log('是CMD模块规范,如sea.js')
        define(function(require, exports, module) {
            module.exports = factory()
        })
    } else {
        console.log('没有模块环境,直接挂载在全局对象上')
        root.umdModule = factory();
    }
}(this, function() {
    return {
        name: '我是一个umd模块'
    }
}))
  1. CommonJS规范主要用于服务端编程,加载模块是同步的,这并不适合在浏览器环境,因为同步意味着阻塞加载,浏览器资源是异步加载的,因此有了AMD CMD解决方案;
  2. AMD规范在浏览器环境中异步加载模块,而且可以并行加载多个模块。不过,AMD规范开发成本高,代码的阅读和书写比较困难,模块定义方式的语义不顺畅;
  3. CMD规范与AMD规范很相似,都用于浏览器编程,依赖就近,延迟执行,可以很容易在Node.js中运行;
  4. ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案;
  5. UMD为同时满足CommonJS, AMD, CMD标准的实现;

http://www.kler.cn/a/394277.html

相关文章:

  • OceanStor Pacific系列 8.1.0 功能架构
  • C++ 并发专题 - 自旋锁的实现(Spinlock)
  • SQL,力扣题目1127, 用户购买平台
  • Spring高手之路26——全方位掌握事务监听器
  • 软件测试:测试用例详解
  • 随时随地编码:香橙派Zero3上安装Code Server远程开发指南
  • spi 回环
  • 【字典树Trie】个人练习-Leetcode-421. Maximum XOR of Two Numbers in an Array
  • 惠州石湾DELL T130服务器黄灯不开机案例
  • 百度秒哒简介
  • #渗透测试#SRC漏洞挖掘#蓝队基础之网络七层杀伤链02
  • 基于 PyTorch 从零手搓一个GPT Transformer 对话大模型
  • 二、vue指令
  • STM32 Option Bytes(选项字节)
  • 【项目组件】第三方库——websocketpp
  • Flutter 应用在真机上调试的流程
  • 【WiFi】ubuntu20.4 WiFi6 无线抓包环境搭建及使用
  • PostgreSQL 序列字段达到最大值
  • 一文窥见神经网络
  • 【QT常用技术讲解】优化网络链接不上导致qt、qml界面卡顿的问题
  • Easyui ComboBox 数据加载完成之后过滤数据
  • AutoDL远程连接技巧
  • php preg_match 不到内容,修改pcre.backtrack_limit解决问题
  • elementui el-table中给表头 el-table-column 加一个鼠标移入提示说明
  • Android 关于使用videocompressor库压缩没有声音的问题
  • GOF设计模式中各模式支持的可变方面(封装变化)