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

发布于 2024-11-17 22:56:04 字数 1393 浏览 2 评论 0原文

我正在开发一个自定义的轻量级 JavaScript 库,该库需要在主要浏览器以及众多独立站点上稳定运行,而不会影响现有库或命名空间或受到现有库或命名空间的影响。也许最重要的是,该库需要轻量级(最多约 15k)。

更新为了澄清对这样一个小型库的需求:这是网站将拉入其页面的第三方服务。我们需要使一切尽可能轻量、快速和独立,因为我们无法控制现有的库、速度或页面加载。 15k 是服务的动态内容访问的库的目标数量。

此时,我的想法是从我能找到的最简洁的类似 jQuery 的基础开始,然后使用自定义模块进行扩展。

所需功能:

  • 像冠军一样处理跨浏览器不一致问题(IE 6+、Chrome、FF 2+、Safari 3+)。
  • 事件处理(排队/绑定/广播)
  • 高效的选择器引擎
  • 链接
  • 使用基本动画
  • 模块中轻松构建和版本控制

DOM 操作 可以从我遇到的 EnderJSMicroJS 但我似乎找不到很多的讨论。此时我对 Ender 更加熟悉和感兴趣,因为它似乎使用 “The Jeesh” 重 7.5k。在我的例子中,添加几个额外的包只会将其推至 10k,这将是完美的,因为我只需要几 k 来充实任何自定义模块。它还允许我编写不同的模块并对其进行版本控制,这些模块可以在构建时合并并压缩到主库中,并定义一个独特的名称空间将其全部组合在一起并希望对其进行保护。 Ender 库的另一个引人注目的部分是它对 NodeJS 的使用,无论如何我都想尝试更多。然而,话虽如此,我仍然对其他想法持开放态度。

所以我的问题是:

有没有人有过 EnderJSMicroJS,或者有另一种解决方案/方法来实现我想要完成的任务?我意识到这不是“闲聊、开放式问题”的地方,这也不是我的意图。我只是在寻找有关构建轻量级自定义库的最佳方法的建议,而无需重新发明轮子,而是插入最新的可用微型库。

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. Perhaps most importantly, the library will need to be lightweight (~15k max).

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.

At this point my idea is to start with the most condensed jQuery-like base I can find, and then extend with custom modules.

Desired features:

  • Handle cross-browser inconsistencies like a champ (IE 6+, Chrome, FF 2+, Safari 3+).
  • Event handling (queuing/binding/broadcasting)
  • Efficient selector engine
  • Chaining
  • DOM manipulation w/ basic animations
  • 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. 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. 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. 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. 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? 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.

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

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

发布评论

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

评论(3

并安 2024-11-24 22:56:04

我是《安德》的共同创作者之一,我会为 Fazal 的话+1。

关于 Jeesh 的注释,尽管对 Ender 来说是一个不错的入门包,但真正的力量在于能够通过其不断增长的模块集来扩展 Ender。您可以在这里查看它们: https://github.com/ender- js/Ender/wiki/Ender-package-list

不知何故,Ender 成为了“微库”开发的前沿,但我们真正追求的是在松散耦合的模块上放置一个内聚的接口(但是它们有大有小)。 jQuery 在抽象其选择器引擎(Sizzle)方面迈出了伟大的第一步,但不幸的是,它的其余部分是相互依赖的(dom、事件、动画、ajax、utils、promise),因此无法选择和提取您想要的内容。

另一方面,Ender 的一个巧妙之处是能够将模块发布到 NPM 并能够按名称将它们移植到您的项目中,允许您仅构建您需要的内容,当你需要它

值得一看 http://enderjs.com/learn 上的学习视频将使您更好地了解如何编写包,建造和消耗。您会发现将 Ender 设置到您的环境中非常简单,而且实际上使用起来非常有趣。

如果您有任何疑问,请告诉我们(@ded 或 @fat),我们将非常乐意帮助解决问题

I'm one of the co-creators of Ender and I'll +1 Fazal's words.

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. You can check them out here: 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). 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

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. You'll find that setting up Ender into your environment is extremely simple and actually quite fun to work with.

Let us (@ded or @fat) know if you have any questions and we'll be more than willing to help sort things out

原来是傀儡 2024-11-24 22:56:04

我最近使用过 Ender,确实没有遇到任何问题。有几个 jQuery 函数一开始就无法使用,但任何相当擅长 JavaScript 的人都可以绕过这个。特别是考虑到 Ender 具有与 jQuery 几乎相同的结构和扩展方式。

我最近在一个实时网站上使用了 Ender,有趣的是,我使用了来自 microjs.com 的几个脚本以及我自己的函数文件,并且所有 JavaScript 的重量都在 15k 左右。让您的整个站点代码的权重在该范围内或更少并不困难。

