ES6-ES12补充 笔记(二)

ES6之前没有模块化的解决方案

/***
 * 没有模块化带来的问题
 * 1. 命名冲突
 * 使用立即执行函数调用带来的问题
 * 1. 必须记住每个模块中返回对象的命名
 * 2. 代码写起来混乱不堪,因为每个文件中的代码都需要包裹再一个匿名函数中编写
 * 3. 再没有合适的规范情况下,有可能会任意命名,出现模块名称相同的情况
 * */

// A js文件
const moduleA = (function () {
  var name = 'coder',
  var age = 19,
  var isFlag = true
  return {
    name,
    age,
    isFlag
  }
})()


// B js文件
const moduleB = (function () {
  var name = 'coder',
  var age = 19,

  return {
    name,
    age
  }
})()


  // C js文件
  (function () {
    if (moduleA.isFlag) {
      console.log('没有模块化之前的解决方案', moduleA.name);
    }
  })()

模块化的历史

在网页开发的早期,Brendan Eich 开发JavaScript仅仅作为一种脚本语言,做一些简单的表单验证或者动画实现等,那个时候代码还算很少的

这个时候我们只需要将js代码写到<script>标签中即可;

并没有必要放到多个文件中来编写,甚至流行:通常来说js程序的长度只有一行

但是随着前端和js的快速发展,js代码变得越来越复杂

  • ajax的出现,前后端开发分离,意味着后端返回数据后,我们需要通过js进行前端页面的渲染
  • SPA的出现,前端页面变得更加复杂:包括前端路由,状态管理等等一系列复杂的需求需要通过js来实现
  • 包括Node的实现,js编写复杂的后端程序,没有模块化的致命的硬伤

所以,没有模块化已经是js一个非常迫切的需求

  • 但是js本身,直到ES6才推出自己的模块化方案
  • 在此之前,为了让js支持模块化,涌现了很多不同的模块化规范:AMD, CMD, CommonJS

CommonJS规范和Node关系

CommonJS是一个规范, 最初提出来是在浏览器以外的地方使用,并且当时被命名为ServerJs,后来为了体现它的广泛性,修改CommonJS,平时我们也会简称为CJS

1. Node是CommonJS在服务器端一个具有代表性的实现

2. Browserify是CommonJS在浏览器中的一个实现

3. webpack打包工具具备对CommonJS的支持和转换

在node中每个js文件都是一个单独的模块

模块中包括CommonJS规范的核心变量: exports module.exports  require

1. exports和module.exports 可以负责对模块中的内容进行导出

2. require 函数可以帮助我们导入其他模块(自定义模块,系统模块,第三方库模块)中的内容

CommonJS导入导出基本使用

// A.js 文件

var name = 'coder'
var age = 18
function sum(num1, num2) {
  return num1 + num2
}

// 1.导出方案一 module.exports
// module.exports = {
//   name,
//   age,
//   sum
// }


// 2.导出方案二 exports
// 源码做的事
// module.exports = {}
// exports = module.exports
exports.name = name
exports.age = age
exports.sum = sum

// 最终能导出的一定是module.exports这个对象
// exports = {
//   age
// }



// B.js文件
// 使用另外一个模块导出的对象,那么就要进行导入 require
// 多个文件引用A.js 是引用的同一个对象
const {name, age, sum} = require('./A.js')

console.log(name);
console.log(age);
console.log(sum);

require细节

// require 是一个函数,可以帮助我们引入一个文件(模块)中导出的对象
// 导入格式如下: require(X)

// 当X 为不同值时,有不同的查找规则

// 情况一: 核心模块
const path = require('path')
const fs = require('fs')


// 情况二 X是以./ 或者../ 或者 /(根目录)开头的
const abc = require('./abc')
/**
 * 第一步: 将X当做一个文件在对应的目录下查找
 * 1. 如果没有后缀名,按照后缀名的格式查找对应的文件
 * 2. 如果没有后缀名,会按照如下顺序: 
 *    1. 直接查找文件X
 *    2. 直接查找X.js文件
 *    3. 查找X.json文件
 *    4. 查找X.node文件
 * */ 

/**
 * 第二步: 没有找到对应的文件,将X作为一个目录
 * 查找目录下的index文件
 *    1. 查找X/index.js文件
 *    2. 查找X/index.json文件
 *    3. 查找X/index.node文件
 * */ 

// 如果没有找到,那么报错, not found


// 情况三: 直接是一个X(没有路径),并且X不是一个核心模块
// 就会去node_modules文件夹中去找index文件,当层没有,就会去上层找,以此类推

ES_Module基本使用

ES Module是js在ES6推出的模块化方案。

/**
 * ES Module采用import export关键字
 * import 负责从其他模块导入内容
 * export 负责将模块内的内容导出
 * 采用 ES Module将自动采用严格模式 use strict
 * */ 


// a.js
// 第一种导出方法: export 声明语句
export const name = 'coder'
export const age = 18

// 第二种导出方式: export 导出 和声明分开
const name = 'coder'
const age = 19
function foo() {
  console.log('foo, function');
}

// 后面的不是对象,而是一个语法
export {
  name,
  age,
  foo
}

// 第三种方式: 第二种导出时起别名
export {
  name as FName,
  age as FAge,
  foo as FFoo
}




// b.js
// 导入方式一: 普通的导入
import { name, age } from './a.js'

// 导入方式二: 起别名
import { name as FName, age as FAge} from './a.js'

// 导入方式三: 将导出的所有内容放到一个标识符中
import * as foo from './a.js'

import export结合使用

// 第一种方式导出
import { add, sub } from './utils/math.js'
import { priceFormat, timeFormat } from './utils/format.js'

// 做一个统一的出口
export {
  add,
  sub,
  priceFormat,
  timeFormat
}

// 第二种方式导出
export { add, sub } from './utils/math.js'
export { priceFormat, timeFormat } from './utils/format.js'

// 第三种方式导出
export * from './utils/math.js'
export * from './utils/format.js'

默认导入导出

const name = 'coder'

const foo = 'foo value'

export {
  name,
  age,
  foo as default // 默认导出第一种写法
}

// 默认导出第二种写法
export default foo

// 注意: 默认导入只能有一个



// b.js文件
import foo from './a.js' // 默认导入

import函数

import { name, age } from './b.js'

console.log('上面这种导入是同步的,在这个模块没有解析下载完,是不会执行下面的代码的');

// import函数返回的结果是一个promise
import('./b.js').then(res => {
  console.log('res:', res.name);
})

console.log('后面的代码会直接执行');

// ES11新增的特性
// meta属性本身也是一个对象: {url:'当前模块所在的路径'}
console.log(import.meta);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

派大星965

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值