本文目录
- 1.简单介绍下前端模块化规范:Amd,Cmd,Commonjs和ES6的module
- 2.babel的定义
- 3.babel的工作流程
- 4.Base64 的原理?编码后比编码前是大了还是小了
- 5.说一说require标识符的加载规则
1.简单介绍下前端模块化规范:Amd,Cmd,Commonjs和ES6的module
AMD
AMD是RequireJS在推广过程中对模块定义的规范化产出。
AMD规范则是异步加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
CMD
CMD是SeaJS在推广过程中对模块定义的规范化产出。
CMD是同步模块定义,注意CMD也是异步加载。
二者的区别是前者是对于依赖的模块提前执行,而后者是延迟执行。 前者推崇依赖前置,而后者推崇依赖就近,即只在需要用到某个模块的时候再require。
CommonJS
Nodejs中使用的是这个规范。CommonJS的核心思想就是通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或者 module.exports 来导出需要暴露的接口。
module.exports默认导出的是一个对象,如果在文件demo-b.js中什么代码都不写,然后在另外一个文件demo-a.js中导入这个文件
const b = require('./b')
console.log(b)
b会是一个默认的对象,如果在demo-b.js中写入module.exports = '123'
,甚至让其等于一个函数,一个变量,在别的文件导入的时候也会导入对应的字符串/函数/变量。
注意:
exports是为module.exports,在导出的时候exports.xxx = xxx就相当于是module.exports.xxx = xxx,但需要特别注意的是,不能让exports直接等于某个对象或者其它类型的数据,这样会切断exports和module.exports的联系,所以为了避免产生不必要的错误,在使用CommonJS规范的时候,统一使用module.exports.xxx= xxx导出数据。
CommonJS模块是同步加载的,即只有加载完成,才能执行后面的操作。
CommonJS输出是值的拷贝,同时模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存。
ES Module
在ES6中,我们可以使用 import 关键字引入模块,通过 exprot 关键字导出模块,功能较之于前几个方案更为强大,也是我们所推崇的。
在一个文件或模块中,export、import可以有多个,export default仅有一个。
export不能直接导出一个变量或者是一个其它类型的数据,在使用export导出时,对应的导入也需要通过{}进行解构才能获得export导出的数据,并且变量名也必须是一致的。
需要注意的是,export可以导出一个现定义的变量,比如
export const Id = {XXXX}
倒入的时候需要{}进行解构
import { Id } from 'xxxx'
export default的导出则可以自由很多,在导入的时候也可以自定义变量名,也不需要{}解构。
import 变量名 from ‘模块’
ES Module与CommonJS的对比
- CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变。
- CommonJS 模块是运行时加载,同步加载,因为node层本身的文件读写Io非常的快速,所以这种运行时的同步加载并不会带来什么显著的负面影响。而ES6 模块是编译时输出接口,支持异步加载。
- CommonJS 加载的是整个模块,即将所有的接口全部加载进来,ES6 可以单独加载其中的某个接口(方法)。
2.babel的定义
Babel 是一个 JavaScript 编译器
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
3.babel的工作流程
Babel的编译过程和大多数其他语言的编译器相似,可以分为三个阶段:
- 解析(Parsing):将代码字符串解析成抽象语法树(AST)。
- 转换(Transformation):对抽象语法树进行转换操作。
- 生成(Code Generation): 根据变换后的抽象语法树再生成代码字符串。
4.Base64 的原理?编码后比编码前是大了还是小了
Base64是一种基于用64个可打印字符来表示二进制数据的表示方法。编码后的数据比原始数据略长,为原来的4/3。
5.说一说require标识符的加载规则
1.如果是以“./”“../”“/”开头的,会被定义为路径形式的模块(./ 代表当前目录,../ 代表上一级目录, /表示的是当前所在的磁盘根路径,这种表达形式在项目中几乎不会使用。)
2.如果不是以“./”“../”“/”开头的,则会验证是否为node的核心模块,如fs,http(核心模块文件已经被编译到了二进制文件中了,我们只需要按照名字来加载就可以了)。
3.如果前两者都不是,则会按照第三方模块进行加载。
第三方模块的加载规则:
如var template = require('art-template')
- 先找到当前文件所处目录中的 node_modules 目录,看看这个目录下是否有art-template文件夹,如果有的话,则看art-template文件夹下是否有package.json 文件,
- 在package.json 文件中一般会有个main属性,这个属性中记录了这个模块的加载入口。然后加载使用这个第三方包,实际上最终加载的还是文件。
- 如果 package.json 文件不存在或者 main 指定的入口模块也没有
则 node 会自动找该目录下的 index.js,也就是说 index.js 会作为一个默认备选项 - 如果以上所有任何一个条件都不成立,则会进入上一级目录中的 node_modules 目录查找,如果上一级还没有,则继续往上上一级查找。。。
- 如果直到当前磁盘根目录还找不到,最后报错:can not find module xxx