Skip to content

Commit

Permalink
fix: Remove support for loading .js config under type: 'module' (#10)
Browse files Browse the repository at this point in the history
It is not possible to detect if this is safe and protecting CJS users is
currently a priority.  Users who want to provide ESM configuration will
need to use `nyc.config.mjs`.
  • Loading branch information
coreyfarrell committed Nov 22, 2019
1 parent 09b6fa8 commit 420fe87
Show file tree
Hide file tree
Showing 12 changed files with 27 additions and 80 deletions.
1 change: 1 addition & 0 deletions .taprc
@@ -1,5 +1,6 @@
{
"test-ignore": "helpers",
"esm": false,
"100": true,
"nyc-arg": "--nycrc-path=nyc-settings.js"
}
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -4,6 +4,7 @@ os:
- linux
- osx
node_js:
- "node"
- 13
- 12
- 10
- 8
17 changes: 3 additions & 14 deletions index.js
Expand Up @@ -19,18 +19,6 @@ const standardConfigFiles = [
'nyc.config.mjs'
];

async function moduleLoader(file) {
try {
return require(file);
} catch (error) {
if (error.code !== 'ERR_REQUIRE_ESM') {
throw error;
}

return require('./load-esm')(file);
}
}

function camelcasedConfig(config) {
const results = {};
for (const [field, value] of Object.entries(config)) {
Expand Down Expand Up @@ -64,10 +52,11 @@ async function actualLoad(configFile) {
const configExt = path.extname(configFile).toLowerCase();
switch (configExt) {
case '.js':
case '.mjs':
return moduleLoader(configFile);
case '.cjs':
return require(configFile);
/* istanbul ignore next: coverage for 13.2.0+ is shown in load-esm.js */
case '.mjs':
return require('./load-esm')(configFile);
case '.yml':
case '.yaml':
return require('js-yaml').load(await readFile(configFile, 'utf8'));
Expand Down
4 changes: 3 additions & 1 deletion load-esm.js
@@ -1,7 +1,9 @@
'use strict';

const {pathToFileURL} = require('url');

module.exports = async filename => {
const mod = await import(filename);
const mod = await import(pathToFileURL(filename));
if ('default' in mod === false) {
throw new Error(`${filename} has no default export`);
}
Expand Down
4 changes: 2 additions & 2 deletions nyc-settings.js
@@ -1,12 +1,12 @@
'use strict';

const {hasImport} = require('./test/helpers');
const {hasESM} = require('./test/helpers');

const include = [
'index.js'
];

if (hasImport) {
if (hasESM) {
include.push('load-esm.js');
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -28,6 +28,7 @@
"resolve-from": "^5.0.0"
},
"devDependencies": {
"semver": "^6.3.0",
"standard-version": "^7.0.0",
"tap": "^14.6.5",
"xo": "^0.25.3"
Expand Down
21 changes: 7 additions & 14 deletions tap-snapshots/test-basic.js-TAP.test.js
Expand Up @@ -32,20 +32,6 @@ Object {
}
`

exports[`test/basic.js TAP esm nyc-config-js-type-module > must match snapshot 1`] = `
Object {
"all": false,
"cwd": "nyc-config-js-type-module",
}
`

exports[`test/basic.js TAP esm nyc-config-mjs > must match snapshot 1`] = `
Object {
"all": false,
"cwd": "nyc-config-mjs",
}
`

exports[`test/basic.js TAP extends > must match snapshot 1`] = `
Object {
"all": false,
Expand Down Expand Up @@ -116,6 +102,13 @@ Object {
}
`

exports[`test/basic.js TAP nyc-config-mjs > must match snapshot 1`] = `
Object {
"all": false,
"cwd": "nyc-config-mjs",
}
`

exports[`test/basic.js TAP nycrc-json > must match snapshot 1`] = `
Object {
"all": false,
Expand Down
18 changes: 4 additions & 14 deletions test/basic.js
@@ -1,6 +1,6 @@
const path = require('path');
const t = require('tap');
const {fixturePath, sanitizeConfig, basicTest, hasImport, hasESM} = require('./helpers');
const {fixturePath, sanitizeConfig, basicTest, hasESM} = require('./helpers');
const {loadNycConfig} = require('..');

t.test('options.nycrcPath points to non-existent file', async t => {
Expand Down Expand Up @@ -32,7 +32,7 @@ t.test('extends failures', async t => {
'invalid.cjs': /Unexpected identifier/,
'missing.json': /Could not resolve configuration file/
};
if (hasImport && await hasESM()) {
if (hasESM) {
files['invalid.mjs'] = /has no default export/;
}

Expand All @@ -59,16 +59,6 @@ t.test('found package.json cwd from subdir', async t => {
t.matchSnapshot(sanitizeConfig(await loadNycConfig({cwd})));
});

if (hasImport) {
t.test('esm', async t => {
if (await hasESM()) {
if (process.versions.node.split('.')[0] >= 12) {
await t.test('nyc-config-js-type-module', basicTest);
}

await t.test('nyc-config-mjs', basicTest);
} else {
t.pass('we have import but it doesn\'t support ES modules');
}
});
if (hasESM) {
t.test('nyc-config-mjs', basicTest);
}
3 changes: 0 additions & 3 deletions test/fixtures/nyc-config-js-type-module/nyc.config.js

This file was deleted.

6 changes: 0 additions & 6 deletions test/fixtures/nyc-config-js-type-module/package.json

This file was deleted.

1 change: 0 additions & 1 deletion test/helpers/esm-tester.mjs

This file was deleted.

28 changes: 4 additions & 24 deletions test/helpers/index.js
@@ -1,8 +1,11 @@
const path = require('path');
const semver = require('semver');
const {loadNycConfig} = require('../..');

const hasESM = semver.gte(process.versions.node, '13.2.0');

function fixturePath(...args) {
return path.join(__dirname, '..', 'fixtures', ...args);
return path.resolve(__dirname, '..', 'fixtures', ...args);
}

function sanitizeConfig(config) {
Expand All @@ -22,32 +25,9 @@ async function basicTest(t) {
t.matchSnapshot(sanitizeConfig(config));
}

function canImport() {
try {
return typeof require('../../load-esm') === 'function';
} catch (_) {
return false;
}
}

async function hasESM() {
try {
const loader = require('../../load-esm');
try {
await loader(require.resolve('./esm-tester.mjs'));
return true;
} catch (_) {
return false;
}
} catch (_) {
return false;
}
}

module.exports = {
fixturePath,
sanitizeConfig,
basicTest,
hasImport: canImport(),
hasESM
};

0 comments on commit 420fe87

Please sign in to comment.