使用 Browserify-shim 配置通用 jQuery 插件? [英] Configure a generic jQuery plugin with Browserify-shim?

查看:44
本文介绍了使用 Browserify-shim 配置通用 jQuery 插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 browserify-shim 并且我想使用一个通用的 jQuery 插件.我已经多次查看 Browserify-shim 文档,但我似乎无法理解发生了什么和/或它如何知道在哪里放置插件、附加到 jQuery 对象等.这是我的 package.json 文件的样子:

I'm using browserify-shim and I want to use a generic jQuery plugin. I have looked over the Browserify-shim docs multiple times and I just can't seem to understand what's going on and/or how it knows where to put plugins, attach to the jQuery object etc. Here's what my package.json file looks like:

"browser": {
  "jquery": "./src/js/vendor/jquery.js",
  "caret": "./src/js/vendor/jquery.caret.js"
},

"browserify-shim": {
  "caret": {
     "depends": ["jquery:$"]
  }
}

根据 browserify-shim 文档中给出的示例,我不想指定导出,因为此插件(以及大多数(如果不是全部)jQuery 插件)将自身附加到 jQuery 对象.除非我在上面做错了什么,否则当我使用它时,我不明白为什么它不起作用(我收到一个错误,告诉我函数未定义).见下文:

According the the example given on the browserify-shim documentation, I don't want to specify an exports because this plugin (and most if not all jQuery plugins) attach themselves to the jQuery object. Unless I'm doing something wrong above, I don't understand why it doesn't work (I get an error telling me the function is undefined) when I use it. See below:

$('#contenteditable').caret(5);  // Uncaught TypeError: undefined is not a function

所以我的问题是,如何使用 browserify 和 browserify-shim 配置通用 jQuery 插件(将自身附加到 jQuery 对象)?

So my question is, how does one configure a generic jQuery plugin (which attaches itself to the jQuery object) with browserify and browserify-shim?

推荐答案

在重新审视这个问题并尝试了更多的东西之后,我终于把我的头脑放在了 browserify-shim 正在做什么以及如何使用它上.对我来说,在我最终理解如何使用 browserify-shim 之前,我必须掌握一个关键原则.对于两个不同的用例,基本上有两种使用 browserify-shim 的方法:公开 &匀场.

After revisiting this and trying some more things, I finally wrapped my head around what browserify-shim is doing and how to use it. For me, there was one key principle I had to grasp before I finally understood how to use browserify-shim. There are basically two ways to use browserify-shim for two different use cases: exposing & shimming.

假设您只想在标记中放入脚本标记(出于测试或性能原因,例如缓存、CDN 等).通过在标记中包含脚本标签,浏览器将点击脚本,运行它,并且很可能在 window 对象上附加一个属性(在 JS 中也称为全局).当然,这可以通过执行 myGlobalwindow.myGlobal 来访问.但是这两种语法都有问题.它不遵循 CommonJS 规范,这意味着如果模块开始支持 CommonJS 语法(require()),您将无法利用它.

Let's say you want to just drop in a script tag in your markup (for testing or performance reasons like caching, CDN & the like). By including a script tag in the markup the browser will hit the script, run it, and most likely attach a property on the window object (also known as a global in JS). Of course this can be accessed by either doing myGlobal or window.myGlobal. But there's an issue with either syntax. It doesn't follow the CommonJS spec which means that if a module begins supporting CommonJS syntax (require()), you're not able to take advantage of it.

Browserify-shim 允许你指定一个你想要暴露"的全局变量.通过 CommonJS require() 语法.记住,你可以做 var nothing = global;var nothing = window.global; 但你不能做 var nothing = require('global') 并期望它为您提供正确的库/模块.不要对变量的名称感到困惑.它可以是任意的.您本质上是将全局变量设为局部变量.这听起来很愚蠢,但它是浏览器中 JS 的可悲状态.同样,希望一旦一个库支持 CommonJS 语法,它就永远不会通过 window 对象上的全局附加自身.这意味着您必须使用 require() 语法并将其分配给局部变量,然后在任何需要的地方使用它.

