简体   繁体   English

自定义轻量级 JavaScript 库:EnderJS 和 MicroJS

[英]Custom Lightweight JavaScript Libraries: EnderJS and MicroJS

I'm working on a custom lightweight JavaScript library that will need to run stably across the major browsers as well as across numerous independent sites without compromising or being compromised by existing libraries or namespaces.我正在开发一个自定义的轻量级 JavaScript 库,该库需要在主要浏览器以及众多独立站点上稳定运行,而不会影响或受到现有库或命名空间的影响。 Perhaps most importantly, the library will need to be lightweight (~15k max).也许最重要的是,库需要是轻量级的(最大约 15k)。

UPDATE To clarify the need for such a small library: This is a third-party service that sites would pull into their page.更新澄清对这样一个小型图书馆的需求:这是一个第三方服务,网站会拉入他们的页面。 We need to keep everything as light-weight, speedy, and self-contained as possible since we have no control over the existent libraries, speed, or page load.由于我们无法控制现有的库、速度或页面加载,我们需要尽可能保持轻量、快速和独立。 15k is the target number just for the library that is accessed by the dynamic content of the service. 15k 是仅用于服务的动态内容访问的库的目标编号。

At this point my idea is to start with the most condensed jQuery-like base I can find, and then extend with custom modules.在这一点上,我的想法是从我能找到的最精简的类 jQuery 基础开始,然后使用自定义模块进行扩展。

Desired features:所需功能:

  • Handle cross-browser inconsistencies like a champ (IE 6+, Chrome, FF 2+, Safari 3+).像冠军一样处理跨浏览器的不一致(IE 6+、Chrome、FF 2+、Safari 3+)。
  • Event handling (queuing/binding/broadcasting)事件处理(排队/绑定/广播)
  • Efficient selector engine高效的选择器引擎
  • Chaining链接
  • DOM manipulation w/ basic animations带有基本动画的 DOM 操作
  • Readily build-able and version-able from modules易于从模块构建和版本化

I've come across EnderJS and MicroJS but I can't seem to find a lot of discussion on either.我遇到过EnderJSMicroJS ,但似乎都找不到很多讨论。 I'm more familiar and interested in Ender at this point since it seems to address all of the above features almost out of the box with "The Jeesh" weighing in at 7.5k.在这一点上,我对 Ender 更加熟悉和感兴趣,因为它似乎解决了几乎开箱即用的所有上述功能,而“The Jeesh”的重量为 7.5k。 Tacking on a couple additional packages only pushes it to 10k in my case which would be perfect since I should only need a few k to flesh out any custom modules.在我的情况下,添加几个额外的包只会将它推到 10k,这将是完美的,因为我应该只需要几 k 来充实任何自定义模块。 It also would allow me to write and version distinct modules that can be incorporated and compressed into the main library at build-time, as well as define a unique namespace to hold it all together and hopefully protect it.它还允许我编写和版本不同的模块,这些模块可以在构建时合并并压缩到主库中,并定义一个独特的命名空间来将它们保存在一起并希望保护它。 Another compelling piece to the Ender library is its use of NodeJS which I would love to play around with more anyway. Ender 库的另一个引人入胜的部分是它对NodeJS的使用,无论如何我都愿意更多地使用它。 Having said all of that, however, I am still wide open to other ideas.然而,说了这么多,我仍然对其他想法持开放态度。

So my question is:所以我的问题是:

Does anyone have any experience with either EnderJS or MicroJS , or have another solution/approach to what I'm trying to accomplish?有没有人对EnderJSMicroJS有任何经验,或者对我想要完成的事情有另一种解决方案/方法? I realize this is not the place for "chatty, open-ended questions" , and that's not my intent here.我意识到这不是“喋喋不休,开放式问题”的地方,这不是我的意图。 I'm just looking for suggestions on the best way to approach building a light-weight custom library without reinventing the wheel and to instead plug into the most up to date micro-libraries available.我只是在寻找有关在不重新发明轮子的情况下构建轻量级自定义库的最佳方法的建议,而是插入可用的最新微库。

I'm one of the co-creators of Ender and I'll +1 Fazal's words.我是 Ender 的共同创造者之一,我会 +1 Fazal 的话。

A note on the Jeesh, albeit a nice starter-pack to Ender, the true power lies in the ability to extend Ender with its growing set of modules.关于 Jeesh 的说明,尽管对 Ender 来说是一个不错的入门包,但真正的力量在于能够通过其不断增长的模块集来扩展 Ender。 You can check them out here: https://github.com/ender-js/Ender/wiki/Ender-package-list你可以在这里查看它们: https://github.com/ender-js/Ender/wiki/Ender-package-list

Somehow, one way or another Ender became the forefront of "micro library" development, but really what we're after is putting a cohesive interface onto loosely coupled modules (however large or small they are).不知何故,Ender 以某种方式成为“微库”开发的前沿,但我们真正追求的是在松散耦合的模块(无论它们大小)上放置一个内聚的接口。 jQuery took a great first step in abstracting its selector engine (Sizzle), but unfortunately the rest of it is interdependent (dom, events, animation, ajax, utils, promises), thus making it impossible to pick and pull what you want. jQuery took a great first step in abstracting its selector engine (Sizzle), but unfortunately the rest of it is interdependent (dom, events, animation, ajax, utils, promises), thus making it impossible to pick and pull what you want.

