Gle*_*lle 41 javascript configuration browserify
我正在使用browserify-shim,我想使用通用的jQuery插件.我多次查看了Browserify-shim文档,我似乎无法理解发生了什么和/或它如何知道放置插件的位置,附加到jQuery对象等.这是我的package.json文件的样子:
"browser": {
"jquery": "./src/js/vendor/jquery.js",
"caret": "./src/js/vendor/jquery.caret.js"
},
"browserify-shim": {
"caret": {
"depends": ["jquery:$"]
}
}
Run Code Online (Sandbox Code Playgroud)
根据browserify-shim文档中给出的示例,我不想指定导出,因为这个插件(以及大多数(如果不是全部)jQuery插件)将自己附加到jQuery对象.除非我上面做错了,否则当我使用它时,我不明白为什么它不起作用(我得到一个错误告诉我函数是未定义的).见下文:
$('#contenteditable').caret(5); // Uncaught TypeError: undefined is not a function
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何使用browserify和browserify-shim配置通用jQuery插件(它将自身附加到jQuery对象)?
Gle*_*lle 98
在重新审视并尝试了更多的东西之后,我终于围绕着浏览器shim正在做什么以及如何使用它.对我来说,在我最终了解如何使用browserify-shim之前,我必须掌握一个关键原则.对于两种不同的用例,有两种方法可以使用browserify-shim:曝光和填充.
假设您想在标记中插入脚本标记(出于测试或性能原因,如缓存,CDN等).通过在标记中包含脚本标记,浏览器将点击脚本,运行它,并且很可能在窗口对象上附加属性(在JS中也称为全局).当然,这可以通过做myGlobal或来访问window.myGlobal.但是这两种语法都存在问题.它不遵循CommonJS规范,这意味着如果模块开始支持CommonJS语法(require()),则无法利用它.
Browserify-shim允许您通过CommonJS require()语法指定您想要"暴露"的全局.记住,你可以这样做var whatever = global;,var whatever = window.global;但你不能这样做,var whatever = require('global')并希望它能为你提供合适的lib /模块.不要混淆变量的名称.它可能是任意的.您实际上是将全局变量设为局部变量.这听起来很愚蠢,但它是浏览器中JS的悲惨状态.同样,希望是一旦lib支持CommonJS语法,它将永远不会通过窗口对象上的全局附加自身.这意味着你必须使用require()语法并将其分配给局部变量,然后在需要的地方使用它.
注意:我发现变量命名在browserify-shim docs/examples中略显混乱.请记住,关键是您要包含一个lib ,就好像它是一个正常运行的CommonJS模块一样.所以你最终要做的就是告诉browserify,当你需要myGlobal时,require('myGlobal')你实际上只是希望在窗口对象上获得全局属性window.myGlobal.
事实上,如果你对require函数实际上做了什么感到好奇,那就非常简单了.这是引擎盖下发生的事情:
var whatever = require('mygGlobal');
Run Code Online (Sandbox Code Playgroud)
成为...
var whatever = window.mygGlobal;
Run Code Online (Sandbox Code Playgroud)
所以在这个背景下,让我们看看我们如何在browserify-shim配置中公开一个模块/ lib.基本上,你告诉browserify-shim两件事.您希望它在调用时可以访问的名称require()以及它应该在窗口对象上找到的全局名称.所以这就是global:*语法的用武之地.让我们看一个例子.我想将jquery作为index.html中的脚本标记放入,以便我获得更好的性能.这是我在配置中需要做的事情(这将在package.json或外部配置JS文件中):
"browserify-shim": {
"jquery": "global:$"
}
Run Code Online (Sandbox Code Playgroud)
所以这就是这意味着什么.我在其他地方包含了jQuery(请记住,browserify-shim不知道我们在哪里放置我们的标签,但它不需要知道),但是我想要的是$当我需要时我在窗口对象上获得属性.带有字符串参数"jquery"的模块.进一步说明.我也可以这样做:
"browserify-shim": {
"thingy": "global:$"
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我必须将"thingy"作为参数传递给require函数,以便获取jQuery对象的实例(它只是从jQuery获取window.$):
var $ = require('thingy');
Run Code Online (Sandbox Code Playgroud)
是的,同样,变量名可以是任何东西.与实际的jQuery库使用$的全局属性相同没有什么特别之处$.尽管使用相同的名称以避免混淆是有意义的.这最终引用$窗口对象上的属性,由package.json global:$中browserify-shim对象中的值选择.
好的,所以几乎涵盖了暴露.browserify-shim的另一个主要功能是填充.那是什么?Shimming与暴露基本相同,除了在HTML标记中包含lib或模块与脚本标记之类的东西,你告诉browserify-shim在哪里抓取JS文件.没有必要使用global:*语法.让我们回顾一下我们的jQuery示例,但这一次假设我们不是从CDN加载jQuery,而只是将它与所有JS文件捆绑在一起.所以这是配置的样子:
"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": "$"
},
Run Code Online (Sandbox Code Playgroud)
这个配置告诉browserify-shim从指定的本地路径加载jQuery,然后从window对象中获取$属性,当需要带有字符串参数的jQuery到"jquery"的require函数时返回该属性.同样,为了便于说明,您还可以将其重命名为其他任何内容.
"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": "$"
},
Run Code Online (Sandbox Code Playgroud)
这可能需要:
var whatever = require('thingy');
Run Code Online (Sandbox Code Playgroud)
我建议查看browserify-shim文档,了解有关使用该exports属性的长手语法的更多信息,以及depends允许您告诉browserify-shim lib是否依赖于另一个lib /模块的属性.我在这里解释的内容适用于两者.我希望这有助于其他人努力了解browserify-shim实际上在做什么以及如何使用它.
匿名填充是browserify-shim的替代品,它允许您使用browserify --standalone选项将libs(如jQuery)转换为UMD模块.
$ browserify ./src/js/vendor/jquery.js -s thingy > ../dist/jquery-UMD.js
Run Code Online (Sandbox Code Playgroud)
如果将其放入脚本标记中,则此模块会将jQuery添加到窗口对象中thingy.当然它也可以是$或任何你喜欢的.
但是,如果它被require编入您的browserify的应用程序包中var $ = require("./dist/jquery-UMD.js");,您将在应用程序内部使用jQuery,而无需将其添加到窗口对象.
这种方法不需要browserify-shim,并利用jQuery的CommonJS意识,它会查找一个module对象,并将一个noGlobal标志传递给它的工厂,告诉它不要将自己附加到窗口对象上.
got*_*ike 13
对于每个人,谁在寻找一个具体的例子:
以下是将自身附加到/ 对象的jQuery插件的示例package.json和app.js文件,例如:.当我需要它时,我不想成为全局变量(),这就是jQuery设置的原因.但是,因为插件期望它可以附加到它自己的全局对象,所以你必须在文件名后面的依赖项中指定它:.此外,你需要在使用插件时实际导出全局,即使你不想这样做,因为插件不会起作用(至少这个特定的插件).jQuery$$('div').expose()jQuerywindow.jQuery'exports': nulljQuery./jquery-2.1.3.js:jQueryjQuery
的package.json
{
"name": "test",
"version": "0.1.0",
"description": "test",
"browserify-shim": {
"./jquery-2.1.3.js": { "exports": null },
"./jquery.expose.js": { "exports": "jQuery", "depends": [ "./jquery-2.1.3.js:jQuery" ] }
},
"browserify": {
"transform": [
"browserify-shim"
]
}
}
Run Code Online (Sandbox Code Playgroud)
app.js
// copy and delete any previously defined jQuery objects
if (window.jQuery) {
window.original_jQuery = window.jQuery;
delete window.jQuery;
if (typeof window.$.fn.jquery === 'string') {
window.original_$ = window.$;
delete window.$;
}
}
// exposes the jQuery global
require('./jquery.expose.js');
// copy it to another variable of my choosing and delete the global one
var my_jQuery = jQuery;
delete window.jQuery;
// re-setting the original jQuery object (if any)
if (window.original_jQuery) { window.jQuery = window.original_jQuery; delete window.original_jQuery; }
if (window.original_$) { window.$ = window.original_$; delete window.original_$; }
my_jQuery(document).ready(function() {
my_jQuery('button').click(function(){
my_jQuery(this).expose();
});
});
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我不希望我的代码设置任何全局变量,但我暂时不得不这样做,以使插件工作.如果你只需要jQuery,你可以这样做,不需要任何解决方法:var my_jQuery = require('./jquery-2.1.3.js').如果您将jQuery公开为全局,那么您可以修改上面的package.json示例,如下所示:
"browserify-shim": {
"./jquery-2.1.3.js": { "exports": "$" },
"./jquery.expose.js": { "exports": null, "depends": [ "./jquery-2.1.3.js" ] }
Run Code Online (Sandbox Code Playgroud)
希望能帮助一些正在寻找具体例子的人(就像我在找到这个问题时那样).
| 归档时间: |
|
| 查看次数: |
12970 次 |
| 最近记录: |