除了构建 Ender 的轻量级版本(例如从 Jeesh 开始)之外,您可能还需要考虑异步加载,达斯汀·迪亚兹

<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>

通过这样做,你基本上可以使原始渲染器构建更轻,并推迟一些加载,但一般来说,如果一开始就很轻,你应该没问题。

您可能还想利用 Ender 为您提供的 Google 闭包编译器,以便与 ender 一起编译您的站点代码。

最后,您可能很清楚,您也可以在 Ender 中执行 noConflict,以防万一他们已经存在另一个库。

当你构建和配置 Ender 时,你可能会想要利用 ender-wallet ,它会给你一个排序API 视图,允许您删除可能根本不需要的库。

热链接截图:
screenshot

I've used Ender recently, and I've had no issues with it really. 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. Especially given the fact that Ender has a near identical structure and way of extending as 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. 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:

<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.

Finally, as you're probably well aware, you can do noConflict in Ender as well, just in case they already have another library present.

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.

hotlinked screenshot:
screenshot

很酷不放纵 2024-11-24 22:56:04

鉴于此:

澄清对这样一个小型库的需求:这是网站将拉入其页面的第三方服务。我们需要使一切尽可能轻量、快速和独立,因为我们无法控制现有的库、速度或页面加载。 15k 是服务的动态内容访问的库的目标数字。

我建议通过 CDN 之一使用按需加载的 jQuery(Google 或 Microsoft 的;我认为 Google 的使用较多,但您想测试一下)。您的代码可以检测 jQuery 是否已加载,如果已加载则使用它 (~0k),如果没有加载,则动态添加一个 script 元素以从 CDN 中提取它。如果用户使用该 CDN 中的 jQuery 访问过任何其他站点,则该脚本很可能来自缓存 (~0k)。如果没有,当然,那么您将获得约 31k 而不是约 15k 的点击量,但同样,您经常不会获得任何点击量,或者只是来自 CDN 的“未修改”响应的点击量。

如果您确实加载了它,则需要发出 noConflict 调用,以防网站将 $ 用于 jQuery 以外的其他内容。通过监视 script 元素上的 load 事件可以轻松完成此操作(您必须在 IE 上使用 readystatechange 并监视 loadedcomplete 状态),然后在完成时执行。

在当今的电信世界中,与最初建立 HTTP 连接的成本相比,15k 下载和 31k 下载之间的差异是微不足道的。

该需求加载实际上是一小段代码,大致如下:

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();
        }
    }
}    

注意 script 元素上的 URL。因此它对 httphttps 页面都很友好 (详细信息)。另请注意,我正在检查最低 jQuery 版本,并在加载它时使用更严格的 noConflict 形式。无论哪种方式,当调用回调时,ourjQuery 符号引用具有最低版本的加载副本。


更新:针对您的上述评论:

这是个好主意,但不幸的是,这对我们来说并不是一个真正的选择。我同意来自 Google CDN 的 jQuery 很可能会被缓存——节省负载——并且我们可以根据需要进行检查和扩展,但它似乎不像我们自己提供的那样可扩展或稳定。该网站可能会决定覆盖一些 jQuery 模块以满足他们的需求或更糟的需求。我们需要的是一个轻量级的独立库,我们可以完全控制它,并且可以根据需要进行扩展和分支。目标是该库将从我们的 CDN 进行缓存和版本控制。

是的,网站修改基本 jQuery 功能的风险很小。 非常风险很小。如果你将自己限制在核心 API(而不是插件等)上,坦率地说,我认为这不值得担心。

但如果你担心这一点,那么坦率地说,我只是使用托管在你自己的 CDN 上的稍微修改过的 jQuery,使用与 jQuery 不同的符号(并且不使用 $ 根本)。在当今的电信世界中,31k 与 15k 的区别不是问题;主要成本将首先在于建立连接。如果您愿意,您可能可以通过删除不需要的部分来减少一点,尽管遗憾的是 jQuery 内部有点混乱,并且有选择地删除功能可能并不微不足道(取决于它是什么功能)。

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.

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). 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. If the user has visited any other site using jQuery from that CDN, then the script may well come from cache (~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.

You'd want to issue a noConflict call if you did load it, in case the site uses $ for something other than 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.

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.

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. That's so it's friendly to both http and https pages (details). Note also that I'm checking for a minimum jQuery version and using the more rigorous form of noConflict if we load it. Either way, by the time the callback is called, the ourjQuery symbol refers to the loaded copy with the minimum version.


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. The site could decide to overwrite some jQuery module to suit their needs or worse. 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.

Yes, there's a small risk of a site having modified basic jQuery functionality. 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.

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). 31k vs. 15k in today's telecomms world is a non-issue; 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).

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