从前端各大框架的出现到现在,模块化和组件化开发已经变得流行,模块化最终的目的是将程序划分成一个个小的结构,这种结构有编写自己的逻辑代码、有自己的作用域,不会影响到其他模块,通过暴露变量、函数、对象等导出其结构使用,也可以通过某种方式导入另外结构中的变量、函数、对象等;而这个结构就是模块,按照这种结构化发开程序的过程,就是模块化开发的过程。
此篇文章主要介绍模块化开发中的导出导入细节。
1、CommonJS导入和导出
CommonJS规范的核心变量:exports、module.exports、require
exports和module.exports可以负责对模块中的内容进行导出;
require函数可以帮助我们导入其他模块(自定义模块、系统模块、第三方库模块)中的内容;
Node中实现CommonJS的本质就是对象的引用赋值;导出的是对象:
bar.js
var name = '小刘'; var msg = 'wgInfo'; function say() { console.log('say...'); } // 导出的exports是对象 // 方式一: exports.name = name; exports.msg = msg; exports.say = say; // 方式二: module.exports = { name, msg, say };
main.js
// 方式一: const base = require('./bar'); console.log(base.name); console.log(base.msg); base.say(); // 方式二: const { name, msg, say } = require('./bar'); console.log(name); console.log(msg); say();
2、ES Module导出和导入
ES Module 中 import 和 export 是关键字,与CommonJS中的exports和module.exposts不同,
foo.js
const person = '张静'; const sex = '女'; const eat = function (food) { console.log(person + ' 正在吃:' + food); }; // 方式一: export const person = '张静'; export const sex = '女'; export const eat = function (food) { console.log(person + ' 正在吃:' + food); }; // 方式二:在 大括号 {} 中统一导出 // {}大括号,它不是一个对象 // 里面放置要导出的变量的引用列表 export { person, sex, eat }; // 方式三:{} 导出时,可以给变量起别名 export { person as perPople, sex as perSex, eat as eatFoo }; // 默认导出 export default function (name) { console.log('我的名字叫:' + name); }
main.js
// 导入方式一:import {} from '路径'; 此时文件必须加上文件的后缀,因为在浏览器解析时时根据这个文件进行解析的,在webpack中,因为有webpack帮助我们进行解析,所以可以不用加文件名称后缀 import { person, sex, eat } from './modules/foo.js'; console.log(person); console.log(sex); eat('香蕉'); // 导入方式二:导出变量之后可以起别名 import { person as WP, sex as Ws, eat as eatFun } from './modules/foo.js'; import { perPople as WP, perSex as Ws, eatFoo as eatFun } from './modules/foo.js'; console.log(WP); console.log(Ws); eatFun('火龙果'); // 方式三:* as PerFoo import * as PerFoo from './modules/foo.js'; console.log(PerFoo.perPople); console.log(PerFoo.perSex); PerFoo.eatFoo('栗子'); // 演练:export 和 import 结合使用 import { person, sex, eat } from './modules/bar.js'; console.log(person); console.log(sex); eat('桃子'); // 演练:default export 如何导入 import myName from './modules/foo.js'; myName('张丽华');
3. 补充
CommonJS模块加载js文件的过程是运行时加载的,并且是同步的,运行时加载意味着是JS引擎在执行js代码的过程中加载模块的;同步意味着一个文件没有加载结束之前,后面代码是不会执行的;
const flag = true; if(flag){ const foo = require('../foo.js'); console.log('if语句继续执行'); }
ES Module加载js文件的过程是编译时加载的,并且是异步的;这里编译(解析)时加载,意味着import不能和运行时相关内容放到一起使用;