【问题标题】:"Bundling" solution for HTML/JS only?仅适用于 HTML/JS 的“捆绑”解决方案?
【发布时间】:2016-04-12 11:30:24
【问题描述】:

我相信有人会告诉我为什么这是一个糟糕的想法,但它可能比我们已经做的更好。所以我们所有的插件都被复制/粘贴到一个 Master.js 脚本中,这是一个更新或排序的噩梦。大多数插件都被缩小了(这很好),但我真的很想从 .net/c#/aspx 捆绑的想法,并实现一些类似的东西来摆脱这个 Master.js 文件。复制/粘贴新脚本通常会冻结项目,并且其中几乎所有内容都已过时 - 所以这是我的疯狂科学:

在 Master.js 中,创建一个包含所有使用的脚本的数组:

var scripts = [
    'jquery-1.10.2.min.js', // jQuery v1.10.2 | 2005 (https://code.jquery.com/)
    'jquery-migrate-1.2.1.min.js', // jQuery Migrate v1.2.1 | 2005 (https://code.jquery.com/)
    'jquery-ui.min.js', // jQuery UI v1.10.3 | 2014-09-14 (https://code.jquery.com/)
    'bootstrap.min.js', // Bootstrap v3.1.0 | 2014 (http://getbootstrap.com)
];

并创建一个循环以将脚本添加到页面:

for (var i = 0; i < scripts.length; i++) {

    var link = 'MainJS/' + scripts[i];

    LoadJsCssFilePortal(link, 'js');

};

function LoadJsCssFilePortal(filename, filetype, callback) {

    // if filename is a external JavaScript file
    if (filetype == "js") {
        var fileref = document.createElement('script');
        fileref.setAttribute("type", "text/javascript");
        fileref.setAttribute("src", filename);

    };

    if (typeof fileref != "undefined") {

        // add this script to the document
        document.getElementsByTagName("head")[0].appendChild(fileref);
    };


};

我也有这个功能

function LoadAndRunPortalJS(url, callback) {

        var script = document.createElement("script")
        script.type = "text/javascript";

        if (script.readyState) {  //IE
            script.onreadystatechange = function () {
                if (script.readyState === "loaded" || script.readyState === "complete") {
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else {  //Others
            script.onload = function () {
                callback();
            };
        }

        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);


};

它有一个内置回调并被这样调用

LoadAndRunPortalJS(link, function () {
    // when done load next
});

问题是脚本在加载之前没有完成

  1. 循环中的下一个增量
  2. 页面上其他依赖于 Master.js 的脚本

通常,可以使用 jquery 延迟对象来强制执行脚本的顺序/完成,因此这可能会在第一个脚本 (jquery) 加载 i > 0 后使用 - 但这并不能解决脚本运行的问题在主人之外。

【问题讨论】:

  • 这个问题已经通过合理的构建过程(Gulp、Grunt等)和它们的插件(minifiers、bundles)得到了全面的解决。解决方案不断发展;有趣的是,使用 HTTP/2 和 ES2015 模块,几年后我们可能不再需要捆绑(我们仍然需要缩小)。无论如何,我在这里看不到一个问题,至少没有一个足够窄的问题来回答。
  • 我在 Visual Studio 中工作,后端代码使用 C# 处理,但我无法更改页面的扩展名。我知道如果它们是 aspx,捆绑是可能的 - 但我没有那个选项。
  • @triplethreat77 — 这不会对您实施构建时间捆绑/缩小过程的能力产生负面影响。
  • @Quentin 我不太明白我在上面的代码中做错了什么。

标签: javascript jquery bundling-and-minification deferred


【解决方案1】:

这是脚本加载器/捆绑器的域。您可以考虑使用RequireJSWebpack 来获得开箱即用的解决方案。如果您仍想自己动手,请继续阅读。

我会用更具弹性的排序结构替换您拥有的文件名数组

var manifest = [
    {key: 'jquery', file: 'jquery-1.10.2.min.js'}
    ...
}

这应该可以处理任何未来可能弹出的版本控制问题(它会)。数组结构还保留了您的加载顺序(不推荐这种方法)。

在页面加载时,只会加载上述清单。您要调用的任何on load 函数都必须推迟到加载脚本为止。我建议使用类似于广告管理器(例如,谷歌广告)处理它的方法。

var onBootloaderInit = [/* array of functions */];
....
onBootloaderInit.push(
    function() {
        /* Code inside can now use jQuery or the likes */
    }
);

加载完成后,您现在只需遍历 onBootloaderInit 数组,然后执行每个函数。

要确保按您需要的顺序加载脚本并等待已排队的脚本,请使用脚本加载器(例如,LABjs)。

$LAB.script('<path to jQuery>').wait(function() {
    /* Code that depends on jQuery */
});

【讨论】:

    猜你喜欢
    • 2016-06-23
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多