Browserify-shim allows you to specify a global you'd like "exposed" through CommonJS require() syntax. Remember, you could do var whatever = global; or var whatever = window.global; but you could NOT do var whatever = require('global') and expect it to give you the right lib/module. Don't be confused about the name of the variable. It could be anything arbitrary. You're essentially making a global variable a local variable. It sounds stupid, but its the sad state of JS in the browser. Again, the hope is that once a lib supports CommonJS syntax it will never attach itself via a global on the window object. Which means you MUST use require() syntax and assign it to a local variable and then use it wherever you need it.

注意:我发现 browserify-shim 文档/示例中的变量命名有些混乱.请记住,关键是您希望包含一个库就好像它是一个行为正常的 CommonJS 模块.因此,您最终要做的是告诉 browserify,当您需要 myGlobal require('myGlobal') 时,您实际上只想在 window 对象上获得全局属性 window.myGlobal.

Note: I found variable naming slightly confusing in the browserify-shim docs/examples. Remember, the key is that you want to include a lib as if it were a properly behaving CommonJS module. So what you end up doing is telling browserify that when you require myGlobal require('myGlobal') you actually just want to be given the global property on the window object which is window.myGlobal.

事实上,如果您对 require 函数的实际作用感到好奇,它非常简单.这是幕后发生的事情:

In fact, if you're curious as to what the require function actually does, it's pretty simple. Here's what happens under the hood:

var whatever = require('mygGlobal');

变成……

var whatever = window.mygGlobal;

暴露

有了这个背景,让我们看看我们如何在我们的 browserify-shim 配置中公开一个模块/库.基本上,您告诉 browserify-shim 两件事.调用 require() 时希望它访问的名称以及它应该在 window 对象上找到的全局变量.所以这就是 global:* 语法的用武之地.让我们看一个例子.我想在 index.html 中将 jquery 作为脚本标记放入,以便获得更好的性能.这是我需要在我的配置中做的事情(这将在 package.json 或外部配置 JS 文件中):

Exposing

So with that background, let's see how we expose a module/lib in our browserify-shim config. Basically, you tell browserify-shim two things. The name you want it accessible with when you call require() and the global it should expect to find on the window object. So here's where that global:* syntax comes in. Let's look at an example. I want to drop in jquery as a script tag in index.html so I get better performance. Here's what I'd need to do in my config (this would be in package.json or an external config JS file):

"browserify-shim": {
  "jquery": "global:$"
}

这就是这意味着什么.我已经在其他地方包含了 jQuery(请记住,browserify-shim 不知道我们把标签放在哪里,但它不需要知道),但我想要的只是被赋予 $ 属性当我需要带有字符串参数jquery"的模块时,在窗口对象上.进一步说明.我也可以这样做:

So here's what that means. I've included jQuery somewhere else (remember, browserify-shim has no idea where we put our tag, but it doesn't need to know), but all I want is to be given the $ property on the window object when I require the module with the string parameter "jquery". To further illustrate. I could also have done this:

"browserify-shim": {
  "thingy": "global:$"
}

在这种情况下,我必须传递thingy"作为 require 函数的参数,以便返回 jQuery 对象的实例(它只是从 window.$ 获取 jQuery):

In this case, I'd have to pass "thingy" as the parameter to the require function in order to get an instance of the jQuery object back (which it's just getting jQuery from window.$):

var $ = require('thingy');

是的,变量名可以是任何东西.$ 与实际 jQuery 库使用的全局属性 $ 没有什么特别之处.尽管使用相同的名称以避免混淆是有意义的.这最终会引用窗口对象上的 $ 属性,由包中 browserify-shim 对象中的 global:$ 值选择.json.

And yes, again, the variable name could be anything. There's nothing special about $ being the same as the global property $ the actual jQuery library uses. Though it makes sense to use the same name to avoid confusion. This ends up referencing the the $ property on the window object, as selected by the global:$ value in the browserify-shim object in package.json.

