Dojo构建失败的一个模块:OPTIMIZER失败:内部错误:缺少名称后.操作符

Dojo Build Failing for One Module: OPTIMIZER FAILED: InternalError: missing name after . operator

本文关键字:失败 错误 内部 操作符 OPTIMIZER 模块 构建 一个 Dojo      更新时间:2023-09-26

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

我已经一遍又一遍地检查代码,但我就是找不到任何似乎与我得到的错误信息相匹配的东西。什么好主意吗?

我遇到了这个错误,因为我使用JavaScript关键字作为对象属性。如:

object.return。值而不是对象['return']。值

您可能使用保留字作为变量,正如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",这也是一个保留字

我切换到闭包编译器来揭示类似错误的原因。添加:

 layerOptimize: "closure",

到概要文件。然后它给了我这个很好的错误信息(在"float"下面有一个^)

dojo.js.uncompressed.js:2991: ERROR - Parse error. invalid property id
                                    domStyle.set(configTags[c], { float: "right", clear: "both" });

而不是无用的shrinksafe版本,它与你的版本非常相似。

不幸的是,对于这个错误消息,关闭或收缩安全的退出代码是零!