模块化:ES Module与commonJS
作者:互联网
模块化以及模块化开发:
模块化开发的目的是将程序划分成一个个小的结构,这个结构有属于自己的代码逻辑,有自己的作用域,不会影响到其他的结构,这个结构希望暴露的变量,函数,对象给其他结构使用,也可以通过某种方式导入其他结构的变量,函数,对象
上面这种结构叫模块,按照这种结构划分开发的过程,就是模块化开发的过程
ES6才开始有的模块化(ES Module),在此之前,为了支持模块化,有很多模块化规范:AMD(异步加载,提前加载,依赖前置 require.js curl.js),CMD(异步加载,按需加载,依赖就近 seajs ),Commonjs(vue cli/ creat-react-app是基于webpack,webpack基于node,node支持commonjs)
ES Module、CommonJS、AMD、CMD规范 - 要慢慢来 - 博客园
再次梳理AMD、CMD、CommonJS、ES6 Module的区别_雾空-CSDN博客
AMD与CMD的区别_chongtui4043的博客-CSDN博客
Commonjs:社区里面的一种规范,node是这种规范的一种实现,建成CJS,webpack打包工具具备对Commonjs的支持和转换
module.exports = {
mode:
entry:
output:
}
exports和module.exports可以负责模块内容的导出
require函数帮我们导入其他模块(自定义,系统,第三方库)的内容
// a.js
var name = 'wy'
var age = 18
module.exports = { //导出
name,
age
}
// b.js
const {name ,age}= require('./a') // 导入
console.log(name,'name');
console.log(age, 'age');
第二种方法:
// a.js
var name = 'wy'
var age = 18
exports.name = name
exports.age = age
// b.js
const {name ,age}= require('./a')
console.log(name,'name');
console.log(age, 'age');
源码:
module.exports = { }
exports = module.exports
module.exports和exports指向同一片内存,exports添加属性,module.exports也会添加 ,最终导出的一定是module.exports
// a.js
var name = 'wy'
var age = 18
exports = { // 这种方法不可取,因为新开辟了一块内存空间
name,
age
}
// b.js
const {name ,age}= require('./a') // 导入
console.log(name,'name');
console.log(age, 'age');
require工作原理:
是一个函数,能够引入一个文件被导出的对象
require(X) X不同,查找规则不同
情况一,X是node的核心模块(path,http )直接返回核心模块,不再查找
require('path')
情况二:路径 , ./当前路径 /电脑的跟路径
require('./abc')
第一步:将abc当作文件在对应目录查找
有后缀:按照后缀查找相应的文件
没有后缀:先查找abc文件,然后找abc.js文件,然后找abc.json 文件,最后找abc.node文件,
第二步:没找到对应文件,将abc作为目录
查找abc/index.js 文件,然后找abc/index.json 文件,最后找adc.node文件
情况三:不是路径也不是核心模块,引入第三方库
const axios = require('axios')
axios.get()
如果上面都不符合,报错:no found
模块加载的过程:
第一次引入时,js中的代码会被运行一次
多次加载,会缓存,最终只会运行一次(原理:每个模块都有一个module的属性,false表示还没加载完,true表示加载完毕)
图结构分为:深度优先和广度优先,node采用深度优先
循环引入的模块加载顺序:main - aaa -ccc - ddd -eee - bbb (深度优先)
commonjs缺点:加载模块是同步的,只有加载完毕模块才能被运行,(在服务器不会有问题,因为服务器加载的js文件都是本地文件, 速度很快)在浏览器中不太适合,加载时文件需要从服务器中下载下来,才会运行,不然会导致后续代码无法运行,所以在浏览器不使用commonjs ,但是webpack会使用commonjs是另外一回事,因为人家会将代码转化成浏览器可执行的代码。
ES Module:(严格模式)
ES Module与commonJS不同之处:
export 负责导出 ,import负责导入
导出基本使用
// index.html
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 需要加type='module'-->
// main.js
import { name,age } from "./foo.js";
console.log(name,'name');
console.log(age, 'age');
// foo.js
export const name = 'wy'
export const age = 18
需要用到vscode 插件Live Server
导出第二种方式 export导出和声明分开
// index.html
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 需要加type='module'-->
// main.js
import { name,age } from "./foo.js";
console.log(name,'name');
console.log(age, 'age');
// foo.js
const name = 'wy'
const age = 18
export {
name, age
}
// 导出第三种方式 第二种的升级版: 取别名
// index.html
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 需要加type='module'-->
// main.js
import { fName, fAge } from "./foo.js";
console.log(fName,'fName');
console.log(fAge, 'fAge');
// foo.js
const name = 'wy'
const age = 18
export {
name as fName,
age as fAge
}
导入的方式: 以上都是方式一,基本使用
导入第二种方式 导入时起别名
// index.html
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 需要加type='module'-->
// main.js
import { name as fName,age as fAge } from "./foo.js";
console.log(fName,'fName');
console.log(fAge, 'fAge');
// foo.js
const name = 'wy'
const age = 18
export {
name, age
}
// 导出方式三 将导出所有内容放在一个标识符中
// index.html
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 需要加type='module'-->
// main.js
import * as foo from "./foo";
console.log(foo.age); //也会避免命名冲突
// foo.js
const name = 'wy'
const age = 18
export {
name, age
}
导入导出同时使用
上面是目录,format和request 文件会统一放到index.js 里面,index.js作为入口
// ============format.js==========
function add (m,n){
return m+n
}
export{
add
}
// ============request.js==========
function sub (m, n) {
return m - n
}
export{
sub
}
// ============index.js==========
// 导出方式一
// import { add } from "./format.js";
// import { sub } from "./request.js";
// export{
// add,sub
// }
// 导出方式二 阅读性强
export { add } from "./format.js";
export { sub } from "./request.js";
// 导出方式三
export * from "./format.js";
export * from "./request.js";
// =============index.html========
<script src='./main.js' type='module'></script> <!-- 作为普通代码解析 遇到import会报错 -->
//==============main.js===========
import { add,sub } from "./utils/index.js";
console.log(add(10,20),'add');
console.log(sub, 'sub');
default默认导出:一个模块只有一个默认导出
默认导出可以不需要重新定义名字
导入时不需要使用{},并且可以自己定义名字
方便和现有commonjs等规范相互操作
==================main.js=====================
//import { name, age } from "./foo.js";
// import * as foo from "./foo.js"
import wy from "./foo.js" // 导入的是默认的导出
console.log(wy, 'wy');
==================foo.js=====================
const name = 'wy'
const age = 18
const foo = 'foo value' // 作为默认导出
// 默认导出方式一
// export{
// name,age,foo as default
// }
// 默认导出方式二 常见
export {
name, age
}
export default foo
import函数
//import { name, age } from "./foo.js"; //要等待全部加在完毕
import ('./foo.js').then(res=>{ //而且是异步,不用等加载完毕执行下面的代码
console.log(res,'res');
}) //返回的是promise
//es11新增特性 meat 属性本身也是一个对象 {url:'当前所在路径'}
console.log(import.meta,'meta');
console.log('hello????')
标签:commonJS,console,name,age,Module,js,foo,ES,log 来源: https://blog.csdn.net/web_girls/article/details/122773993