Dojo构建失败的一个模块:OPTIMIZER FAILED:InternalError:之后缺少名称。操作者

时间:2014-06-23 03:42:34

标签: javascript optimization dojo amd dojo-build

我使用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();
            }

        } );
    } 
);

我已经遍及代码,但我找不到任何与我收到的错误消息相符的内容。有什么想法吗?

3 个答案:

答案 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中改变的内容。

不幸的是,对于此错误消息,退出代码为零以进行关闭或收缩!