一文带你了解,前端模块化那些事儿

前端模块化

省流:chatGPT总结

该文章主要讲述了前端模块化的发展历史和各个阶段的技术方案,包括无模块化(IIFE)、CommonJS、AMD、CMD、ESModule、UMD。

其中,无模块化时期的文件拆分是最基础的模块化,但也存在函数命名冲突的问题;

IIFE 是现代模块化的基石,利用函数的块级作用域进行隔离,可以控制作用域;

CommonJS 文件即模块,模块加载同步,适用于服务器端 node,浏览器端使用 webpack 或 browserfy。

最后,各种模块化技术方案都是为了更好地满足前端代码管理、组织、通信的需求,模块已经成为了代码管理/编译、业务分离的基本单元。

一、参考资料

二、发展历史

总的发展历史:

1.无模块化

需求:

  1. 开始需要在页面中加载不同的js:动画、组件、格式化
  2. 多种js分布在不同的文件中
  3. 不同的文件又被同一个模块中引用

文件拆分是最基础的模块化




// ...

问题:这个时期函数命名可能会冲突,影响到其他人写的代码

引出的问题:

总结: 主要是对标签下载和执行时机的控制

横向拓展

  1. 兼容性如何? > IE9
  2. 引导内容
  3. 浏览器渲染原理
  4. 同步异步的原理(Promise,任务队列)
  5. 模块化加载原理
  6. 产生的问题
  7. 污染全局作用域 => 不利于大型项目的开发以及多人团队的共建

2.IIFE

IIFE主要是开始对作用域的把控 利用函数的块级作用域进行隔离 可以说IIFE是现代模块化的基石

(function($){
    console.log($)
    return {
       data:[]
    }
})(jQuery) //注入对象

3.Commonjs(cjs)

// a.js
var name = 'morrain'
var age = 18
exports.name = name
exports.getAge = function(){
    return age
}
// b.js
var a = require('a.js')
console.log(a.name) // 'morrain'
a.name = 'rename'
var b = require('a.js')
console.log(b.name) // 'rename'
// a.js
var name = 'morrain'
var age = 18
exports.name = name
exports.age = age
exports.setAge = function(a){
    age = a
}
// b.js
var a = require('a.js')
console.log(a.age) // 18
a.setAge(19)
console.log(a.age) // 18

4.AMD

AMD(Asynchronous module definition)异步的模块定义 解决了Commonjs不支持异步的缺点,可以在浏览器端运行

经典代表:require.js

使用方法:

// define来定义模块
define(id, [depends], callback);
// require进行加载
require([module], callback);

示例:

//提前加载执行顺序
// RequireJS
define('a', function () {
  console.log('a load')
  return {
    run: function () { console.log('a run') }
  }
})

define('b', function () {
  console.log('b load')
  return {
    run: function () { console.log('b run') }
  }
})

require(['a', 'b'], function (a, b) {
  console.log('main run') // 
  a.run()
  b.run()
})

// a load
// b load
// main run
// a run
// b run

缺点:

引出的问题:

define('amdModule', [], require => {
    const dep1 = require('./dep1');
    const dep2 = require('./dep2');
    // 业务逻辑……
})

5.CMD

CMD(Common Module Definition-通用模块定义)推崇依赖后置,也就是按需执行 CMD解决了AMD依赖前置导致的引入成本过高的问题 整合了CJS和AMD的特点,浏览器端运行

经典代表:Sea.js

// 引入require
var fs = require('fs'); //同步
require.async('./module3', function (m3) {}) //异步


// sea.js,按需引入
define('a', function (require, exports, module) {
  console.log('a load')
  exports.run = function () { console.log('a run') }
})

define('b', function (require, exports, module) {
  console.log('b load')
  exports.run = function () { console.log('b run') }
})

define('main', function (require, exports, module) {
  console.log('main run')
  var a = require('a')
  a.run()
  var b = require('b')
  b.run()
})

seajs.use('main')

// main run
// a load
// a run
// b load
// b run

缺点:

6.UMD

UMD (Universal Module Definition)就是一种通用模块定义规范,让你的模块能在所有运行环境中使用,如CommonJS, AMD, CMD

(function(root, factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        console.log('是commonjs模块规范,nodejs环境')
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        console.log('是AMD模块规范,如require.js')
        define(factory)
    } else if (typeof define === 'function' && define.cmd) {
        console.log('是CMD模块规范,如sea.js')
        define(function(require, exports, module) {
            module.exports = factory()
        })
    } else {
        console.log('没有模块环境,直接挂载在全局对象上')
        root.umdModule = factory();
    }
}(this, function() {
    return {
        name: '我是一个umd模块'
    }
}))

7.ESM

ESModule是伴随着ES6推出的原生模块化解决方案 import输入、export输出

展开阅读全文

页面更新:2024-02-23

标签:事儿   函数   模块   加载   缺点   定义   浏览器   作用   标签   代码   文件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top