前端模块化的发展
CommonJS的模块化实现
但是应用到项目中需要node技术支持解析
ES6的模块化实现
模块化
概述
Javascript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其 他都可以加载别人已经写好的模块。 但是,Javascript不是一种模块化编程语言,它不支持"类"(class),包(package)等概念,更遑论"模 块"(module)了
最早,我们是这么写代码的:
function foo () { // ... } function bar () { // ... }
这样很容易导致全局命名冲突。那定义一个对象,不放到全局中不就好了吗,这就是 Namespace 模式。
var MYAPP = { foo: function () {}, bar: function () {} } MYAPP.foo()
这样全局变量虽然少了,但本质了是个对象,是可以操作修改的,这样很不安全。
函数是 JavaScript 唯一的 LocalScope,函数外部是修改不了函数内部代码的。所以相对来说是安全的。这就是 IIFE 模式。
// 利用闭包 var Module = (function () { var _private = 'safe now' var foo = function () { console.log(_private) } // 暴露接口 return { foo: foo } })()
开发中往往会依赖第三方库,这时候就要引入依赖。例如依赖于 jQuery 时,就要将 jQuery
引入。
var Module = (function ($) { // 使用 jQuery var _$body = $("body") var foo = function () { console.log(_$body) } return { foo: foo } // 引入 jQuery })(jQuery) Module.foo()
这就是模块模式,也是现代模块实现的基石。
模块化可以降低单个文件的复杂度,降低偶合度,使文件更好维护。当文件分离后可以按需加载,提高了复用性。并且每个模块都是一个独立的作用域,避免了命名冲突。
但是这样就引发了一个问题:文件分离导致需要发送更多的 HTTP 请求,并且使模块与模块之间的依赖变得模糊。
模块化规范就可以通过依赖关系来合并文件,现在有主流的 CommonJS、AMD、CMD、ES6 四种规范。
CommonJS模块化
CommonJS使用 exports 和require 来导出、导入模块
const sum = function(a,b){ return parseInt(a) + parseInt(b) } const subtract = function(a,b){ return parseInt(a) - parseInt(b) } //导出 module.exports = { sum: sum } //简写 module.exports = { sum } //引入模块,注意:当前路径必须写 ./ const m = require('./四则运算.js') const result1 = m.sum(1, 2) console.log(result1)
ES6模块化
使用 export 和 import 来导出、导入模块
因为ES6的模块化无法在Node.js中执行,需要用Babel编辑成ES5后再 执行
第一种
export function getList() { console.log('获取数据列表') } export function save() { console.log('保存数据') } //只取需要的方法即可,多个方法用逗号分隔 import { getList, save } from "./userApi.js" getList() save()
第二种
export default { getList() { console.log('获取数据列表2') }, save() { console.log('保存数据2') } } import user from "./userApi2.js" user.getList() user.save()
CMD和AMD模块规范