使用 RequireJS 优化器 r.js 缩小后,Jquery 对象转换为普通变量

Posted

技术标签:

【中文标题】使用 RequireJS 优化器 r.js 缩小后,Jquery 对象转换为普通变量【英文标题】:Jquery object converted to normal variable after minifying with RequireJS optimizer r.js 【发布时间】:2015-04-18 09:57:44 【问题描述】:

我在 CoffeeScript 中有这个功能

render: -> 
_.each @$elements, ($el) =>
  if $el[0].id is 'tabs-div'
    emptySlate = "<div class='js-empty-slate' style='padding:40px;'><h3>no data available</h3><div>"
    @setEmptyPlacholde($el, emptySlate)
    return 

  @setEmptyPlacholde($el)


setEmptyPlacholde: ($el, emptySlate)->
emptySlatehtml = emptySlate or "<h3 class='js-empty-slate'>no data available</h3>"
if $el.hasClass('mobile-os-con') or 
   $el.hasClass('time-of-visit-con') or 
   $el.hasClass('gender-visit-con') or 
   $el.hasClass('time-redemption-sales-con') or 
   $el.hasClass('gender-redemption-con')

  $el.children().hide()
else
  $el.empty()
$el.append emptySlateHTML 

$elements 是一个 jQuery 变量,它使用这样的数组:

$elements: [
$("#tabs-div")
$("#visits-male")
$("#visits-female")
$("#days-of-visits")
$(".time-of-visit-con")
]

当我使用使用 Uglify 的 RequireJS 优化器 r.js 时,生成的缩小代码.. 看起来像这样:

render:function()var e=this;return _.each(this.$elements,function(t)var n;if(t[0].id==="tabs-div")n="<div class='js-empty-slate' style='padding:40px;'><h3>no data available</h3><div>",e.setEmptyPlacholde(t,n);returnreturn e.setEmptyPlacholde(t))

在之前的缩小代码中,$el 变成了t .. 所以这拒绝在生产中将$el 作为 jQuery 元素执行。

这是问题所在,但我不知道为什么会这样。谁能解释一下为什么会发生这种情况,谢谢。

更新:缩小的代码不是问题,而是在数组中的节点正确加载之前执行的脚本,但是我在文档 ready 之后调用函数表示 DOM 必须完全加载。

提示:我将脚本标签放在 中,当代码没有被缩小时,这可以正常工作。

【问题讨论】:

这不是同一个代码。您的缩小代码引用selector 属性,而未缩小代码引用id。此外,未缩小的代码索引到元素中;缩小的代码没有。您确定您发布的示例正确吗? 对不起,你是对的。我正在分享另一个我正在玩的缩小代码。现在,我用正确的缩小代码更新了它。感谢您通知我。 缩小后的代码对我来说看起来不错,它与咖啡脚本代码完全相同。 $el 现在是 t 并不重要,它只是一个变量的本地名称,仅在 _.each 函数调用的范围内 是的,这不是缩小代码的问题。但是,在执行脚本之前,数组中的节点没有正确加载。所以t 没有按预期作为包含节点的 jquery 对象工作(这发生在缩小代码之后,但是我将脚本放在文档ready 事件之后执行) 【参考方案1】:

仅在纯粹的技术说明上,您可以通过以下方式改进代码 -

$elements: $("#tabs-div,#visits-male,#visits-female,#days-of-visits,.time-of-visit-con")

$elements.filter("#tabs-div")

至于变量重命名 - 变量名称对任何东西都没有任何区别,除非它用于公共 API - 因此代码压缩器/uglifier 会将变量名称更改为尽可能短,换句话说,从单个字符开始,并且通常以随机顺序(尽管有些从 a、b、c 等开始)。默认情况下,uglifier 会理解 window 等是全局的并且不会重命名它。

除非您将所有内容都包装在一个闭包中,否则您应该从 $: window["jQuery"] 之类的内容开始,这样当变量重命名发生时您的本地 var $ 将是正确的,它将指向正确的东西。

如果将所有内容包装在一个闭包中(在所有内容周围包装一个函数可以立即调用它),那么您可以将 jQuery 作为参数传递 - 通常您还会传递更长的命名全局变量,这些变量也会像 window 和 @987654327 这样使用@。

通常,您将脚本包含在 HTML 的末尾,或将其包装在 $() 中,这相当于 document.ready 状态。

【讨论】:

【参考方案2】:

首先,您的&lt;div class='js-empty-slate' style='padding:40px;'&gt;&lt;h3&gt;no data available&lt;/h3&gt;&lt;div&gt;

就变量而言..这似乎是UgliyJS 的默认行为,它只是缩短了您在优化过程中提供的变量名称。它应该不会引起任何问题...但是,如果您想阻止它,请尝试在选项下将 uglify: no_mangle: true 添加到 r.js 优化器设置:

english: 
  ..your settings...
  options: 
   ...your other options...
    uglify: 
      no_mangle: true
    ,
  

对于 Uglify2,改用这个:

uglify2: 
  mangle: false

【讨论】:

@nouran-mahmoud 不确定您投了反对票还是其他人...您可以分享您的设置吗? 我没有否决您的答案,但我相信重点不在于不缩小函数或变量名称。我想知道为什么它在缩小时不能正常工作,但它应该可以工作。

以上是关于使用 RequireJS 优化器 r.js 缩小后,Jquery 对象转换为普通变量的主要内容,如果未能解决你的问题,请参考以下文章

reuire代码优化之:r.js

RequireJS和AMD规范

将 JSLint/Hint 与 requirejs 一起使用

使用r.js来打包模块化的javascript文件

require.js实现js模块化编程:RequireJS Optimizer

requirejs 使用实例r.js打包