69 lines
2.4 KiB
JavaScript
69 lines
2.4 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
// Transpiles all .js files under a directory (in place) to syntax supported
|
||
|
|
// by nodejs-mobile-cordova's embedded Node 12.19 — primarily optional
|
||
|
|
// chaining (?.) and nullish coalescing (??) used by some npm dependencies
|
||
|
|
// and by this project's own source.
|
||
|
|
//
|
||
|
|
// Usage: node transpile-node12.js <dir> [<dir> ...]
|
||
|
|
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
// Resolve esbuild from this project's own node_modules (no longer parent repo)
|
||
|
|
const esbuild = require('esbuild');
|
||
|
|
|
||
|
|
const SKIP_DIRS = new Set(['.bin']);
|
||
|
|
|
||
|
|
function walk(dir, cb) {
|
||
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||
|
|
if (SKIP_DIRS.has(entry.name)) continue;
|
||
|
|
const full = path.join(dir, entry.name);
|
||
|
|
if (entry.isSymbolicLink()) continue;
|
||
|
|
if (entry.isDirectory()) {
|
||
|
|
walk(full, cb);
|
||
|
|
} else if (entry.name.endsWith('.js') || entry.name.endsWith('.cjs') || entry.name === 'package.json') {
|
||
|
|
cb(full);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
let count = 0;
|
||
|
|
let pkgCount = 0;
|
||
|
|
for (const dir of process.argv.slice(2)) {
|
||
|
|
if (!fs.existsSync(dir)) continue;
|
||
|
|
walk(dir, (file) => {
|
||
|
|
if (path.basename(file) === 'package.json') {
|
||
|
|
// esbuild converts ESM (import/export) to CJS (module.exports) below,
|
||
|
|
// but Node still treats .js files as ES modules if the nearest
|
||
|
|
// package.json has "type": "module" — drop that so the converted
|
||
|
|
// CJS output is loaded correctly under Node 12.
|
||
|
|
const pkg = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||
|
|
if (pkg.type === 'module') {
|
||
|
|
delete pkg.type;
|
||
|
|
fs.writeFileSync(file, JSON.stringify(pkg, null, 2) + '\n');
|
||
|
|
pkgCount++;
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const src = fs.readFileSync(file, 'utf8');
|
||
|
|
let out;
|
||
|
|
try {
|
||
|
|
out = esbuild.transformSync(src, { target: 'node12', format: 'cjs', loader: 'js' }).code;
|
||
|
|
} catch (err) {
|
||
|
|
console.warn(`Skipping ${file}: ${err.message.split('\n')[0]}`);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
// Node 12 doesn't understand the "node:" builtin-module prefix
|
||
|
|
// (added in Node 14.18/16), used by some dependencies (e.g. express-rate-limit).
|
||
|
|
out = out.replace(/require\((['"])node:([a-z/_-]+)\1\)/g, "require($1$2$1)");
|
||
|
|
|
||
|
|
if (out !== src) {
|
||
|
|
fs.writeFileSync(file, out);
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
console.log(`Transpiled ${count} file(s) and dropped "type": "module" from ${pkgCount} package.json file(s) for Node 12 compatibility.`);
|