什么是模块化
凡是开发大型应用程序,模块必然是不可或缺的一部分。那么什么是模块化呢?其实模块化就是将一个复杂的系统分解成多个独立的模块的代码组织方式。在很长的一段时间里,前端只能通过一系列的<script>标签来维护我们的代码关系,但是一旦我们的项目复杂度提高的时候,这种简陋的代码组织方式便是如噩梦般使得我们的代码变得混乱不堪。
所以,在开发大型Javascript应用程序的时候,就必须引入模块化机制。由于早期官方并没有提供统一的模块化解决方案,所以在群雄争霸的年代,各种前端模块化方案层出不穷。
commonJS
随着Javasript应用进军服务器端,业界急需一种标准的模块化解决方案,
这是一种被广泛使用的Javascript模块化规范,大家最熟悉的Node.js应用中就是采用这个规范。在Node.js中,内置了module对象用来定义模块, require函数用来加载模块文件,代码如下:
// add.js
var add = function(a, b) {
return a + b;
};
module.exports = {
add: add
};
// test.js
// 加载模块
var utils = require('./add');
console.log(utils.add(1, 2));
ES6 Modules
在ES6中,从语法层面就提供了模块化的功能。然而受限于浏览器的实现程度,如果想要在浏览器中运行,还是需要通过Babel等转译工具进行编译。ES6提供了import和export命令,分别对应模块的导入和导出功能。具体实例如下:
// say.js
var name = "hello"
var sayHello = (name) => {
console.log(name);
}
export {name, sayHello};
// test.js 使用模块
import { sayHello } from "./say.js";
sayHello("hello world");
import
如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。
// main.js
import { sayHello as say } from './say.js';
say("hello world");
ES2020提案 引入import()函数,支持动态加载模块。import()函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行,也就是说,什么时候运行到这一句,就会加载指定的模块。另外,import()函数与所加载的模块没有静态连接关系,这点也是与import语句不相同。import()类似于 Node.js 的require()方法,区别主要是前者是异步加载,后者是同步加载。
if (condition) {
import('moduleA').then(...);
} else {
import('moduleB').then(...);
}
模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。
import * as say from './say.js';
say.sayHello("hello world");
注意事项
- 导入内容的时候,需要添加 {}
- 导入的内容(num),必须是模块导出的内容(num).如果导入内容与导出内容不相同,那么,导入内容为: undefined
- export 不带 default 可以出现任意多次
给导入的变量起别名(解决命名冲突)
import { num as bNum } from '模块名称'
一次性全部导入一个模块中的内容
import * as bModule from '模块名称'