21

Let's start with an example:

import renewCreepLife from '../tasks/renew_creep_life';
import harvestEnergy from '../tasks/harvest_energy';
import pickupEnergy from '../tasks/pickup_energy';
import storeEnergy from '../tasks/store_energy';
import upgradeController from '../tasks/upgrade_controller';

const taskFuncs = {
    [Tasks.RENEW]: renewCreepLife,
    [Tasks.PICKUP_ENERGY]: pickupEnergy,
    [Tasks.HARVESTING]: harvestEnergy,
    [Tasks.STORING]: storeEnergy,
    [Tasks.UPGRADING]: upgradeController,
};

Is there any way to simplify this so that I'm not creating these pointless temporary variable names? Something like:

// incorrect but desired syntax
const taskFuncs = {
    [Tasks.RENEW]: import '../tasks/renew_creep_life',
};

N.B. each of those files is using export default function()

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • 2
    Not ES6, but since you're probably using something like webpack or browserify, you can use `require`, which gives you the ability to do just that. – Ori Drori Apr 19 '16 at 05:12
  • possible duplicate of [How to import into properties using ES6 module syntax (destructing)?](http://stackoverflow.com/q/32124640/1048572) – Bergi May 02 '16 at 08:37

1 Answers1

11

No. The import statement does not have a return value, so it can never be used to assign directly to a variable like that.

Additionally, import and export must be declared at the top level.

This is not possible with ES6 and likely will stay that way for the foreseeable future (ES2016+).

However, there is a HTML Module Loader spec being worked on which will allow you to load modules like:

System.import('../tasks/renew_creep_life')
.then(renewCreepLife => {

});

But since it's promise-based, you'll still not be able to just write it inline in an object like that.

If you want synchronous loading, NodeJS' require is probably the closest you'll get. There are browser implementations such as Webpack/Browserify/etc. which attempt to mimic the behaviour:

const taskFuncs = {
    [Tasks.RENEW]: require('../tasks/renew_creep_life').default
};
CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • 1
    Btw, in my opinion your original solution is explicit, clear, concise and more importantly statically analyzable. I personally would keep what you have. – CodingIntrigue Apr 19 '16 at 07:33
  • 1
    It'd have to be `require('../tasks/renew_creep_life').default` then, no? – mpen Apr 19 '16 at 14:59
  • 1
    @mpen In true CommonJS yes, you're right (some browser implementations aren't 100% compliant - Babel 5 for example) - I'll update – CodingIntrigue Apr 19 '16 at 15:23