工程化核心技术

86 阅读2分钟

代码仓库

一.前端模块化的进化过程

  1. 全局function模式 缺陷:容易引发全局命名空间冲突
var a = 1
function add() {
    a++
}
function api() {
    return {
        name: 'lw',
        age: 18
    }
}
  1. 全局namespace模式 缺陷:外部能够修改模块内部数据
var __Module = {
    a: 1,
    add() {
        a++
    },
    api() {
        return {
            name: 'lw',
            age: 18
        }
    }
}
//__Module.a = 100
  1. IIFE模式(自执行函数)缺陷:无法解决模块间相互依赖问题
(function(global) {
    var a = 1
    function add() {
        a++
    }
    function geta() {
        return a
    }
    function seta(x) {
        a = x
    }
    function api() {
        return {
            name: 'lw',
            age: 18
        }
    }
    global.__Module = {
        a,
        geta,
        seta,
        add,
        api
    }
}(window))
//注意__Module.a只是值引用 __Module.a =100 函数内部变量不会改变的

4.IIFE模式增强 缺点:多依赖传入时,代码阅读困难 无法支持大规模的模块化开发 无特定语法支持,代码简陋

//module1
(function(global) {
    var a = 1
    function add() {
        a++
    }
    function geta() {
        return a
    }
    function seta(x) {
        a = x
    }
    function api() {
        return {
            name: 'lw',
            age: 18
        }
    }
    global.__Module1 = {
        a,
        geta,
        seta,
        add,
        api
    }
}(window))
//module2
(function(global,module){
    function log() {
    }
    global.__Module2 = {
        log,
        api:module.api
    }
}(window,__Module1))
//注意要先引用module1

二.commonJS规范

  1. 特点
1.在 commonjs 中每一个 js 文件都是一个单独的模块,我们可以称之为 module2.该模块中,包含 CommonJS 规范的核心变量: exportsmodule.exportsrequire3.exportsmodule.exports 可以负责对模块中的内容进行导出;

4.require 函数可以帮助我们导入其他模块(自定义模块、系统模块、第三方库模块)中的内容;

2.原理

每个模块文件上存在 moduleexportsrequire三个变量

module 记录当前模块信息。
require 引入模块的方法。
exports 当前模块导出的属性
这三个变量是没有被定义的,但是我们可以在 Commonjs 规范下每一个 js 模块上直接使用它们。在 nodejs 中还存在 __filename 和 __dirname 变量

在编译的过程中,实际 Commonjs 对 js 的代码块进行了首尾包装,使用的 require ,exports ,module 是通过形参的方式传递到包装函数中的, fn_handle.js中被包装之后的样子如下:

(function(exports,require,module,__filename,__dirname){
   const setName = require('./fn_data.js')
    module.exports = function set(){
        return {
            name: setName(),
            title: '夜空中最亮的星'
        }
    }
})

包装函数(后面用eval执行)

function wrapper (script) {
    return '(function (exports, require, module, __filename, __dirname) {' + 
        script +
     '\n})'
}

三.AMD和CMD和UMD规范

  1. amd和cmd都是异步加载js(执行代码发现依赖然后去加载js)
  2. amd是依赖前置(加在完不存在依赖或者依赖执行完就执行)cmd(加载完也不执行,根据入口模块的代码执行顺序执行) //这里的执行是执行回调
  3. umd就是node+amd webpack一般默认打包就是这种格式(就是代码里兼容判断环境是node还是浏览器选择用那种格式)