On another aside, one of the neat things about Ender is the ability to publish modules to NPM and being able to port them into your project by name allowing you to build only what you need, when you need it另一方面,关于 Ender 的一个巧妙之处是能够将模块发布到 NPM 并能够by name将它们移植到您的项目中,从而允许您在build only what you need, when you need it

It's worth checking out the learn videos at http://enderjs.com/learn which will give you a better idea of how packages are authored, built, and consumed.值得查看http://enderjs.com/learn上的学习视频,这将使您更好地了解包的创作、构建和使用方式。 You'll find that setting up Ender into your environment is extremely simple and actually quite fun to work with.您会发现将 Ender 设置到您的环境中非常简单,而且实际上使用起来非常有趣。

Let us (@ded or @fat) know if you have any questions and we'll be more than willing to help sort things out如果您有任何问题,请告诉我们(@ded 或 @fat),我们非常乐意帮助您解决问题

I've used Ender recently, and I've had no issues with it really.我最近使用了 Ender,我真的没有遇到任何问题。 There are a couple of jQuery functions that aren't available from the off, but anyone who is fairly adept at JavaScript can circumvent this.有几个 jQuery 功能从一开始就无法使用,但是任何精通 JavaScript 的人都可以规避这一点。 Especially given the fact that Ender has a near identical structure and way of extending as jQuery.特别是考虑到 Ender 具有与 jQuery 几乎相同的结构和扩展方式这一事实。

I've used Ender on a live site recently and funnily enough I have used a couple of scripts from microjs.com alongside my own functions file, and all the JavaScript weighed in at around 15k.我最近在一个现场网站上使用了 Ender,有趣的是,我使用了来自 microjs.com 的几个脚本以及我自己的函数文件,所有 JavaScript 的重量都在 15k 左右。 It's not hard to make your entire site code weigh around that or less.使您的整个站点代码的权重大约等于或小于该值并不难。

As well as building a lightweight version of Ender, for example starting with the Jeesh, you might also want to consider async loading, an example is provided by Dustin Diaz :除了构建轻量级版本的 Ender,例如从 Jeesh 开始,您可能还需要考虑异步加载, Dustin Diaz提供了一个示例:

<script src="ender.min.js"></script>

<script>
$.require('/js/core.min.js', 'core')

$.ready('core', function () {
  $(document).ready(function () {
    $('<p>hello world</p>').appendTo('body')
      .bind('click', function (e) {
        $.require('/js/ajax.min.js', function () {
          $(e.target).css('position', 'relative')
            .animate({
              left: 500
            })
        })
      })
  })
})
</script>

By doing this you could essentially make the original ender build even lighter, and defer some of the loading, but generally speaking, if it's light in the first place you should be ok.通过这样做,您基本上可以使原始末影构建更轻,并推迟一些加载,但一般来说,如果它首先是轻的,您应该没问题。

You might also want to take advantage of the Google closure compiler that Ender gives you access to in order to compile your site code alongside ender.您可能还想利用 Ender 允许您访问的 Google 闭包编译器,以便与 ender 一起编译您的站点代码。

Finally, as you're probably well aware, you can do noConflict in Ender as well, just in case they already have another library present.最后,您可能很清楚,您也可以在 Ender 中执行 noConflict ,以防万一他们已经存在另一个库。

As you build and configure Ender you will probably want to take advantage of ender-wallet which will give you a sort of API view, allowing you to remove libraries you might not need at all.在构建和配置 Ender 时,您可能希望利用 ender -wallet ,它会给您一种 API 视图,允许您删除您可能根本不需要的库。

hotlinked screenshot:热链接截图:
截屏

Given this:鉴于这种:

To clarify the need for such a small library: This is a third-party service that sites would pull into their page.澄清对这样一个小型库的需求:这是一个第三方服务,网站会拉入他们的页面。 We need to keep everything as light-weight, speedy, and self-contained as possible since we have no control over the existant libraries, speed, or page load.由于我们无法控制现有的库、速度或页面加载,我们需要尽可能保持轻量、快速和独立。 15k is the target number just for the library that is accessed by the dynamic content of the service. 15k 是仅用于服务的动态内容访问的库的目标编号。

I'd recommend using demand-loaded jQuery via one of the CDNs (Google's or Microsoft's; I think Google's is used more but you'd want to test).我建议通过 CDN 之一(谷歌或微软的;我认为谷歌的使用更多,但你想测试)使用按需加载的 jQuery。 Your code can detect whether jQuery is already loaded and use it if so (~0k), and if not add a script element dynamically that pulls it from the CDN.您的代码可以检测 jQuery 是否已经加载,如果是(~0k)则使用它,如果没有,则动态添加一个script元素,从 CDN 中提取它。 If the user has visited any other site using jQuery from that CDN, then the script may well come from cache (~0k).如果用户使用该 CDN 中的 jQuery 访问了任何其他站点,则脚本很可能来自缓存 (~0k)。 If not, granted, then you have the ~31k rather than ~15k hit, but again, quite frequently you won't have any hit, or just the hit of a "not modified" response from the CDN.如果没有,当然,那么你有 ~31k 而不是 ~15k 命中,但同样,你经常不会有任何命中,或者只是来自 CDN 的“未修改”响应的命中。

