其他分享
首页 > 其他分享> > 模块化:ES Module与commonJS

模块化: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