DenReg/jsx-html/deno2nodejs.js

102 lines
3.0 KiB
JavaScript

const fs = require('fs');
const { parse } = require('@babel/parser');
const { default: generator } = require('@babel/generator');
const { default: traverse } = require('@babel/traverse');
const { resolve, extname, join, dirname } = require('path');
const { tmpdir } = require('os');
const { readdir } = require('fs').promises;
const { cwd } = require('process');
const exts = ['.ts'];
const excludes = [
'/node_modules/',
'/examples/',
'/dist/',
'/jsx.d.ts',
'/mod.d.ts',
'/deno.d.ts',
];
const regExpRemoveExts = /\.(ts|tsx|js|jsx)$/i;
const tsconfig = {
compilerOptions: {
types: ['node'],
module: 'commonjs',
declaration: true,
removeComments: true,
emitDecoratorMetadata: true,
experimentalDecorators: true,
allowSyntheticDefaultImports: true,
target: 'es6',
sourceMap: true,
outDir: join(cwd(), 'nodejs'),
baseUrl: './',
},
};
// const distFolder = join(tmpdir(), `deno2nodejs-${+new Date()}`);
const distFolder = join(cwd(), `tmp`);
console.log('distFolder:', distFolder);
fs.mkdirSync(distFolder);
fs.writeFileSync(join(distFolder, 'tsconfig.json'), JSON.stringify(tsconfig));
async function getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(
dirents.map((dirent) => {
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}),
);
return Array.prototype.concat(...files);
}
getFiles('./').then((files) => {
const tsFiles = files.filter(
(f) =>
exts.includes(extname(f)) &&
!excludes.some((val) => f.includes(val)),
);
tsFiles.forEach((file) => {
const code = deno2nodejs(file);
const dist = join(distFolder, file.substr(cwd().length));
const ensureDir = dirname(dist);
fs.mkdirSync(ensureDir, { recursive: true });
fs.writeFileSync(dist, code);
// console.log({ file, dist, ensureDir });
});
});
// we might want to execute `tsc -p ./tmp/tsconfig.json` in here
function deno2nodejs(file) {
const source = fs.readFileSync(file).toString();
const ast = parse(source, {
sourceType: 'module',
plugins: ['typescript', 'classProperties'],
});
traverse(ast, {
ImportDeclaration: function ImportDeclaration(path) {
var source = path.node.source;
if (!source.value.match(regExpRemoveExts)) {
return;
}
source.value = source.value.replace(regExpRemoveExts, '');
},
ExportDeclaration: function ExportDeclaration(path) {
var source = path.node.source;
if (source) {
if (!source.value.match(regExpRemoveExts)) {
return;
}
source.value = source.value.replace(regExpRemoveExts, '');
}
},
});
const { code } = generator(ast);
return code;
}