You'd want to issue a noConflict call if you did load it, in case the site uses $ for something other than jQuery.如果你确实加载了它,你会想要发出一个noConflict调用,以防网站使用$来代替 jQuery 以外的东西。 That's readily done by watching for the load event on the script element (you have to use readystatechange on IE and watch for either loaded or complete status) and then doing it when that comes through.这很容易通过观察script元素上的load事件来完成(您必须在 IE 上使用readystatechange并观察loadedcomplete状态),然后在完成时执行它。

In today's telecomms world, the difference between a 15k download and a 31k download is trivial compared with the cost of setting up the HTTP connection in the first place.在当今的电信世界中,与首先建立 HTTP 连接的成本相比,15k 下载和 31k 下载之间的差异微不足道

That demand-load really is a tiny bit of code, along these lines:该需求负载实际上是一小段代码,大致如下:

function loadJQuery(cb) {
    var d, s, t;

    if (typeof jQuery === "function"
        && parseFloat(jQuery.fn.jquery) >= 1.5) { /* Or whatever */
        window.ourjQuery = jQuery;
        if (cb) {
            cb();
        }
        return;
    }

    d = document;
    s = d.createElement('script');
    t = d.body || d.getElementsByTagName('head')[0] || d.documentElement;

    s.onload = loaded;
    s.onreadystatechange = handleReadyStateChange;
    s.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
    t.appendChild(s);

    function loaded() {
        if (s) {
            s = undefined;
            window.ourjQuery = jQuery.noConflict(true);
            if (cb) {
                cb();
            }
        }
    }

    function handleReadyStateChange() {
        if (s && (s.readyState === "loaded" || s.readyState === "complete")) {
            loaded();
        }
    }
}    

Note the URL on the script element.请注意script元素上的 URL。 That's so it's friendly to both http and https pages ( details ).所以它对httphttps页面都很友好(详情)。 Note also that I'm checking for a minimum jQuery version and using the more rigorous form of noConflict if we load it.另请注意,我正在检查最低 jQuery 版本,如果我们加载它,则使用更严格的noConflict形式。 Either way, by the time the callback is called, the ourjQuery symbol refers to the loaded copy with the minimum version.无论哪种方式,在调用回调时, ourjQuery符号都指向加载的具有最低版本的副本。


Update : Addressing your comment above:更新:解决您的上述评论:

That's a good idea but unfortunately not really an option for us.这是一个好主意,但不幸的是,这对我们来说并不是一个真正的选择。 I agree jQuery from Google's CDN would most likely be cached - saving load - and that we could check and extend as needed, but it doesn't seem as scalable or stable as serving it ourselves.我同意来自 Google 的 CDN 的 jQuery 很可能会被缓存 - 节省负载 - 我们可以根据需要进行检查和扩展,但它似乎不像我们自己提供服务那样可扩展或稳定。 The site could decide to overwrite some jQuery module to suit their needs or worse.该站点可能会决定覆盖一些 jQuery 模块以满足他们的需求或更糟。 What we need is a light-weight self-contained library that we have complete control over and can extend and branch as needed.我们需要的是一个轻量级的自包含库,我们可以完全控制它,并且可以根据需要进行扩展和分支。 The goal is that this library will be cached and versioned from our CDN.目标是这个库将从我们的 CDN 缓存和版本化。

Yes, there's a small risk of a site having modified basic jQuery functionality.是的,网站修改基本 jQuery 功能的风险很小。 A very small risk.很小的风险。 If you're restricting yourself to the core API (not plugins and such) I frankly don't think it's worth worrying about.如果您将自己限制在核心 API (不是插件等),坦率地说,我认为这不值得担心。

But if you're worried about that, then frankly I'd just use a slightly-modified jQuery hosted on your own CDN using a different symbol than jQuery (and not using $ at all).但是,如果您对此感到担心,那么坦率地说,我会使用与jQuery不同的符号(并且根本不使用$ )托管在您自己的 CDN 上的稍作修改的 jQuery。 31k vs. 15k in today's telecomms world is a non-issue;在当今的电信世界中,31k 与 15k 不是问题; the primary cost will be in establishing the connection in the first place.主要成本将是首先建立连接。 If you wanted, you could probably pare that down a bit by removing parts you don't need, although sadly the jQuery internals are a bit of a morass and selectively removing functionality may not be trivial (depending on what functionality it is).如果你愿意,你可以通过移除你不需要的部分来减少它,尽管遗憾的是 jQuery 内部有点像泥沼,选择性地移除功能可能不是微不足道的(取决于它是什么功能)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM