diff --git a/lib/follow.ts b/lib/follow.ts index fe42c524d..5340fa170 100644 --- a/lib/follow.ts +++ b/lib/follow.ts @@ -4,6 +4,7 @@ import { core, sync, SyncOpts } from 'resolve'; import assert from 'assert'; import fs from 'fs'; import path from 'path'; +import { CachedInputFileSystem, ResolverFactory } from 'enhanced-resolve'; import { toNormalizedRealPath } from './common'; Object.keys(core).forEach((key) => { @@ -119,3 +120,40 @@ export function follow(x: string, opts: FollowOptions) { ); }); } + +export function followESM(x: string, opts: FollowOptions) { + return new Promise((resolve, reject) => { + const fileSystem = new CachedInputFileSystem(fs, 4000); + + fileSystem.readFileSync = (file) => { + if (opts.ignoreFile && opts.ignoreFile === file) { + return Buffer.from(`{"main":"${PROOF}"}`); + } + + if (opts.readFile) { + opts.readFile(file); + } + + return fs.readFileSync(file); + } + + const resolver = ResolverFactory.createResolver({ + extensions: opts.extensions as string[], + fileSystem + }); + + const lookupStartPath :string = opts.basedir || __dirname; + const context = {}; + const resolveContext = {}; + + resolver.resolve(context, lookupStartPath, x, resolveContext, (err, result) => { + if(!result || err) { + reject(err || Error(`Cannot resolve ${x}`)) + } else { + resolve(result); + } + }); + + + }); +} diff --git a/lib/walker.ts b/lib/walker.ts index bf78b9683..2c5df8e04 100644 --- a/lib/walker.ts +++ b/lib/walker.ts @@ -21,7 +21,7 @@ import { toNormalizedRealPath, } from './common'; -import { follow, natives } from './follow'; +import { follow, followESM, natives } from './follow'; import { log, wasReported } from './log'; import * as detector from './detector'; import { @@ -752,7 +752,7 @@ class Walker { const basedir = path.dirname(record.file); try { - newFile = await follow(derivative.alias, { + newFile = await followESM(derivative.alias, { basedir, // default is extensions: ['.js'], but // it is not enough because 'typos.json' diff --git a/package.json b/package.json index 9a007af1a..75d466d07 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@babel/parser": "7.13.13", "@babel/types": "7.13.12", "chalk": "^4.1.0", + "enhanced-resolve": "5.8.3", "escodegen": "^2.0.0", "fs-extra": "^9.1.0", "globby": "^11.0.3", diff --git a/test/test-00-esm/main.cjs b/test/test-00-esm/main.cjs new file mode 100644 index 000000000..9f6e00284 --- /dev/null +++ b/test/test-00-esm/main.cjs @@ -0,0 +1,47 @@ +#!/usr/bin/env node + +'use strict'; + +const path = require('path'); +const assert = require('assert'); +const utils = require('../utils.js'); +const os = require('os'); + +const MAJOR_VERSION = parseInt(process.version.match(/v([0-9]+)/)[1], 10); + +if (MAJOR_VERSION < 14) { + console.log( + 'skiping test as it requires nodejs >= 14', + MAJOR_VERSION + ); + return; +} + +assert(__dirname === process.cwd()); + +const ext = process.platform === 'win32' ? '.exe' : ''; + +const target = process.argv[2] || 'host'; +const input = './test.js'; +const output = './test-output' + ext; + +console.log('target = ', target); +utils.pkg.sync([ + '--target', + target, + '--output', + output, + input, +]); + +// check that produced executable is running and produce the expected output. +const log = utils.spawn.sync(output, [], { + cwd: path.dirname(output), + expect: 0, +}); +assert(log === os.arch() + '\n'); + +// clean up +utils.vacuum.sync(output); + +console.log('OK'); diff --git a/test/test-00-esm/package.json b/test/test-00-esm/package.json new file mode 100644 index 000000000..f295f8460 --- /dev/null +++ b/test/test-00-esm/package.json @@ -0,0 +1,13 @@ +{ + "name": "test-00-esm", + "version": "1.0.0", + "description": "", + "type": "module", + "main": "test.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/test/test-00-esm/test.js b/test/test-00-esm/test.js new file mode 100644 index 000000000..aea7ba01e --- /dev/null +++ b/test/test-00-esm/test.js @@ -0,0 +1,3 @@ +import os from 'os'; + +console.log(os.arch()); diff --git a/test/test.js b/test/test.js index 1384a1c09..c53c3f66b 100644 --- a/test/test.js +++ b/test/test.js @@ -49,11 +49,14 @@ function joinAndForward(d) { const list = []; if (flavor.match(/^test/)) { - list.push(joinAndForward(`${flavor}/main.js`)); + list.push( + joinAndForward(`${flavor}/main.js`), + joinAndForward(`${flavor}/main.cjs`) + ); } else if (flavor === 'only-npm') { list.push(joinAndForward('test-79-npm/main.js')); } else { - list.push(joinAndForward('**/main.js')); + list.push(joinAndForward('**/main.js'), joinAndForward('**/main.cjs')); if (flavor === 'no-npm') { list.push('!' + joinAndForward('test-42-fetch-all')); list.push('!' + joinAndForward('test-46-multi-arch')); diff --git a/yarn.lock b/yarn.lock index 27813080c..c29a8cc1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -868,6 +868,14 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +enhanced-resolve@5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" @@ -1370,6 +1378,11 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +graceful-fs@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz" @@ -2603,6 +2616,11 @@ table@^6.0.9: string-width "^4.2.0" strip-ansi "^6.0.0" +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz"