summaryrefslogtreecommitdiff
path: root/utils/js2common.js
diff options
context:
space:
mode:
Diffstat (limited to 'utils/js2common.js')
-rwxr-xr-xutils/js2common.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/utils/js2common.js b/utils/js2common.js
new file mode 100755
index 0000000..aeba49d
--- /dev/null
+++ b/utils/js2common.js
@@ -0,0 +1,140 @@
+#!/usr/bin/env node
+
+const path = require('path');
+const program = require('commander');
+const fs = require('fs');
+const fse = require('fs-extra');
+const babel = require('@babel/core');
+
+program
+ .option('-m, --with-source-maps [type]', 'output source maps when not generating a bundled app (type may be empty for external source maps, inline for inline source maps, or both) ')
+ .option('--clean', 'clear the lib folder before building')
+ .parse(process.argv);
+
+// the various important paths
+const paths = {
+ main: path.resolve(__dirname, '..'),
+ core: path.resolve(__dirname, '..', 'core'),
+ vendor: path.resolve(__dirname, '..', 'vendor'),
+ libDirBase: path.resolve(__dirname, '..', 'lib'),
+};
+
+// util.promisify requires Node.js 8.x, so we have our own
+function promisify(original) {
+ return function promiseWrap() {
+ const args = Array.prototype.slice.call(arguments);
+ return new Promise((resolve, reject) => {
+ original.apply(this, args.concat((err, value) => {
+ if (err) return reject(err);
+ resolve(value);
+ }));
+ });
+ };
+}
+
+const writeFile = promisify(fs.writeFile);
+
+const readdir = promisify(fs.readdir);
+const lstat = promisify(fs.lstat);
+
+const ensureDir = promisify(fse.ensureDir);
+
+const babelTransformFile = promisify(babel.transformFile);
+
+// walkDir *recursively* walks directories trees,
+// calling the callback for all normal files found.
+function walkDir(basePath, cb, filter) {
+ return readdir(basePath)
+ .then((files) => {
+ const paths = files.map(filename => path.join(basePath, filename));
+ return Promise.all(paths.map(filepath => lstat(filepath)
+ .then((stats) => {
+ if (filter !== undefined && !filter(filepath, stats)) return;
+
+ if (stats.isSymbolicLink()) return;
+ if (stats.isFile()) return cb(filepath);
+ if (stats.isDirectory()) return walkDir(filepath, cb, filter);
+ })));
+ });
+}
+
+function makeLibFiles(sourceMaps) {
+ // NB: we need to make a copy of babelOpts, since babel sets some defaults on it
+ const babelOpts = () => ({
+ plugins: [],
+ presets: [
+ [ '@babel/preset-env',
+ { modules: 'commonjs' } ]
+ ],
+ ast: false,
+ sourceMaps: sourceMaps,
+ });
+
+ fse.ensureDirSync(paths.libDirBase);
+
+ const outFiles = [];
+
+ const handleDir = (vendorRewrite, inPathBase, filename) => Promise.resolve()
+ .then(() => {
+ const outPath = path.join(paths.libDirBase, path.relative(inPathBase, filename));
+
+ if (path.extname(filename) !== '.js') {
+ return; // skip non-javascript files
+ }
+ return Promise.resolve()
+ .then(() => ensureDir(path.dirname(outPath)))
+ .then(() => {
+ const opts = babelOpts();
+ // Adjust for the fact that we move the core files relative
+ // to the vendor directory
+ if (vendorRewrite) {
+ opts.plugins.push(["import-redirect",
+ {"root": paths.libDirBase,
+ "redirect": { "vendor/(.+)": "./vendor/$1"}}]);
+ }
+
+ return babelTransformFile(filename, opts)
+ .then((res) => {
+ console.log(`Writing ${outPath}`);
+ const {map} = res;
+ let {code} = res;
+ if (sourceMaps === true) {
+ // append URL for external source map
+ code += `\n//# sourceMappingURL=${path.basename(outPath)}.map\n`;
+ }
+ outFiles.push(`${outPath}`);
+ return writeFile(outPath, code)
+ .then(() => {
+ if (sourceMaps === true || sourceMaps === 'both') {
+ console.log(` and ${outPath}.map`);
+ outFiles.push(`${outPath}.map`);
+ return writeFile(`${outPath}.map`, JSON.stringify(map));
+ }
+ });
+ });
+ });
+ });
+
+ Promise.resolve()
+ .then(() => {
+ const handler = handleDir.bind(null, false, paths.main);
+ return walkDir(paths.vendor, handler);
+ })
+ .then(() => {
+ const handler = handleDir.bind(null, true, paths.core);
+ return walkDir(paths.core, handler);
+ })
+ .catch((err) => {
+ console.error(`Failure converting modules: ${err}`);
+ process.exit(1);
+ });
+}
+
+let options = program.opts();
+
+if (options.clean) {
+ console.log(`Removing ${paths.libDirBase}`);
+ fse.removeSync(paths.libDirBase);
+}
+
+makeLibFiles(options.withSourceMaps);