Mobile-BillTracker/scripts/transpile-node12.js

69 lines
2.4 KiB
JavaScript
Raw Permalink Normal View History

#!/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.`);