Skip to content

Commit 5c8f8fd

Browse files
committed
enable ES module mode automatically
by prepending --experimental-modules flag https://nodejs.org/api/esm.html#esm_enabling
1 parent 674b9ec commit 5c8f8fd

File tree

6 files changed

+134
-9
lines changed

6 files changed

+134
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
coverage
22
node_modules
3+
tmp

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ All files | 95.15 | 79.52 | 100 | 95.09 | |
2727
----------|----------|----------|----------|----------|-------------------|
2828
```
2929

30-
This is a wrapper of [c8](https://github.com/bcoe/c8), different in the following points:
30+
This is an opinionated wrapper of [c8](https://github.com/bcoe/c8), different in the following points:
3131

3232
* Runs both [`html` and `text` reporter](https://github.com/istanbuljs/nyc#running-reports) by default
33+
* Automatically enables [ECMAScript module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) support for `.mjs` files
3334
* The first argument can be a JavaScript file path instead of a command
3435
* Built-in [Codecov](https://codecov.io) support
3536

@@ -49,13 +50,19 @@ Once this package is installed to the project directory, users can execute `cove
4950

5051
<img alt="An example of the HTML report" src="screenshot.png" width="330px" align="right">
5152

52-
Execute a JavaScript file with Node.js or run a command, print code coverage to the stdout and write [HTML reports](https://istanbul.js.org/docs/advanced/alternative-reporters/#html) under the `./coverage` directory.
53+
Execute the command, print code coverage to the stdout and write [HTML reports](https://istanbul.js.org/docs/advanced/alternative-reporters/#html) under the `./coverage` directory.
54+
55+
`<file|command>` can be either a JavaScript file path or a command. If a path is provided, the file is run with the `node` command.
5356

5457
```console
55-
$ coverage /path/to/entry-point.js # is the same as ↓
58+
$ coverage /path/to/entry-point.js # is the same as ↓
5659
$ coverage node /path/to/entry-point.js
5760
```
5861

62+
If the provided JavaScript path ends with `.mjs`, [ECMAScript module mode](https://nodejs.org/api/esm.html) is automatically [enabled](https://nodejs.org/api/esm.html#esm_enabling) and [`--es-module-specifier-resolution`](https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm) is set to `node`.
63+
64+
#### Reporters
65+
5966
Users can override the default format of reports with `--reporter` option.
6067

6168
```console
@@ -79,6 +86,8 @@ Lines : 100% ( 1/1 )
7986
$ coverage --reporter=none example.js # No reports
8087
```
8188

89+
#### Codecov integration
90+
8291
When the execution exits with code `0` on a CI service or [GitHub Actions](https://github.com/features/actions), it automatically uploads the generated coverage to [Codecov](https://docs.codecov.io/docs). Whether `CODECOV_TOKEN` environment variable is required or not varies between [services](https://github.com/codecov/codecov-bash#ci-providers).
8392

8493
```console

index.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const c8PackageData = require(c8PackageJsonPath);
2020
normalizePackageData(c8PackageData);
2121

2222
const c8BinPath = join(dirname(c8PackageJsonPath), c8PackageData.bin.c8);
23-
const [nodePath] = process.argv;
23+
const nodePath = process.execPath;
2424
const optionArgs = process.argv.slice(2);
2525
const {_: [command], reporter} = yargsParser(optionArgs);
2626
const promisifiedWhich = promisify(which);
@@ -65,7 +65,17 @@ const codecovBashPath = process.platform === 'win32' ? join(cwd, 'coverage', uui
6565
process.exit(127);
6666
}
6767

68-
optionArgs.splice(optionArgs.indexOf(command), 1, nodePath, entryPath);
68+
optionArgs.splice(
69+
optionArgs.indexOf(command),
70+
1,
71+
nodePath,
72+
...ext === 'mjs' ? [
73+
'--experimental-modules',
74+
'--es-module-specifier-resolution=node',
75+
'--no-warnings'
76+
] : [],
77+
entryPath
78+
);
6979
}
7080

7181
return [

package-lock.json

Lines changed: 83 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"@shinnn/eslint-config": "^6.10.2",
4545
"eslint": "^5.16.0",
4646
"lodash": "^4.17.11",
47+
"rmfr": "^2.0.0",
4748
"tape": "^4.10.1"
4849
},
4950
"eslintConfig": {

test.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
'use strict';
22

3+
const {dirname, join} = require('path');
34
const {execFile} = require('child_process');
4-
const {join} = require('path');
5+
const {mkdir, writeFile} = require('fs').promises;
56
const {promisify} = require('util');
67

78
const attempt = require('lodash/attempt');
9+
const rmfr = require('rmfr');
810
const test = require('tape');
911

1012
const coverage = require.resolve('.');
11-
const execNode = promisify(execFile).bind(null, process.argv[0]);
13+
const execNode = promisify(execFile).bind(null, process.execPath);
1214
const timeout = 1000000;
1315

1416
test('A `coverage` command with a command', async t => {
@@ -54,14 +56,14 @@ test('A `coverage` command with a file path', async t => {
5456
t.end();
5557
});
5658

57-
test('A `coverage` command with nyc flags', async t => {
59+
test('A `coverage` command with c8 flags', async t => {
5860
try {
5961
await execNode([coverage, '--reporter=unknown', 'node', '--version'], {timeout});
6062
t.fail('Unexpectedly succeeded.');
6163
} catch ({stderr}) {
6264
t.ok(
6365
stderr.includes('Cannot find module \'unknown\''),
64-
'should pass flags to the underlying `nyc` command.'
66+
'should pass flags to the underlying `c8` command.'
6567
);
6668
}
6769

@@ -158,3 +160,22 @@ test('A `coverage report` command', async t => {
158160

159161
t.end();
160162
});
163+
164+
if (Number(process.versions.node.split('.')[0]) >= 12) {
165+
test('A `coverage` command with a .mjs file path', async t => {
166+
const tmpFile = join(__dirname, 'tmp', 'tmp.mjs');
167+
168+
await rmfr(dirname(tmpFile));
169+
await mkdir(dirname(tmpFile));
170+
await writeFile(tmpFile, 'import {open} from "fs"');
171+
await execNode([
172+
coverage,
173+
'--exclude=tmp.mjs',
174+
`--temp-directory=${join(dirname(tmpFile), '_')}`,
175+
tmpFile
176+
], {timeout});
177+
t.pass('should enable ECMAScript modules for .mjs files automatically.');
178+
179+
t.end();
180+
});
181+
}

0 commit comments

Comments
 (0)