@@ -1362,9 +1362,7 @@ transpiler hooks should only be used for development and testing purposes.
1362
1362
` ` ` mjs
1363
1363
// coffeescript-hooks.mjs
1364
1364
import { readFile } from ' node:fs/promises' ;
1365
- import { dirname , extname , resolve as resolvePath } from ' node:path' ;
1366
- import { cwd } from ' node:process' ;
1367
- import { fileURLToPath , pathToFileURL } from ' node:url' ;
1365
+ import { findPackageJSON } from ' node:module' ;
1368
1366
import coffeescript from ' coffeescript' ;
1369
1367
1370
1368
const extensionsRegex = / \. (coffee| litcoffee| coffee\. md)$ / ;
@@ -1391,7 +1389,7 @@ export async function load(url, context, nextLoad) {
1391
1389
}
1392
1390
1393
1391
// Let Node.js handle all other URLs.
1394
- return nextLoad (url);
1392
+ return nextLoad (url, context );
1395
1393
}
1396
1394
1397
1395
async function getPackageType (url ) {
@@ -1402,37 +1400,23 @@ async function getPackageType(url) {
1402
1400
// this simple truthy check for whether `url` contains a file extension will
1403
1401
// work for most projects but does not cover some edge-cases (such as
1404
1402
// extensionless files or a url ending in a trailing space)
1405
- const isFilePath = !! extname (url);
1406
- // If it is a file path, get the directory it's in
1407
- const dir = isFilePath ?
1408
- dirname (fileURLToPath (url)) :
1409
- url;
1410
- // Compose a file path to a package.json in the same directory,
1411
- // which may or may not exist
1412
- const packagePath = resolvePath (dir, ' package.json' );
1413
- // Try to read the possibly nonexistent package.json
1414
- const type = await readFile (packagePath, { encoding: ' utf8' })
1415
- .then ((filestring ) => JSON .parse (filestring).type )
1416
- .catch ((err ) => {
1417
- if (err? .code !== ' ENOENT' ) console .error (err);
1418
- });
1419
- // If package.json existed and contained a `type` field with a value, voilà
1420
- if (type) return type;
1421
- // Otherwise, (if not at the root) continue checking the next directory up
1422
- // If at the root, stop and return false
1423
- return dir .length > 1 && getPackageType (resolvePath (dir, ' ..' ));
1403
+ const pJson = findPackageJSON (url);
1404
+ if (pJson) {
1405
+ try {
1406
+ const file = await readFile (pJson, ' utf8' );
1407
+ return JSON .parse (file)? .type ;
1408
+ } catch {}
1409
+ }
1410
+ return undefined ;
1424
1411
}
1425
1412
` ` `
1426
1413
1427
1414
##### Synchronous version
1428
1415
1429
1416
` ` ` mjs
1430
1417
// coffeescript-sync-hooks.mjs
1431
- import { readFileSync } from ' node:fs/promises' ;
1432
- import { registerHooks } from ' node:module' ;
1433
- import { dirname , extname , resolve as resolvePath } from ' node:path' ;
1434
- import { cwd } from ' node:process' ;
1435
- import { fileURLToPath , pathToFileURL } from ' node:url' ;
1418
+ import { readFileSync } from ' node:fs' ;
1419
+ import { registerHooks , findPackageJSON } from ' node:module' ;
1436
1420
import coffeescript from ' coffeescript' ;
1437
1421
1438
1422
const extensionsRegex = / \. (coffee| litcoffee| coffee\. md)$ / ;
@@ -1451,23 +1435,18 @@ function load(url, context, nextLoad) {
1451
1435
};
1452
1436
}
1453
1437
1454
- return nextLoad (url);
1438
+ return nextLoad (url, context );
1455
1439
}
1456
1440
1457
1441
function getPackageType (url ) {
1458
- const isFilePath = !! extname (url);
1459
- const dir = isFilePath ? dirname (fileURLToPath (url)) : url;
1460
- const packagePath = resolvePath (dir, ' package.json' );
1461
-
1462
- let type;
1463
- try {
1464
- const filestring = readFileSync (packagePath, { encoding: ' utf8' });
1465
- type = JSON .parse (filestring).type ;
1466
- } catch (err) {
1467
- if (err? .code !== ' ENOENT' ) console .error (err);
1442
+ const pJson = findPackageJSON (url);
1443
+ if (pJson) {
1444
+ try {
1445
+ const file = readFileSync (pJson, ' utf-8' );
1446
+ return JSON .parse (file)? .type ;
1447
+ } catch { }
1468
1448
}
1469
- if (type) return type;
1470
- return dir .length > 1 && getPackageType (resolvePath (dir, ' ..' ));
1449
+ return undefined ;
1471
1450
}
1472
1451
1473
1452
registerHooks ({ load });
@@ -1489,6 +1468,21 @@ console.log "Brought to you by Node.js version #{version}"
1489
1468
export scream = (str ) - > str .toUpperCase ()
1490
1469
` ` `
1491
1470
1471
+ For the sake of running the example, add a ` package .json ` file containing the
1472
+ module type of the CoffeeScript files.
1473
+
1474
+ ` ` ` json
1475
+ {
1476
+ " type" : " module"
1477
+ }
1478
+ ` ` `
1479
+
1480
+ In real world loaders, ` getPackageType ()` must be able to return an ` format`
1481
+ known to Node.js even in the absence of an explicit type in a ` package .json ` ,
1482
+ or otherwise the loader hook would throw ` ERR_UNKNOWN_FILE_EXTENSION ` (if undefined)
1483
+ or ` ERR_UNKNOWN_MODULE_FORMAT ` (if it's not a known format listed in the [load hook][]
1484
+ documentation).
1485
+
1492
1486
With the preceding hooks modules, running
1493
1487
` node -- import ' data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee`
1494
1488
or ` node --import ./coffeescript-sync-hooks.mjs ./main.coffee`
0 commit comments