Skip to content
Go back

兼容AMD CMD CommonJS 原生浏览器的封装写法

经常看见一些库,可以支持浏览器和Node引用,同时兼容多种模块化规范(AMD CMD CommonJS)。比如著名的Vue,你可以使用下面的方法:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
const Vue = require('vue');

既可以直接引入js使用,也可以和webpack等模块化打包工具结合使用,非常方便!

那么这是怎么实现的呢?

其实原理很简单,通过检测引入文件时的环境,如果是支持CommonJS或者CMD,则导出时使用

module.exports

如果支持AMD,则导出时使用

define()

否则,默认是浏览器环境,直接在window对象上添加

简单实例


(function (global, factory) {
    // 导出模块
})(this, (function () {
    // 真正的逻辑代码
}))

首先,上面这段代码,可以算是一个模板代码,你可以在各种JS库的源码里看到类似的影子。

这段代码定义了一个立即执行函数:把当前的全局对象(this)和一个匿名函数当作参数传给了另外一个马上就要执行的匿名函数

改写成这样可以容易理解点:


(function B (global, factory) {
    // 导出模块
})(this, (function A () {
    // 真正的逻辑代码
}))

全局对象this和函数A当作参数传给了函数B,函数B通过global接收this,factory接收A,然后函数B立即执行

hentai.js


(function (global, factory) {
    if (typeof exports === 'object' && typeof module !== 'undefined') {
        // CommonJS、CMD规范检查
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD规范检查
        define(factory);
    } else {
        // 浏览器注册全局对象
        global.Hentai = factory();
    }
})(this, (function () {
    function say() {
        console.log('hello hentai');
    }

    return {
        say: say
    }
}))

现在你可以在浏览器或者node中使用了

<script src="./hentai.js"></script>
<script>
    Hentai.say(); // hello hentai
</script>
const Hentai = require('hentai');
Hentai.say(); // hello hentai

Share this post on:

Previous Post
再见,2017
Next Post
从零开始搭建一个简单的基于webpack的vue开发环境