Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESM support #29

Merged
merged 10 commits into from
May 9, 2020
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ npm-debug.log*

#ignore node_modules, as the node project is not "deployed" per se: http://www.mikealrogers.com/posts/nodemodules-in-git.html
/node_modules

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
language: node_js
node_js:
- 6
- 8
- 10
- 12
- 13
- 14
before_install: npm i -g npm@6
script: npm run test:ci
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,75 @@ after the absolute path resolved to by `'./some/path'`.

Spiffy!

> Note: `defaultFakeCreator` is not supported for ES Module stubbing

## ES Modules support

Quibble supports ES Modules. Quibble implements ES module support using [ES Module
Loaders](https://nodejs.org/api/esm.html#esm_experimental_loaders) which are the official way to
"patch" Node.js' module loading mechanism for ESM.

> Note that Loader support is currently experimental and unstable. We will be doing our best
to track the changes in the specification for the upcoming Node.js versions. Also note that
Quibble ESM support is tested only for versions 13 and above.

To use Quibble support, you must run Node with the `quibble` package as the loader:

```sh
node --loader=quibble ...
```

Most test runners allow you to specify this in their command line, e.g. for Mocha:

```sh
mocha --loader=quibble ...
```

The `quibble` loader will enable the replacement of the ES modules with the stubs you specify, and
without it, the stubbing will be ignored.

### Restrictions on ESM

* `defaultFakeCreator` is not yet supported.

### `quibble` ESM API

The API is similar to the CommonJS API, but uses `quibble.esm` function, and is async:

```js
// a-module.mjs (ESM)
export const life = 42;
export default 'universe';

// uses-a-module.mjs
import universe, {life} from './a-module.mjs';

console.log(life, universe);

(async function () {
await quibble.esm('./a-module.mjs', {life: 41}, 'replacement universe');

await import('./uses-some-module.mjs');
// ==> logs: 41, replacement universe
})();
```

The parameters to `quibble` for ESM modules are:

1. the module path: similar to CommonJS, the path is relative to the directory you are in. It is
resolved the ESM way, so if you're using a relative path, you must specify the filename,
including the extension.

* `quibble.reset` works the same as for CommonJS modules

ESM support also exposes the function `quibble.esmImportWithPath` which both imports a module and
resolves the path to the module that is the package's entry point:

* `async quibble.esmImportWithPath(importPath)`: imports a module, just like `import(importPath)`,
but returns an object with two properties:
* `module`: the module returned by `await import(importPath)`.
* `modulePath`: the full path to the module (file) that is the entry point to the package/module.

## How's it different?

A few things that stand out about quibble:
Expand Down
1 change: 1 addition & 0 deletions example-esm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules
1 change: 1 addition & 0 deletions example-esm/lib/animals/bear.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function () { return 'a real bear' }
1 change: 1 addition & 0 deletions example-esm/lib/animals/lion.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function () { return 'a real lion' }
11 changes: 11 additions & 0 deletions example-esm/lib/zoo.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import lion from './animals/lion.mjs'
import bear from './animals/bear.mjs'

export default function () {
return {
animals: [
lion(),
bear()
]
}
}