System.Web.Optimization.JsMinify 产生无效 JavaScript
System.Web.Optimization.JsMinify produces invalid JavaScript
我在我认为是标准配置的情况下使用 System.Web.Optimization
v1.3,以在 MVC 5 Web 应用程序中捆绑和缩小 JavaScript 和 CSS 文件。在大多数情况下,这工作得很好,但我发现了 JavaScript 被缩小过程损坏的情况。
这是最初 AngularJS 输入验证指令的简化版本:
var myApp;
(function (myApp) {
myApp.module.directive("validator", [
function () {
return {
link: function (scope, element) {
var validators = [
{ signal: "required", message: "Please enter a value", value: null },
{ signal: "email", message: "Please enter a valid email address", value: null }
];
$("input", element).on("blur", function () {
for (var i in validators) {
var validator = validators[i];
if (scope.$parent.form[scope.modelName].$error[validator.signal]) {
element.removeClass("has-success");
scope.errorMessage = myApp.Utility.formatString(validator.message, eval(validator.value));
break;
}
}
});
}
};
}
]);
})(myApp || (myApp = {}));
虽然上面的代码不再做任何有用的事情(因为它已经被修剪),但它确实展示了缩小问题。缩小后,结果 JavaScript 如下:
var myApp;
function(n){
n.module.directive("validator",[
function(){
return{
link:function(t,i){
var r=[
{signal:"required",message:"Please enter a value",value:null},
{signal:"email",message:"Please enter a valid email address",value:null}
];
$("input",i).on("blur",function(){
var i,
validator;
for(i in r)
if(validator=r[i],t.$parent.form[t.modelName].$error[validator.signal]){
i.removeClass("has-success");
t.errorMessage=n.Utility.formatString(validator.message,eval(validator.value));
break
}
})
}
}
}
])
})(myApp||(myApp={}))
注意缩小化如何将参数名称 t
和 i
分配给 link
函数,尽管在原始文件中使用了循环变量 i
代码。
不用说,这破坏了代码。在这种情况下,我可以通过重命名我的循环变量来修复它,但我担心 JsMinify
的缩小可能会有其他我不知道的不利后果。
所以,我有 3 个与此问题相关的问题:
- 我认为这是一个缩小错误是否正确,如果是这样,是
有什么地方我应该报告吗?
- 是否有任何实用的方法可以在我的缩小代码中找到此问题的任何其他实例?
- 是否可以替换 JavaScript 使用的缩小引擎
System.Web.Optimization
并且,如果是这样,那将是一件好事
替代方案?
非常感谢您的想法。
蒂姆
更新:经过进一步调查,我发现实际上是 WebGrease
代表 System.Web.Optimization
执行缩小,而 this issue 似乎是我看到的那个.这似乎回答了我的第一个问题,但我仍然希望获得有关替代缩小器的建议。
过去,我成功地使用了 YUI Compressor for .Net (now moved to GitHub),它是来自 YUI Compressor Java 的 .NET 端口。它的伟大之处在于它基于 Mozilla 的 Rhino Java 脚本解释器,这意味着它实际上理解代码,而不仅仅是在其上运行正则表达式。因此,如果您有 Java 脚本语法错误,您的构建将失败。
我发现 Bundle Transformer (https://bundletransformer.codeplex.com/) 运行良好。它有许多 minifier 选项,例如 YUI、JSMin、Microsoft Ajax Minifier 等
Global.asax.cs中的示例代码:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var yuiMinifier = new BundleTransformer.Yui.Minifiers.YuiJsMinifier();
var customerTransformer = new BundleTransformer.Core.Transformers.ScriptTransformer(yuiMinifier);
var customBundle = new BundleTransformer.Core.Bundles.CustomScriptBundle("~/js/my-javascript.min.js");
customBundle.Include("~/js/script1.js");
customBundle.Include("~/js/script2.js");
customBundle.Transforms.Clear();
customBundle.Transforms.Add(customerTransformer);
BundleTable.Bundles.Add(customBundle);
}
}
注意:对我来说,只有在 web.config.
中将调试模式设置为 false 时才会出现缩小
我在我认为是标准配置的情况下使用 System.Web.Optimization
v1.3,以在 MVC 5 Web 应用程序中捆绑和缩小 JavaScript 和 CSS 文件。在大多数情况下,这工作得很好,但我发现了 JavaScript 被缩小过程损坏的情况。
这是最初 AngularJS 输入验证指令的简化版本:
var myApp;
(function (myApp) {
myApp.module.directive("validator", [
function () {
return {
link: function (scope, element) {
var validators = [
{ signal: "required", message: "Please enter a value", value: null },
{ signal: "email", message: "Please enter a valid email address", value: null }
];
$("input", element).on("blur", function () {
for (var i in validators) {
var validator = validators[i];
if (scope.$parent.form[scope.modelName].$error[validator.signal]) {
element.removeClass("has-success");
scope.errorMessage = myApp.Utility.formatString(validator.message, eval(validator.value));
break;
}
}
});
}
};
}
]);
})(myApp || (myApp = {}));
虽然上面的代码不再做任何有用的事情(因为它已经被修剪),但它确实展示了缩小问题。缩小后,结果 JavaScript 如下:
var myApp;
function(n){
n.module.directive("validator",[
function(){
return{
link:function(t,i){
var r=[
{signal:"required",message:"Please enter a value",value:null},
{signal:"email",message:"Please enter a valid email address",value:null}
];
$("input",i).on("blur",function(){
var i,
validator;
for(i in r)
if(validator=r[i],t.$parent.form[t.modelName].$error[validator.signal]){
i.removeClass("has-success");
t.errorMessage=n.Utility.formatString(validator.message,eval(validator.value));
break
}
})
}
}
}
])
})(myApp||(myApp={}))
注意缩小化如何将参数名称 t
和 i
分配给 link
函数,尽管在原始文件中使用了循环变量 i
代码。
不用说,这破坏了代码。在这种情况下,我可以通过重命名我的循环变量来修复它,但我担心 JsMinify
的缩小可能会有其他我不知道的不利后果。
所以,我有 3 个与此问题相关的问题:
- 我认为这是一个缩小错误是否正确,如果是这样,是 有什么地方我应该报告吗?
- 是否有任何实用的方法可以在我的缩小代码中找到此问题的任何其他实例?
- 是否可以替换 JavaScript 使用的缩小引擎
System.Web.Optimization
并且,如果是这样,那将是一件好事 替代方案?
非常感谢您的想法。 蒂姆
更新:经过进一步调查,我发现实际上是 WebGrease
代表 System.Web.Optimization
执行缩小,而 this issue 似乎是我看到的那个.这似乎回答了我的第一个问题,但我仍然希望获得有关替代缩小器的建议。
过去,我成功地使用了 YUI Compressor for .Net (now moved to GitHub),它是来自 YUI Compressor Java 的 .NET 端口。它的伟大之处在于它基于 Mozilla 的 Rhino Java 脚本解释器,这意味着它实际上理解代码,而不仅仅是在其上运行正则表达式。因此,如果您有 Java 脚本语法错误,您的构建将失败。
我发现 Bundle Transformer (https://bundletransformer.codeplex.com/) 运行良好。它有许多 minifier 选项,例如 YUI、JSMin、Microsoft Ajax Minifier 等
Global.asax.cs中的示例代码:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var yuiMinifier = new BundleTransformer.Yui.Minifiers.YuiJsMinifier();
var customerTransformer = new BundleTransformer.Core.Transformers.ScriptTransformer(yuiMinifier);
var customBundle = new BundleTransformer.Core.Bundles.CustomScriptBundle("~/js/my-javascript.min.js");
customBundle.Include("~/js/script1.js");
customBundle.Include("~/js/script2.js");
customBundle.Transforms.Clear();
customBundle.Transforms.Add(customerTransformer);
BundleTable.Bundles.Add(customBundle);
}
}
注意:对我来说,只有在 web.config.
中将调试模式设置为 false 时才会出现缩小