简体   繁体   English

构建JavaScript框架时如何实现图书馆不可知论?

[英]How to achieve library-agnosticism when building a javascript framework?

I've started looking into architecturing a javascript framework. 我已经开始研究构造JavaScript框架。

I don't want to reinvent the wheel here, especially regarding browser quirks, and know that for that matter, I'll have to rely, at some point, on some commonly-used libraries to handle low-level concerns. 我不想在这里重新发明轮子,尤其是在浏览器怪癖方面,并且我知道在这一点上,我将不得不依靠某些常用的库来处理低级问题。

The thing is, I'm not sure how i can depend on an external library for some piece of functionality (say for example dom manipulation), without tying it to my design. 问题是,我不确定如何将外部库依赖于某些功能(例如dom操纵),而不将其与我的设计联系在一起。

Practical examples would help make a better point, but I'm not at the design stage yet, and I'm merely trying to avoid getting started on the wrong foot. 实际的例子将有助于提出更好的观点,但是我还没有进入设计阶段,我只是想避免从错误的脚步入手。

So I'm looking for some examples, guidelines, best-practices or maybe patterns that could help in this situation. 因此,我正在寻找一些示例,准则,最佳实践或可能对这种情况有帮助的模式。

Any insight ? 有见识吗?

EDIT : Bit of a clarification on why I'd want to do this. 编辑:关于我为什么要这样做的一点说明。
My goal is to build something resembling more of an application framework than most traditional libraries like jQuery. 我的目标是构建比jQuery之类的大多数传统库更像应用程序框架的东西。
Think layered architecture, where the libraries would fit into the infrastructure layer (as per Evans' definition in Domain Driven Design), and handle things such as events, dom traversing and manipulation etc... 考虑分层架构,其中库适合基础架构层(根据Evans在域驱动设计中的定义),并处理事件,dom遍历和操纵等事情。

This is a very broad question, but if I were you, I would use jQuery as a base. 这是一个非常广泛的问题,但是如果我是您,我将使用jQuery作为基础。 It is a very easy library to extend and add functionality too. 这也是一个非常容易扩展和添加功能的库。

I'd recommend grabbing a copy of ExtJS and taking a look at how they provide support for replacing the underlying core of their product. 我建议您获取一份ExtJS副本,然后看看它们如何为替换产品的基础核心提供支持。 You can use their higher level libraries, such as grids, trees, etc, but choose to use YUI or prototype in place of their Ext core. 您可以使用其较高级的库,例如网格,树等,但是可以选择使用YUI或原型代替其Ext核心。

That should give you a good starting point. 那应该给你一个很好的起点。

Edit to answer comment: 编辑以回答评论:

Once you've downloaded ExtJS, take a look in the "adapter" folder. 下载ExtJS后,请查看“适配器”文件夹。 In there, you'll see the various adapters that exist to make ExtJS work with other libraries. 在其中,您将看到使ExtJS与其他库一起使用的各种适配器。 You'll quickly see how they define functions that in turn make use of the appropriate underlying lib. 您将快速了解它们如何定义功能,这些功能又利用适当的基础库。

Segregate your code: 隔离您的代码:

use the external libraries to the fullest possible, within their separate section of code. 在代码的单独部分中,尽可能充分地使用外部库。

Taking jQuery as an example, just designate a section for interfacing with jQuery and then use jQuery within that section of the library like there's no tomorrow, and give it interface functions that the rest of the code uses exclusively. 以jQuery为例,只需指定一个与jQuery接口的部分,然后在库的该部分中使用jQuery,就像没有明天一样,并为其提供其余代码专用的接口功能。

Frankly, if you integrate a library with your code and try to make it generic enough that you can trivially swap it out with something else, you're probably going to neuter the library to the point where you might as well have not included it at all. 坦白说,如果您将一个库与您的代码集成在一起,并尝试使其足够通用,以至于可以将其与其他内容进行微不足道的交换,那么您可能会将中立该库,以至于您可能还没有在其中包含它所有。

Accept that you may need to rewrite if you end up swapping libraries, but prepare for that by giving the library-interfacing code it's own separate section, and you'll be able to write less generic, more powerful code with those external libraries and save yourself a lot of work. 接受如果您最终交换库可能需要重写,但是为此提供库接口代码是它自己的单独部分,为此您可以做准备,并且可以使用那些外部库编写更少通用,更强大的代码并保存自己很多工作。

This doesn't answer your pattern question, but a word about the frameworks. 这不会回答您的模式问题,而是有关框架的一句话。 All of the modern JavaScript libraries are pretty good at playing well with each other, but some are better than others. 所有现代JavaScript库在相互配合方面都非常擅长,但是其中一些优于其他。 Just make sure that they libraries don't monkey-patch the core objects with arbitrary properties or muck with the global namespace and you should be good to go. 只需确保它们的库不会胡闹地修补具有任意属性的核心对象,或者不要将其与全局命名空间混为一谈,那么您应该一切顺利。 JQuery and YUI are both well designed and namespaced libraries. JQuery和YUI都是经过精心设计和命名空间的库。 Dojo is also quite good, but a couple years ago when looking at all of the options, it seemed like Dojo encouraged the use of proprietary element attributes in markup as JS hooks. Dojo也相当不错,但是几年前,当查看所有选项时,Dojo似乎鼓励在标记中使用专有元素属性作为JS挂钩。 At that time Prototype was the library that mucked with objects like String/Array and didn't play well with others. 当时,Prototype是一个库,里面充斥着String / Array之类的对象,与其他对象的配合不好。 I haven't looked/used Dojo or Prototype so take that with a grain of salt. 我还没有看过/使用过Dojo或Prototype,所以请带一点盐。 I'm actively using YUI and JQuery in the same app; 我正在同一个应用程序中积极使用YUI和JQuery; YUI for widgets and event management and JQuery for Selector/DOM manipulation. YUI用于小部件和事件管理,JQuery用于选择器/ DOM操作。

I'd suggest you pick a single general purpose library or no library at all, depending on the requirements of the framework you plan to write. 我建议您根据计划编写的框架的要求,选择一个通用库或根本不选择任何库。 It's very difficult to make any kind of recommendation without more information, such as what your framework is aiming to achieve, who will be using it and in what kind of environment. 没有更多信息就很难提出任何建议,例如您的框架旨在实现什么,谁将使用它以及在什么样的环境中使用。

If you're considering writing a script of reasonable complexity then I would suggest learning the relevant "low level" DOM manipulation techniques for yourself. 如果您正在考虑编写合理复杂性的脚本,那么我建议您自己学习相关的“低级” DOM操作技术。 It's not as difficult as devotees of some of the famous general purpose libraries would have you believe. 这并不像某些著名的通用库的奉献者所相信的那样困难。

Use some kind of interface to link to the library. 使用某种接口链接到库。

Don't do: 不要做:

$("blah").something();

do

something("blah")

function something(id){
  $(id).something();
}

Since you could call something() 20 times, it'll be simpler to update if the actual use of the library is in only 1 place. 由于您可以调用something()20次,因此如果只在1个地方实际使用该库,则更新起来会更简单。

It'll add development time and then complexity, but you won't be as dependent on a library. 它会增加开发时间,然后增加复杂性,但您不会像以前那样依赖库。

I don't think this can be achieved very effortlessly. 我认为这很难做到。 If you really want this behavior, I think you'd have to manually map the features that are covered by all libraries you want to include support for. 如果您确实想要这种行为,我想您必须手动映射要包含其支持的所有库所涵盖的功能。

So that the implementation would look like: 这样实现看起来像:

yourLibrary.coreFramework = 'prototype';
yourLibrary.doStuff();

And your librar would treat it in the following manner: 并且您的librar将以以下方式对其进行处理:

function doStuff() {
   var elem = getElement('id');
   // do stuff with 'elem';
}

function getElement(id) {
   switch(this.coreFramework) {
       case 'prototype': return $(id);
       case 'jquery': return $('#'+id);
       /* etc */
   }
}

Check out the jQuery or prototype frameworks. 查看jQuery原型框架。

If you decide you need to, then extend these. 如果您决定需要,则将其扩展。

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

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