好的,所以几乎涵盖了暴露.browserify-shim 的另一个主要功能是填充.那是什么?Shimming 与公开的作用本质上是相同的,除了不是将 lib 或模块包含在 HTML 标记中并带有类似 script 标签的东西,您告诉 browserify-shim 在本地获取 JS 文件的位置.无需使用 global:* 语法.所以让我们回顾一下我们的 jQuery 示例,但这次假设我们不是从 CDN 加载 jQuery,而是简单地将它与所有 JS 文件捆绑在一起.所以这里是配置的样子:

Ok, so that pretty much covers exposing. The other main feature of browserify-shim is shimming. So what's that? Shimming does essentially the same thing as exposing except rather than including the lib or module in HTML markup with something like a script tag, you tell browserify-shim where to grab the JS file locally. There's no need to use the global:* syntax. So let's refer back to our jQuery example, but this time suppose we are not loading jQuery from a CDN, but simply bundling it with all the JS files. So here's what the config would look like:

"browser": {
  "jquery": "./src/js/vendor/jquery.js", // Path to the local JS file relative to package.json or an external shim JS file
},
"browserify-shim": {
  "jquery": "$"
},

此配置告诉 browserify-shim 从指定的本地路径加载 jQuery,然后从 window 对象中获取 $ 属性,并在您需要带有字符串参数的 jQuery 时将其返回给jquery"的 require 函数.同样,出于说明目的,您也可以将其重命名为其他任何名称.

This config tells browserify-shim to load jQuery from the specified local path and then grab the $ property from the window object and return that when you require jQuery with a string parameter to the require function of "jquery". Again, for illustrative purposes, you can also rename this to anything else.

"browser": {
  "thingy": "./src/js/vendor/jquery.js", // Path to the local JS file relative to package.json or an external shim JS file
},
"browserify-shim": {
  "thingy": "$"
},

可能需要:

var whatever = require('thingy');

我建议您查看 browserify-shim 文档以获取有关使用 exports 属性以及 depends 属性的长手语法的更多信息,它允许您告诉 browserify-shim 一个库是否依赖于另一个库/模块.我在这里解释的内容适用于两者.我希望这可以帮助其他努力了解 browserify-shim 实际在做什么以及如何使用它的人.

I'd recommend checking out the browserify-shim docs for more info on the long-hand syntax using the exports property and also the depends property which allows you to tell browserify-shim if a lib depends on another lib/module. What I've explained here applies to both. I hope this helps others struggling to understand what browserify-shim is actually doing and how to use it.

匿名填充是 browserify-shim 的替代方法,它允许您使用 browserify 的 --standalone 选项将 jQuery 等库转换为 UMD 模块.

Anonymous shimming is an alternative to browserify-shim which lets you transform libs like jQuery into UMD modules using browserify's --standalone option.

$ browserify ./src/js/vendor/jquery.js -s thingy > ../dist/jquery-UMD.js

如果你把它放到一个脚本标签中,这个模块会将 jQuery 添加到 window 对象中作为 thingy.当然也可以是 $ 或者任何你喜欢的.

If you dropped that into a script tag, this module would add jQuery onto the window object as thingy. Of course it could also be $ or whatever you like.

但是,如果它require被添加到浏览器的应用程序包中,var $ = require("./dist/jquery-UMD.js");,您将在应用程序中使用 jQuery,而无需将其添加到 window 对象中.

If however, it's requireed into your browserify'd app bundle, var $ = require("./dist/jquery-UMD.js");, you will have jQuery available inside the app without adding it to the window object.

此方法不需要 browserify-shim 并利用 jQuery 的 CommonJS 意识,它查找 module 对象并将 noGlobal 标志传递给它的工厂,告诉它不将自身附加到窗口对象.

This method doesn't require browserify-shim and exploits jQuery's CommonJS awareness where it looks for a module object and passes a noGlobal flag into its factory which tells it not to attach itself to the window object.

这篇关于使用 Browserify-shim 配置通用 jQuery 插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