【es6入门】总结ES Module模块化的写法,顺便介绍node的CommonJS规范

没有模块化写法的问题

在以前前后端不分离时期,都是一个html文件里引入各种js文件,这就会照成js变量污染的问题。

虽然有函数执行的方式能够一定程度避免,例如a.js文件:

let aData = (function () {
  // 不想暴露到全局上的变量
  let a = 1;

  // 暴露给全局的变量
  let b = 2;
  let c = 3;
  return {
    b,
    c,
  };
})();

然后b.js文件:

(function () {
  console.log("获取到a文件的变量", aData);
})();

但随着项目越来越复杂,这种方式也会渐渐力不从心的。

当工程化时代来临后,可以通过模块化的导入导出完美的解决这个问题。


ES Module写法

export的导入导出

a.js中导出

export function a(n) {
  console.dir("a" + n);
}
export function b(n) {
  console.dir("b" + n);
}
export function c(n) {
  console.dir("c" + n);
}

b.js中选择性引入

import { a, b as B } from "./a.js"; // 选择性导入a,b导入后改名为B

a("可直接使用")

这种方式我觉得适合一些比较大的js库,可以引入所需部分。

b.js中全部引入

import * as obj from "./a.js"; // 全部导出是个*表示,然后命名为obj,是个对象

obj.a("可直接使用");

export default的导入导出

a.js中导出

export default {
  a: function (n) {
    console.log("a" + n);
  },
  b: function (n) {
    console.log("b" + n);
  }
};

或者

function a(n) {
  console.log("a" + n);
}
function b(n) {
  console.log("b" + n);
}
export default {
  a, // es6的语法省略
  b,
};

b.js中引入

import utils from "./a.js";  // 默认要以对象的形式接收

utils.a("以对象的形式使用");

注意:如果项目用webpack的话,引用 ./ 不能省略,因为是通过webpack来进行的编译,而webpack又是通过node写出来的,所以要遵循node的规定;


export与export default同时写

这两个可以同时出现在一个js文件中:

const obj = { a: 'a' }
export class Person {}
export default obj

默认导出的是obj,要导入Person就需要手动写:

import obj, { Person } from './index.js'

动态按需导入

没想到吧,可以按需导入:

clickFn() {
	import('jquery').then(res=>{
		let $ = res.default
	})
}

注意哦是个异步的导入方式。


借助webpack导出

适用场景,例如一个icon文件夹中有很多名字有规律的图片:

---icon
	---icon1.png
	---icon2.png
	...

我们可以在文件夹里建个js,然后写上:

const context = require.context('./', true, /.png$/)

let iconMap = {}
context.keys().forEach((filename) => {
    iconMap[filename.slice(2, 6)] = context(filename).default
})

export default iconMap

在其他文件中导入就能获取到一个存放key为文件名,value为base64图片的对象啦。

如果出现webpack的报错,很有可能这个webpack版本不能正确解析循环引用关系,可以改写成导出函数,这个函数里循环获取文件数据并返回出。其他文件导入使用的时候再执行下这个函数就好了


注意符号绑定的特性/引用传递

假如有个js文件专门存放很多变量导出供各个组件使用,那么要注意了,当其中一个组件中修改了js文件的某个变量,这个变量在其他组件的值也会改变(无论值类型还是引用类型)。

同上,json类型的文件引入到各个组件中使用也会有这样的问题。

引用传递的解释可参考:引用传递

这种特性的说法叫符号绑定或者引用传递。

如果不想利用到这种特性,我想到两种做法:

第一:

每个变量都单独一个函数返回出来:

export function fn() {
    return {
        a: 1
    }
}

但是这个方式麻烦就是每次都要执行一次用个变量赋值。

第二:

在引入的时候重新声明变量:

import { a } from './user.js' // 用 as 也是一样的效果
import * as obj from './user1.js'

const A = a
const { c: C } = counter; // 解构赋值

但是引用类型的话还是同一个内存


ES Module特性总结

  • 符号绑定/引用传递
  • 是官方的新语法标准
  • 支持node和浏览器环境(node更常用的是CommonJS规范)
  • 支持异步动态按需导入

commonJS模块化规范

开发重点看webpack的批量文件导出部分

具体看:【Node.js】学习系列2-commonJS的模块规范


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值