Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
Support .mjs files by default.
Browse files Browse the repository at this point in the history
Since rollup prefers ESM formatted modules, it should look for node's new .mjs file extension before looking for .js files by default. This offers support for deployed modules intended to be used in node's ESM mode.

Folks can work around this today by manually supplying the `extensions` option, however it would be great if this worked by default.

Note that looking for `.mjs` before `.js` is important for rollup which prefers ESM, however the `resolve` dependency should not use the same order by default since it is used in many other tools which do not yet support ESM or would not expect it by default.

Encountered this as the root cause behind graphql/graphql-js#1293
  • Loading branch information
leebyron committed Mar 29, 2018
1 parent 7846a19 commit f711ab2
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 5 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -44,7 +44,7 @@ export default {
browser: true, // Default: false

// not all files you want to resolve are .js files
extensions: [ '.js', '.json' ], // Default: ['.js']
extensions: [ '.mjs', '.js', '.jsx', '.json' ], // Default: [ '.mjs', '.js', '.json', '.node' ]

// whether to prefer built-in modules (e.g. `fs`, `path`) or
// local ones with the same names
Expand All @@ -53,7 +53,7 @@ export default {
// Lock the module search in this path (like a chroot). Module defined
// outside this path will be marked as external
jail: '/my/jail/path', // Default: '/'

// Set to an array of strings and/or regexps to lock the module search
// to modules that match at least one entry. Modules not matching any
// entry will be marked as external
Expand Down
9 changes: 6 additions & 3 deletions src/index.js
Expand Up @@ -6,7 +6,9 @@ import fs from 'fs';

const ES6_BROWSER_EMPTY = resolve( __dirname, '../src/empty.js' );
const CONSOLE_WARN = ( ...args ) => console.warn( ...args ); // eslint-disable-line no-console
const exts = [ '.js', '.json', '.node' ];
// It is important that .mjs occur before .js so that Rollup will interpret npm modules
// which deploy both ESM .mjs and CommonJS .js files as ESM.
const DEFAULT_EXTS = [ '.mjs', '.js', '.json', '.node' ];

let readFileCache = {};
const readFileAsync = file => new Promise((fulfil, reject) => fs.readFile(file, (err, contents) => err ? reject(err) : fulfil(contents)));
Expand Down Expand Up @@ -110,6 +112,7 @@ export default function nodeResolve ( options = {} ) {
return new Promise( ( fulfil, reject ) => {
let disregardResult = false;
let packageBrowserField = false;
const extensions = options.extensions || DEFAULT_EXTS;

const resolveOptions = {
basedir: dirname( importer ),
Expand All @@ -123,7 +126,7 @@ export default function nodeResolve ( options = {} ) {
const absoluteKey = resolve( pkgRoot, key );
browser[ absoluteKey ] = resolved;
if ( !extname(key) ) {
exts.reduce( ( browser, ext ) => {
extensions.reduce( ( browser, ext ) => {
browser[ absoluteKey + ext ] = browser[ key ];
return browser;
}, browser );
Expand All @@ -146,7 +149,7 @@ export default function nodeResolve ( options = {} ) {
},
readFile: cachedReadFile,
isFile: cachedIsFile,
extensions: options.extensions
extensions: extensions
};

if (preserveSymlinks !== undefined) {
Expand Down
1 change: 1 addition & 0 deletions test/node_modules/dual-cjs-mjs/entry.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/node_modules/dual-cjs-mjs/entry.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/node_modules/dual-cjs-mjs/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/node_modules/module-mjs/entry.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/node_modules/module-mjs/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/samples/dual-cjs-mjs/main.js
@@ -0,0 +1,3 @@
import module from 'dual-cjs-mjs';

export default module; // MODULE
3 changes: 3 additions & 0 deletions test/samples/module-mjs/main.js
@@ -0,0 +1,3 @@
import module from 'module-mjs';

export default module; // MODULE
22 changes: 22 additions & 0 deletions test/test.js
Expand Up @@ -436,6 +436,28 @@ describe( 'rollup-plugin-node-resolve', function () {
});
});

it('finds and uses an .mjs module', function () {
return rollup.rollup({
input: 'samples/module-mjs/main.js',
plugins: [
nodeResolve({ preferBuiltins: false })
]
}).then( executeBundle ).then( module => {
assert.equal( module.exports, 'MODULE-MJS' );
});
});

it('finds and uses a dual-distributed .js & .mjs module', function () {
return rollup.rollup({
input: 'samples/dual-cjs-mjs/main.js',
plugins: [
nodeResolve({ preferBuiltins: false })
]
}).then( executeBundle ).then( module => {
assert.equal( module.exports, 'DUAL-MJS' );
});
});

describe( 'symlinks', () => {
function createMissingDirectories () {
createDirectory( './samples/symlinked/first/node_modules' );
Expand Down

0 comments on commit f711ab2

Please sign in to comment.