Мы столкнулись с проблемой минификации, предоставляемой пакетом NuGet Microsoft.AspNet.Web.Optimization
, поскольку, похоже, у него есть проблемы с let
. Каким-то образом минификатор устанавливает для переменных bookingDefaultIndex
и i
одно и то же имя (i
). Это заставляет Firefox и IE 11 сообщать о проблеме с областью действия (Firefox сообщает о SyntaxError: redeclaration of let i
, IE 11 сообщает о Let/Const redeclaration
), поскольку переменная уже была определена. Без минификации код отлично работает в IE и FF. Chrome не сообщает о проблемах с минимизированным кодом.
В следующих фрагментах кода я пометил соответствующие строки комментарием, который начинается с // [SO-COMMENT]
, поэтому вы можете найти его, чтобы увидеть проблемные строки.
Это унифицированная функция, которая вызывает проблемы:
_handleDDLValuesByContext: function () {
if (this.options.isCreate) {
if (this.options.isChildCreation) {
//If we are creating a child ->
this.$ddlBookingType.val(this.options.data.BookingTypeID);
this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID);
this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID);
if (this.options.data.ServiceCategoryID == null) {
this.$ddlServiceCategory.val('-1').trigger('change');
if (this.options.data.PricePerUnit != null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
}
} else {
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger('change');
}
//If we are creating a child, prefill his accounting type with the parent accounting type
if (this.options.data.AccountingTypeID == null) {
this.$ddlAccountingType.val('-1').trigger('change');
} else {
this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger('change');
}
} else {
//If it's parent creation ->
let bookingTypes = this.options.structureSpecificData.BookingTypes;
let bookingDefaultID = null;
// [SO-COMMENT] the following variable is minified to 'i'
let bookingDefaultIndex = null;
for (let i = 0, len = bookingTypes.length; i < len; i++) {
if (bookingTypes[i].IsDefault) {
bookingDefaultID = bookingTypes[i].ID;
bookingDefaultIndex = i;
}
}
let allocationTypes = this.options.structureSpecificData.AllocationUnitTypes;
if (bookingDefaultID == null) {
//In case there's no default booking type id, we set the booking types, allocations and effort allocations to their first available value
this.$ddlBookingType.val(bookingTypes[0].ID);
this.$ddlAllocationUnit.val(allocationTypes[0].ID);
this.$ddlEffortAllocationUnit.val(allocationTypes[0].ID);
} else {
let allocationDefaultID = null;
this.$ddlBookingType.val(bookingDefaultID).trigger('change');
allocationTypes = [];
let bookings = this.options.structureSpecificData.BookingTypes;
let allocations = this.options.structureSpecificData.AllocationUnitTypes;
// [SO-COMMENT] this is the 'original' i
for (let i = 0, len = allocations.length; i < len; i++) {
if (allocations[i].BaseUnitID == bookings[bookingDefaultIndex].BaseUnitID) {
allocationTypes.push(allocations[i]);
}
}
for (let i = 0, len = allocationTypes.length; i < len; i++) {
if (allocationTypes[i].IsDefault) {
allocationDefaultID = allocationTypes[i].ID;
}
}
if (allocationDefaultID == null) {
this.$ddlAllocationUnit.val(allocationTypes[0].ID);
this.$ddlEffortAllocationUnit.val(allocationTypes[0].ID);
} else {
this.$ddlAllocationUnit.val(allocationDefaultID);
this.$ddlEffortAllocationUnit.val(allocationDefaultID);
}
}
this.$ddlServiceCategory.val('-1');
}
} else {
//If we are edditing ->
this.$ddlBookingType.val(this.options.data.BookingTypeID);
this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID);
this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID);
if (this.options.data.IsParentElement) {
this.$ddlServiceCategory.val('-1').trigger('change');
//We have to check against a NaN type since the effort and the total cost can be of that type
//in case we have a structure hierarchy with an accounting type of fixed price and therefore no effort and cost
if (isNaN(this.options.structureTotalCost)) {
this.$structureTotalCost.val('');
} else {
this.$structureTotalCost.val(GetFormat(this.options.structureTotalCost));
}
if (isNaN(this.options.structureEffort)) {
this.$structureEffortUnits.val('');
} else {
this.$structureEffortUnits.val(GetFormat(this.options.structureEffort));
}
} else {
if (this.options.data.ServiceCategoryID == null) {
this.$ddlServiceCategory.val('-1').trigger('change');
if (this.options.data.PricePerUnit != null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
this._checkTotalCostCalculation();
}
} else {
if (this.options.data.PricePerUnit !== null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID);
this._checkTotalCostCalculation();
} else {
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger('change');
}
}
}
//Since we are editing we should prefill the accounting type with the accounting id and the fixed price too if it exists
//And not trigger anything
if (this.options.data.AccountingTypeID == null) {
this.$ddlAccountingType.val('-1').trigger('change');
} else {
this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger('change');
}
if (isNaN(this.options.totalFixedPrice)) {
this.$fixedPrice.val('');
} else {
this.$fixedPrice.val(GetFormat(this.options.totalFixedPrice));
}
}
}
А это уменьшенная версия:
_handleDDLValuesByContext: function() {
if (this.options.isCreate)
if (this.options.isChildCreation) this.$ddlBookingType.val(this.options.data.BookingTypeID), this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID), this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID), this.options.data.ServiceCategoryID == null ? (this.$ddlServiceCategory.val("-1").trigger("change"), this.options.data.PricePerUnit != null && this.$structureRate.val(GetFormat(this.options.data.PricePerUnit))) : this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger("change"), this.options.data.AccountingTypeID == null ? this.$ddlAccountingType.val("-1").trigger("change") : this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger("change");
else {
let t = this.options.structureSpecificData.BookingTypes,
i = null, // [SO-COMMENT] this shouldn't be named i
r = null;
for (let n = 0, u = t.length; n < u; n++) t[n].IsDefault && (i = t[n].ID, r = n);
let n = this.options.structureSpecificData.AllocationUnitTypes;
if (i == null) this.$ddlBookingType.val(t[0].ID), this.$ddlAllocationUnit.val(n[0].ID), this.$ddlEffortAllocationUnit.val(n[0].ID);
else {
let t = null;
this.$ddlBookingType.val(i).trigger("change");
n = [];
let f = this.options.structureSpecificData.BookingTypes,
u = this.options.structureSpecificData.AllocationUnitTypes;
for (let t = 0, i = u.length; t < i; t++) u[t].BaseUnitID == f[r].BaseUnitID && n.push(u[t]);
// [SO-COMMENT] here there is a second i that causes the problem
for (let i = 0, r = n.length; i < r; i++) n[i].IsDefault && (t = n[i].ID);
t == null ? (this.$ddlAllocationUnit.val(n[0].ID), this.$ddlEffortAllocationUnit.val(n[0].ID)) : (this.$ddlAllocationUnit.val(t), this.$ddlEffortAllocationUnit.val(t))
}
this.$ddlServiceCategory.val("-1")
} else this.$ddlBookingType.val(this.options.data.BookingTypeID), this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID), this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID), this.options.data.IsParentElement ? (this.$ddlServiceCategory.val("-1").trigger("change"), isNaN(this.options.structureTotalCost) ? this.$structureTotalCost.val("") : this.$structureTotalCost.val(GetFormat(this.options.structureTotalCost)), isNaN(this.options.structureEffort) ? this.$structureEffortUnits.val("") : this.$structureEffortUnits.val(GetFormat(this.options.structureEffort))) : this.options.data.ServiceCategoryID == null ? (this.$ddlServiceCategory.val("-1").trigger("change"), this.options.data.PricePerUnit != null && (this.$structureRate.val(GetFormat(this.options.data.PricePerUnit)), this._checkTotalCostCalculation())) : this.options.data.PricePerUnit !== null ? (this.$structureRate.val(GetFormat(this.options.data.PricePerUnit)), this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID), this._checkTotalCostCalculation()) : this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger("change"), this.options.data.AccountingTypeID == null ? this.$ddlAccountingType.val("-1").trigger("change") : this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger("change"), isNaN(this.options.totalFixedPrice) ? this.$fixedPrice.val("") : this.$fixedPrice.val(GetFormat(this.options.totalFixedPrice))
}
Мои поиски в Google проблем с областью минификации IIS не дали никаких полезных результатов. Что мы могли бы попытаться исследовать и исправить эту проблему, кроме как не использовать let
?
Вы правы, это делает не IIS, а пакет NuGet Microsoft.AspNet.Web.Optimization
. Я исправил это в своем вопросе. Кажется, нет ничего особенного в том, как мы настраиваем бандлинг, и он работает для остальной части приложения, за исключением данного примера.
Я не думаю, что сам IIS выполняет минификацию. Я видел, как минификация выполняется с помощью модулей, установленных в IIS, или выполняется через само приложение (или как часть процесса развертывания / системы CI). Установлены ли у вас какие-либо пользовательские модули в IIS или библиотеки в самом приложении, которые могут быть основной причиной? Конфиг внутри
<appsettings />
подразумевает его часть вашего приложения?