ES2015Modules
devguides.io / ES2015

Modules

Use import as a substitute for require(). These two lines do the same thing in most cases.

var fs = require('fs')    ES5
import fs from 'fs'       ES2015

How can we import many things from a module? Next

Destructuring

You can also extract certain things from a module using destructuring.

var readFile = require('fs').readFile    ES5
import { readFile } from 'fs'            ES2015

You can also use the assign to new name destructuring syntax to extract things into new names.

var openFile = require('fs').openFile    ES5
import { open: openFile } from 'fs'      ES2015

Let's learn about hoisting. Next

Hoisting

If import appears on the top-level, but not at the top, they will be hoisted to the top.

console.log(util.inspect('hello'))
import util from 'util'
This will work as if the import was placed on top.

import can't be used inside a block (like a function), unlike require().

function openFile (file) { 
  import fs from 'fs'    return fs.readFileSync(file) } 

Error: 'import' and 'export' may only appear at the top level.

How can we export? Next

Exporting

Use export default as a substitute for assigning to module.exports.

function start () {   return 'Starting engines...' } 

module.exports = start  ES5
export default start    ES2015

You can also export inline function definitions. In fact, you can export any expression, not just functions!

export default function () {
  return 'hello'
}
export default {
  name: 'devguides',
  version: '1.0.0'
}

How can we export many things from one module? Next

Named exports

You can have as many named exports in a module.
Use export function to export functions.
Use export var to export variables.

export function start () {  return 'Vroom!' 
}
export var version = '1.0.0'

You can then import named exports by the destructuring syntax.

import { start, version } from './engine'

You can also assign different names:
import { start as engineStart } from './engine'

Try not to mix default exports and named exports! Let's find out why in the next section.

Can we mix this with export default? Next

Mixing exports

You can mix default exports with named exports, but there are caveats.

export default function () {
  
}

export function start () {
  
}

With a default export: Doing import X from will fetch the default export if it's available.

import Engine from './engine'      Yields [Function]
import { start } from './engine'

Without a default export: If there isn't a default export, it will return object with every named export.

import Engine from './engine'      Yields { start: [Function] }
Engine.start()

This is very different from require()! To emulate this behavior with require, you need to do this:

ES5 equivalent:
var Engine =
  require('./engine').default ||
  require('./engine')
Further reading...

Let's recap what we've learned. Next

Recap

import is the new require().

import fs from 'fs'var fs = require('fs') 
import { readFile } from 'fs'var readFile = require('fs').readFile 

export is the new module.exports. You can export default, function, or var.

export default startmodule.exports = start 
export function start () {  }
export var PI = 3.14159

exports.start = function () { ... } exports.PI = 3.14159 

When mixing export default with other exports, import will fetch the default export. This different from the require() behavior.

import Engine from './engine'      Gets export default
import { start } from './engine'   Gets export function

var Engine =   require('./engine').default ||   require('./engine') 

That's all for now! Back