Skip to content

Instantly share code, notes, and snippets.

@nekman
Last active September 29, 2018 11:59
Show Gist options
  • Save nekman/83bbffc477c9cc0da93ad5f02894d010 to your computer and use it in GitHub Desktop.
Save nekman/83bbffc477c9cc0da93ad5f02894d010 to your computer and use it in GitHub Desktop.
Node.js with esm and app-module-path (using mocha as test runner)

Node.js with esm and app-module-path

This is a short post on how to use ESM with app-module-path in a Node.js (6+) project.

Q: Why?

Lots of benifits, easier to export/import modules.

Instead of:

const foo = require('app/foo');

module.exports = { foo, bar: 2 };

We can now use:

import foo from 'app/foo';

export default { foo, bar: 2 };

And we don't need to do:

exports = module.exports = Foo;

exports.bar = 'bar';

We can just:

export default Foo;

export const bar = 'bar';

Q: Why not just update to Node 9+ ?

A1: Not possible to run anything higher than Node 8.2 on AWS Lambda.
A2: Perhaps don't wan't/can't start Node process with flag --experimental-modules

Install esm and setup with app-module-path

# install esm
npm i esm -S

Add a new entry point (entry.js):

// Entry point for our application.

// Setup esm
require = require('esm')(module);
// Setup app-module-path
require('app-module-path/register');

module.exports = require('./old-entry-point');

Migration

The app with require calls and module.exports will continue to work, but here is a shortcut for how to convert to import and export. Of course, manual work is also going to be needed.

Replace require with import

(VS Code is used as editor, don't know how to search/replace in other editors)

In VS Code RegExp Search Replace:

Search: const\s+(\w+)\s+=\s+require\('([^']+)'\);?
Replace: import $1 from '$2';

Replace module.exports with export default

Search: module.exports =
Replace: export default

Replace exports.<variable> = with export <variable>

Search: exports.(\w+)\s+=\s+([^']+)?
Replace: export $1 $2

Manually replace destructing require

-const { sleep } = require('src/utils/promise-utils');
+import { sleep } from 'src/utils/promise-utils';

-const { expect } = require('chai');
+import { expect } from 'chai';

Mocha

To be able to setup esm with mocha, it was not enough to just --require esm in mocha.opts or try to initialize esm in the test/bootstrap.js file.

Had to change the test script in package.json from:

-"test": "_mocha --recursive",
+"test": "node -r esm node_modules/.bin/_mocha --recursive",

to make it work.

Links

https://medium.com/web-on-the-edge/es-modules-in-node-today-32cff914e4b - ESM release post
https://nodejs.org/api/esm.html#esm_enabling
https://github.com/standard-things/esm
https://github.com/patrick-steele-idem/app-module-path-node

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment