天天看点

前端模块化开发之CommonJS规范和ES6规范前端模块化

前端模块化

前言

在项目开发过程中,随着功能的不断增强,代码量,文件数量也急剧增加,需要把一个大函数拆成小函数,把一个大文件拆成小文件,把一个大功能拆成若干个小功能。这里很自然地就涉及到模块化的想法:一个复杂的系统分成几个子系统,体现在几个小文件在组成一个大文件,集成强大的功能。

es5 不支持模块化:在一个js文件内,不能引入其他js文件。不能通过若干个小文件去集成一个大文件。

这样就会带来多个问题:

  1. 文件的加载先后顺序
  2. 不同的文件内部定义的变量共享
  3. 变量命名冲突
  4. 文件依赖复杂度增高
  5. 页面载入过多依赖分不清,不利于维护

模块化

什么是模块化

项目中一些程序代码经常被其他业务场景使用,为了避免重复开发,就把这些代码设置为共享模式,共享模式就是模块化。像jquery、axios、vue等等都是模块化的体现,需要的时候直接拿过来用即可 。

一个js文件中可以引入其他的js文件,能使用引入js文件中的变量、数据,这种特性就称为模块化。使用模块化开发可以很好的解决变量、函数名冲突问题,也能灵活的解决文件依赖问题。

模块化技术有哪些

CommonJs、ES6、AMD、CMD模块化介绍

  1. es5 不支持模块化。为了支持模块化,一般会借用第三方库来实现:
    • sea.js
    • require.js
  2. es6 原生语法支持模块化。
    • ES6 模块化 是2015年官方正式出品的,已经被纳入到JavaScript标准里边,也是js未来的标准。由于各种原因 nodejs和浏览器中现在还不能直接使用ES6模块化,要相信未来可以。
  3. Nodejs 内部支持CommonJS模块化。
    • CommonJS模块化 是2009年发布的,是民间出品的,相对不正规,可以在nodejs中应用
      // 导出
      module.exports = 对象
      // 或者
      exports = 对象
      
      // 导入
      var obj = require(模块文件)
                 
  4. AMD
    • Asynchronous Module Definition 异步模块定义
    • 2009年诞生,可以实现浏览器中应用模块化技术。
  5. CMD
    • Common Module Definition 通用模块定义
    • 2011年诞生,阿里公司出品,可以实现浏览器中应用模块化技术。

各个模块化应用场景

  1. commonjs模块化可以应用在nodejs中,浏览器中不可以。
  2. es6模块化暂时还不能在nodejs 和 浏览器 中使用,要相信未来可以。
  3. 浏览器中可以运行的模块化名称为 AMD 和 CMD。

CommonJS 模块化规范

在node中,一个js文件就是一个模块。每一个js文件中的js代码都独立运行在一个函数中,而不是全局作用域,所以一个模块中的变量和函数在其他模块内无法被访问,所以要向外部暴露变量和方法。
  • 通过 module.exports 或 exports 对外暴露接口
    • node 为了简化操作,专门提供了一个变量:

      exports

      等于

      module.exports

      ,相当于在模块中有这么一句代码

      var exports = module.exports

  • 通过 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动作。

注意

  1. 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  {对象}       // 默认导出
           

注意

  1. 一个模块只能默认导出一次,按需导出可以设置多次。
  2. 默认导出的语句没有摆放位置要求。

导入语法

// 分别导入
import  名称  from  模块          // 默认导入
import  {xx,yy}  from  模块      // 按需导入

// 一并导入必须是 默认在"前",按需在"后"
import 名称,{xx,yy} from 模块