关于javascript插件源码的问题?

发布于 2022-09-07 15:24:09 字数 296 浏览 13 评论 0

很多js插件源码都有如下代码:

//兼容CommonJs规范
if (typeof module !== 'undefined' && module.exports) module.exports = MyPlugin;

//兼容AMD/CMD规范
if (typeof define === 'function') define(function() { return MyPlugin; });

这两段代码具体作用是什么呢?
对于提高原生插件的编写能力有没有相关方面的书籍可以看呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧时光的容颜 2022-09-14 15:24:09

都是模块化方案。

amd 对应 requireJs
cmd 对应 seaJs
commonJs 对应 nodeJs

之所以都想兼容过去,是因为很多js文件可以兼容运行在浏览器和node环境,为了重复利用,加上你列出的通用代码,是最合适不过的,比如一个字符串处理trim,那么就可以在node和browser同时使用。不加模块化代码的话,就可能得写3份重复的js了。

怂人 2022-09-14 15:24:09

这些基本都是模块化方案,实际上自己页很容易写出模块化的原理
webpack

(function(modulesArr) {
    var rootModule = {};
    function __require__(id) {
        if (rootModule[id]) {
            return rootModule[id].exports;
        }
        var currentModule = modulesArr[id];
        var module = {
            id,
            exports: {}
        };
        currentModule.call(module.exports, module.exports, module, __require__);
        currentModule[id] = module;
        return module.exports;
    }
    return __require__(0);
})([
    function(exports, module, require) {
        var m1 = require(1);
        console.log(m1);
    },
    function(exports, module, require) {
        exports.msg = 'Hello World';
        var m2 = require(2);
        m2();
    },
    function(exports, module, require) {
        module.exports = function() {
            var str = 'Hello World';
            console.log(str);
            return str;
        };
    }
]);

我自己实现的browser端模块化

(function(global) {
    'use strict';
    var errMsg = Math.random().toString(32).substr(2);
    var rootModule = {};
    function ModuleCtor(id) {
        if (!this || this.__proto__ !== ModuleCtor.prototype) {
            return new ModuleCtor(id);
        }
        this.id = id;
        this.exports = {};
        this.loaded = !1;
    }

    function define(id, fn) {
        if (typeof id === 'function') {
            fn = id;
            id = document.currentScript
                ? document.currentScript.src
                : Math.random()
                      .toString(32)
                      .substr(2);
        }
        if (typeof id !== 'string') {
            id = '' + id;
        }
        var module = ModuleCtor(id);
        exec();
        function __require__(src) {
            if (rootModule[src] && rootModule[src].__proto__ === ModuleCtor.prototype) {
                return rootModule[src].exports;
            }
            loadScript(src, function() {
                exec();
            });
            throw new Error(errMsg);
        }
        function exec() {
            try {
                fn.call(module.exports, module.exports, module, __require__);
                module.loaded = !0;
                rootModule[id] = module;
            } catch (err) {
                if (err.message !== errMsg) {
                    throw err;
                }
            }
        }
    }

    function loadScript(src, callback) {
        var script = document.createElement('script');
        script.src = src;
        script.onload = function() {
            callback && callback(src);
        };
        document.body.appendChild(script);
        return script;
    }
    global.define = define;
})(window);

本质都是js没有模块,所以我们就想到全局暴露一个rootModule对象,每一个键都是一个模块,exports对象是依赖的暴露。
如a.js

    module.exports = 'Hello World';

b.js

    var chars = require('./a');
    process.stdout.write(chars + '\n'); // Hello World

但是我们怎么实现呢,(一)编译:如webpack,(二)暴露一个函数,如requirejs、seajs。


webpack 可以配置 output libraryTarget: 'umd', library: 'globalVarName' 打题主说的这种umd包,兼容浏览器,requirejs,node环境。


另外我还是忍不住吐槽一下seajs的垃圾,一个文件的多个require发请求时没有顺序之分,字符串正则来分析依赖。。。如果jQuery的plugin依赖jQuery,需要对jQueryplugin改一下代码讨个套个客,不能直接想requirejs直接在config中声明依赖。垃圾。当然我自己写的模块加载更垃圾,连依赖都不分析。多try几次必然成功。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文