前端模块化
前言
在项目开发过程中,随着功能的不断增强,代码量,文件数量也急剧增加,需要把一个大函数拆成小函数,把一个大文件拆成小文件,把一个大功能拆成若干个小功能。这里很自然地就涉及到模块化的想法:一个复杂的系统分成几个子系统,体现在几个小文件在组成一个大文件,集成强大的功能。
es5 不支持模块化:在一个js文件内,不能引入其他js文件。不能通过若干个小文件去集成一个大文件。
这样就会带来多个问题:
- 文件的加载先后顺序
- 不同的文件内部定义的变量共享
- 变量命名冲突
- 文件依赖复杂度增高
- 页面载入过多依赖分不清,不利于维护
模块化
什么是模块化
:
项目中一些程序代码经常被其他业务场景使用,为了避免重复开发,就把这些代码设置为共享模式,共享模式就是模块化。像jquery、axios、vue等等都是模块化的体现,需要的时候直接拿过来用即可 。
一个js文件中可以引入其他的js文件,能使用引入js文件中的变量、数据,这种特性就称为模块化。使用模块化开发可以很好的解决变量、函数名冲突问题,也能灵活的解决文件依赖问题。
模块化技术有哪些
:
CommonJs、ES6、AMD、CMD模块化介绍
- es5 不支持模块化。为了支持模块化,一般会借用第三方库来实现:
- sea.js
- require.js
- es6 原生语法支持模块化。
- ES6 模块化 是2015年官方正式出品的,已经被纳入到JavaScript标准里边,也是js未来的标准。由于各种原因 nodejs和浏览器中现在还不能直接使用ES6模块化,要相信未来可以。
- Nodejs 内部支持CommonJS模块化。
- CommonJS模块化 是2009年发布的,是民间出品的,相对不正规,可以在nodejs中应用
// 导出 module.exports = 对象 // 或者 exports = 对象 // 导入 var obj = require(模块文件)
- CommonJS模块化 是2009年发布的,是民间出品的,相对不正规,可以在nodejs中应用
- AMD
- Asynchronous Module Definition 异步模块定义
- 2009年诞生,可以实现浏览器中应用模块化技术。
- CMD
- Common Module Definition 通用模块定义
- 2011年诞生,阿里公司出品,可以实现浏览器中应用模块化技术。
各个模块化应用场景
:
- commonjs模块化可以应用在nodejs中,浏览器中不可以。
- es6模块化暂时还不能在nodejs 和 浏览器 中使用,要相信未来可以。
- 浏览器中可以运行的模块化名称为 AMD 和 CMD。
CommonJS 模块化规范
在node中,一个js文件就是一个模块。每一个js文件中的js代码都独立运行在一个函数中,而不是全局作用域,所以一个模块中的变量和函数在其他模块内无法被访问,所以要向外部暴露变量和方法。
- 通过 module.exports 或 exports 对外暴露接口
- node 为了简化操作,专门提供了一个变量:
等于exports
,相当于在模块中有这么一句代码module.exports
var exports = module.exports
- node 为了简化操作,专门提供了一个变量:
- 通过 require (“路径”)函数导入模块。
- 相对路径必须以
或者./
开头。../
- 使用require()引入模块后,会返回一个对象,这个对象代表的就是这个模块。
- 相对路径必须以
// utils/m1.js
module.exports.sum = function (n) {
let total = 0
for(let i = 0; i<=n; i++) {
total += i
}
return total
}
exports.x = 'nihao'
// pages/module/module.js
const m1 = require('../../utils/m1.js')
const ret = m1.sum(100)
const x = m1.x
ES6 模块化规范
默认导出和导入
在一个js文件中,通过一个对象把全部数据导出去,就是默认导出。
// 导出:
export default {对象}
// 一个模块中默认导出只能进行一次
// 默认必须导出一个对象{}
对默认导出的成员进行接收就是默认导入。
// 导入:
import 名称 from 模块文件名字
模块
:
一个js文件就是一个模块,前提是该文件要有做导出export动作。
注意
:
- es6模块化现在只可以在VueCli项目中使用。
示意案例
:
// utils.js文件对外部导出内容,以便被使用
// 默认导出:通过一个对象把所有的信息都导出出去
// CommonJS: module.exports = {}
export default {
name:'kitty',
age:4,
walk:function(){
console.log('走直线')
}
}
main.js导入
// import 名称 from '模块js文件路径名'
import cat from './modules/utils.js'
console.log(cat)
按需导出和导入
一个js模块中,定义了N多的成员信息,根据需要,用哪个就导出哪个,这就是按需导出。
哪些成员可以做按需导出导入处理:
常量、对象 、函数 三种信息可以做模块化应用 (var、let等变量,用于模块化没有意义)
导出语法
:
export const a = 10 // 常量
export function ab(){} // 函数
export const cat = {name:'kitty',age:5} // 对象
导入语法
:
// xx,yy,zz代表被导入的成员名称,要与导出的名称一致
// 成员不用全部都导入,根据需要,导入1个或多个或全部都可以
import {xx,yy,zz} from 模块文件
// 如果导入进来的成员名称与当前环境名称有冲突,根据需要可以使用as设置别名
import {xx as XX,yy as YY,zz as ZZ} from 模块文件
案例
:
按需导出:
// CommonJs : (module.exports.xx = yy)
export const city = 'beijing'
export function getApple(){
return '国光苹果'
}
export const tiger = {color:'yellow and black'}
按需导入:
import {city as ct,getApple,tiger} from './modules/export.js'
console.log(ct)
getApple()
console.log(tiger)
默认和按需同时导出和导入
实际开发中,在一个模块中 默认导出 和 按需导出会同时存在
导出语法
:
export const a = 10 // 按需导出
export function ab(){} // 按需导出
export default {对象} // 默认导出
注意
:
- 一个模块只能默认导出一次,按需导出可以设置多次。
- 默认导出的语句没有摆放位置要求。
导入语法
:
// 分别导入
import 名称 from 模块 // 默认导入
import {xx,yy} from 模块 // 按需导入
// 一并导入必须是 默认在"前",按需在"后"
import 名称,{xx,yy} from 模块