我使用Dojo Build工具成功构建了我的项目。但是,我有一个模块squad_builder/Pilot
,只要我包含它就会导致构建失败,从而产生以下错误:
error(356) The optimizer threw an exception; the module probably contains syntax errors. module identifier: /Users/ferg/Dropbox/webdev/x-wing_squadron_builder/www/js/dist/squad_builder/run_deps.js; exception: (compile time:1.247s). OPTIMIZER FAILED: InternalError: missing name after . operator
该模块在开发中运行良好,甚至可以通过JS Lint运行,其中没有明显的错误,特别是与错位的"无关。"我可以在任何地方看到。
这是模块的代码:
define( [ 'dojo/_base/declare',
// parents
'dijit/TitlePane',
// used modules
'dojo/_base/lang',
'dojo/_base/array',
'dojo/dom-construct',
'dojo/dom-style',
'dojo/_base/fx',
'dojo/_base/event',
'squad_builder/actionIconParser',
'dojo/promise/all',
'dojo/Deferred',
// dijits
'dijit/form/Button',
// stores
// @todo only load rebels or empire store
'squad_builder/storeBroker!rebelsStore',
'squad_builder/storeBroker!empireStore',
'squad_builder/storeBroker!actionsStore',
'squad_builder/storeBroker!upgradeTypesStore',
'squad_builder/storeBroker!setsStore',
'squad_builder/storeBroker!shipTypesStore',
// template
'dojo/text!./Pilot/templates/Pilot.html' // extended TitlePane template
],
function( declare,
TitlePane,
lang, array, domConstruct, domStyle, fx, event, actionIconParser, all, Deferred,
Button,
rebelsStore, empireStore, actionsStore, upgradeTypesStore, setsStore, shipTypesStore,
template )
{
return declare( [ TitlePane ],
{
// provided to constructor
faction: null,
pilotId: null,
squadList: null,
squadPaneId: null, // used for duplicating
basePoints: null, // initial points
points: null, // total points of pilot + upgrades
_loaded: false, // flag to prevent multiple startup() calles
allUpgradesLoaded: false,
templateString: template,
// A class to be applied to the root node in our template
baseClass: 'pilotWidget dijitTitlePane',
// used in auto-generated IDs
declaredClass: 'squad_builder.PilotWidget',
constructor: function()
{
// declared in constructor so all instances have their own copy
this.pilotData = {};
this.originalPilotData = {}; // used when removing upgrades so we cannot remove boost from A-Wings for example
this.initiallySelectedUpgrades = [];
this.upgradeButtons = [];
// reference to squad-level caches
this.uniqueUpgradeCache = {};
this.collection = null;
},
// fetch the pilot data before loading template
postMixInProperties: function()
{
this.inherited( arguments );
// use pilot id to load the rest of the pilot data
var store = this.faction == 'rebels' ? rebelsStore : empireStore,
data = store.get( this.pilotId ); // pilot data
// save pilot data
lang.mixin( this.pilotData, lang.clone( data ) ); // bugfix: needs clone or all copies of this ship will be modified by pilot modules
this.originalPilotData = lang.clone( this.pilotData );
// set initial points
this.basePoints = parseInt( this.pilotData.cost ); // base points = pilot cost
this.points = parseInt( this.pilotData.cost ); // may increase with upgrades
},
postCreate: function()
{
// Run any parent postCreate processes - can be done at any point
this.inherited( arguments );
// wait until we have child widgets containing upgrades before figuring out points
this._calculatePoints();
// info
this.infoDiv.innerHTML = shipTypesStore.get( this.pilotData.ship_type_id )['name'];
if( this.pilotData.unique )
{
this.infoDiv.innerHTML += ', Unique';
}
if( !this.pilotData.released )
{
this.infoDiv.innerHTML += ', Unreleased';
}
// switch between energy and primary stats
if( !this.pilotData.energy )
{
domStyle.set( this.energyNode, { display: 'none' } );
}
if( !this.pilotData.primary )
{
domStyle.set( this.primaryNode, { display: 'none' } );
}
// ability
if( this.pilotData.ability )
{
this.abilityDiv.innerHTML = actionIconParser( this.pilotData.ability );
}
// add icons for actions
this._initActions();
// sets
array.forEach( this.pilotData.sets, function( set )
{
var setData = setsStore.get( set );
domConstruct.create( 'div',
{
innerHTML: setData.acronym,
title: setData.name
},
this.setsContainer );
}, this );
// clear message if any upgrades
if( this.pilotData.upgrades.length )
{
this.upgradesDiv.innerHTML = '';
}
},
/*
* Upgrades added here or watch() doesn't fire!
*/
startup: function()
{
if( this._loaded == false ) // only call this once when first adding pilot, not again when sorting
{
// track all upgrades
var allUpgradesLoadedPromises = [];
// upgrade buttons
array.forEach( this.pilotData.upgrades, function( upgradeTypeId, index )
{
var deferred = this._addUpgradeButton( upgradeTypeId, this.initiallySelectedUpgrades[ index ], index, false );
allUpgradesLoadedPromises.push( deferred.promise );
},
this );
// do we have extra upgrades (eg. added by another upgrade)?
var extraUpgrades = array.filter( this.initiallySelectedUpgrades, function( selectedUpgrade )
{
return selectedUpgrade instanceof Array;
} );
if( extraUpgrades.length > 0 )
{
array.forEach( extraUpgrades, function( extraUpgrade, index )
{
var deferred = this._addUpgradeButton( extraUpgrade[1], extraUpgrade[0], this.pilotData.upgrades.length + index, true );
allUpgradesLoadedPromises.push( deferred.promise );
},
this );
}
// track when all promises fulfilled
// other objects (eg. modules) can use watch('allUpgradesLoaded') to hook into this
all( allUpgradesLoadedPromises ).then( lang.hitch( this, function()
{
this.set( 'allUpgradesLoaded', true );
} ) ).otherwise( function()
{
console.warn( 'Failed to track whether upgrades loaded', arguments );
} );
// highlight
domStyle.set( this.containerNode, { backgroundColor: '#FFF8B5' } );
fx.animateProperty(
{
node: this.containerNode,
properties: {
backgroundColor: '#FFFFFF'
},
duration: 500,
delay: 1000
} ).play();
this._loaded = true;
}
},
_initActions: function()
{
// show action icons
// in function so we can fade out old icons first...
var show = lang.hitch( this, function()
{
domStyle.set( this.actionsDiv, 'opacity', 0 );
array.forEach( this.pilotData.actions, function( action )
{
var actionData = actionsStore.get( action );
domConstruct.create( 'div',
{
className: 'icon_action ' + actionData.class_name,
title: actionData.name
},
this.actionsDiv );
},
this );
fx.fadeIn(
{
node: this.actionsDiv
} ).play();
} );
// already got icons?
if( this.actionsDiv !== undefined && this.actionsDiv.innerHTML != '' )
{
fx.fadeOut(
{
node: this.actionsDiv,
onEnd: lang.hitch( this, function()
{
this.actionsDiv.innerHTML = '';
show();
} )
} ).play();
}
else
{
show();
}
},
_addUpgradeButton: function( upgradeTypeId, selectedId, position, isExtra )
{
var upgradeTypeData = upgradeTypesStore.get( upgradeTypeId ), // type of upgrade tells us what upgrade store to use
upgradeButtonDeferred = new Deferred();
// get specific upgrade data for this button
require( [ 'squad_builder/PilotUpgradeButton', 'squad_builder/storeBroker!' + upgradeTypeData.store ],
lang.hitch( this, function( PilotUpgradeButton, upgradeStore )
{
// create button
var upgradeButton = new PilotUpgradeButton(
{
position: position,
isExtra: Boolean( isExtra ),
pilot: this,
upgradeTypeId: upgradeTypeId,
name: upgradeTypeData.name,
upgradeClass: upgradeTypeData.class,
upgradeStore: upgradeStore,
selectedId: selectedId,
// reference to squadlist-level cache
// used to check if unique upgrades used
uniqueUpgradeCache: this.uniqueUpgradeCache,
// reference to squadpane-level collection store
// used to record component use
collection: this.collection
} );
// watch points changes
upgradeButton.watch( 'points', lang.hitch( this, function()
{
this._calculatePoints();
} ) );
// store reference
this.upgradeButtons.push( upgradeButton );
// place
upgradeButton.placeAt( this.upgradesDiv );
upgradeButton.startup(); // add upgrades after watch() added
upgradeButtonDeferred.resolve( upgradeButton );
} ) );
return upgradeButtonDeferred; // allows pilot._addUpgradeButton( ... ).then( ... )
},
_calculatePoints: function()
{
var points = this.get('basePoints');
// get points from upgrade buttons
array.forEach( this.upgradeButtons, function( upgradeButton )
{
points += upgradeButton.get( 'points' );
} );
this.set( 'points', points );
},
_calculateTitle: function()
{
var title = this.pilotData.name;
array.forEach( this.upgradeButtons, function( upgradeButton )
{
var upgradeName = upgradeButton.get( 'selectedName' );
if( upgradeName )
{
title += ' + ' + upgradeName;
}
} );
title += ' (' + this.get( 'points' ) + ')';
this.set( 'title', title );
},
// for dojo/Stateful watch/get/set
_setPointsAttr: function( value )
{
this._set( 'points', value );
this._calculateTitle();
},
close: function()
{
this.set( 'open', false );
},
_onDelete: function( e )
{
event.stop( e );
this.onDelete();
this.destroyRecursive();
},
/**
* Extension point
*/
onDelete: function()
{
},
_onDuplicate: function( e )
{
event.stop( e );
this.onDuplicate();
this.squadList.addPilot( this.get( 'squadPaneId' ), this.get('faction'), this.get('pilotId'), this.get('upgrades') );
},
/**
* Extension point
*/
onDuplicate: function()
{
},
_onMoveUp: function( e )
{
event.stop( e );
this.onMoveUp();
this.squadList.movePilot( this.get( 'id' ), -1 );
},
/**
* Extension point
*/
onMoveUp: function()
{
},
_onMoveDown: function( e )
{
event.stop( e );
this.onMoveDown();
this.squadList.movePilot( this.get( 'id' ), 1 );
},
/**
* Extension point
*/
onMoveDown: function()
{
},
/**
* Data to save/recreate this pilot
*/
getData: function()
{
return {
id: this.get('pilotId'),
points: this.get('points'),
basePoints: this.get('basePoints'),
upgrades: this.get('upgrades')
};
},
/**
* allows: this.get('upgrades')
*/
_getUpgradesAttr: function()
{
// get upgrades from buttons
var upgrades = [];
// upgradeButton widgets may not be instantiated when this.get('upgrades') first called
// if so default to...
if( this.upgradeButtons.length == 0 )
{
// ... initially selected upgrades
if( this.initiallySelectedUpgrades.length !== undefined && this.initiallySelectedUpgrades.length > 0 )
{
upgrades = this.initiallySelectedUpgrades;
}
// ... or create array of nulls
else
{
var numUpgrades = this.pilotData.upgrades.length,
i = 0;
while( i++ < numUpgrades )
{
upgrades.push( null );
}
}
}
else
{
array.forEach( this.upgradeButtons, function( upgradeButton )
{
// use position from instantiation to ensure we get them in the right order
upgrades[ upgradeButton.get( 'position' ) ] = upgradeButton.get( 'selectedId' ); // id or null or tuple pair
} );
}
return upgrades;
},
_getNameAttr: function()
{
return this.pilotData.name;
},
_getPilotAttr: function()
{
return this.pilotData.pilot;
},
_setPilotAttr: function( value )
{
this.pilotData.pilot = value;
// animate change
fx.fadeOut(
{
node: this.pilotNode,
onEnd: lang.hitch( this, function()
{
this.pilotNode.innerHTML = value;
fx.fadeIn(
{
node: this.pilotNode
} ).play();
} )
} ).play();
},
_getShieldsAttr: function()
{
return this.pilotData.shields;
},
_setShieldsAttr: function( value )
{
this.pilotData.shields = value;
// animate change
var shieldsNode = this.shieldsNode; // was losing scope so use local var
fx.fadeOut(
{
node: shieldsNode,
onEnd: function()
{
shieldsNode.innerHTML = value;
fx.fadeIn(
{
node: shieldsNode
} ).play();
}
} ).play();
},
_getAgilityAttr: function()
{
return this.pilotData.agility;
},
_setAgilityAttr: function( value )
{
this.pilotData.agility = value;
// animate change
fx.fadeOut(
{
node: this.agilityNode,
onEnd: lang.hitch( this, function()
{
this.agilityNode.innerHTML = value;
fx.fadeIn(
{
node: this.agilityNode
} ).play();
} )
} ).play();
},
_getHullAttr: function()
{
return this.pilotData.hull;
},
_setHullAttr: function( value )
{
this.pilotData.hull = value;
// animate change
fx.fadeOut(
{
node: this.hullNode,
onEnd: lang.hitch( this, function()
{
this.hullNode.innerHTML = value;
fx.fadeIn(
{
node: this.hullNode
} ).play();
} )
} ).play();
},
_getEnergyAttr: function()
{
return this.pilotData.energy;
},
_setEnergyAttr: function( value )
{
this.pilotData.energy = value;
// animate change
fx.fadeOut(
{
node: this.energyNode,
onEnd: lang.hitch( this, function()
{
this.energyNode.innerHTML = value;
fx.fadeIn(
{
node: this.energyNode
} ).play();
} )
} ).play();
}
} );
}
);
我已经遍及代码,但我找不到任何与我收到的错误消息相符的内容。有什么想法吗?
答案 0 :(得分:3)
我遇到了这个错误,因为我使用JavaScript关键字作为对象属性。 EG:
object.return.value而不是object [&#39; return&#39;]。value
答案 1 :(得分:1)
你可能正在使用保留字作为变量,正如Julian Doucette建议的那样。最有可能的是你使用变量“set”。把它重命名为别的,比如“setItem”?
array.forEach(this.pilotData.sets, function(setItem)
{
var setData = setsStore.get(setItem);
domConstruct.create('div',
{
innerHTML: setData.acronym,
title: setData.name
},
this.setsContainer);
}, this);
我还要重命名“event”,这也是一个保留字。
答案 2 :(得分:0)
我切换到闭包编译器以揭示类似错误的原因。添加:
layerOptimize: "closure",
到个人资料。然后它给了我这个很好的错误信息(在“浮动”下面有一个^)
dojo.js.uncompressed.js:2991: ERROR - Parse error. invalid property id
domStyle.set(configTags[c], { float: "right", clear: "both" });
而不是与你的非常相似的无益收缩版本。节拍四处寻找我最近在git中改变的内容。
不幸的是,对于此错误消息,退出代码为零以进行关闭或收缩!