]> git.proxmox.com Git - mirror_novnc.git/blame - utils/use_require.js
Allow transforming to any format
[mirror_novnc.git] / utils / use_require.js
CommitLineData
ae510306
SR
1#!/usr/bin/env node
2
3var path = require('path');
4var program = require('commander');
5var fs = require('fs');
6var fse = require('fs-extra');
ae510306 7
6cae7b58 8const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']);
ae510306
SR
9
10program
6cae7b58
SR
11 .option('--as [format]', `output files using various import formats instead of ES6 import and export. Supports ${Array.from(SUPPORTED_FORMATS)}.`)
12 .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) ')
13 .option('--with-app', 'process app files as well as core files')
ae510306
SR
14 .parse(process.argv);
15
16// the various important paths
6cae7b58 17var main_path = path.resolve(__dirname, '..');
ae510306
SR
18var core_path = path.resolve(__dirname, '..', 'core');
19var app_path = path.resolve(__dirname, '..', 'app');
6cae7b58 20var vendor_path = path.resolve(__dirname, '..', 'vendor');
ae510306
SR
21var out_dir_base = path.resolve(__dirname, '..', 'build');
22var lib_dir_base = path.resolve(__dirname, '..', 'lib');
23
6cae7b58
SR
24// walkDir *recursively* walks directories trees,
25// calling the callback for all normal files found.
26var walkDir = function (base_path, cb) {
27 fs.readdir(base_path, (err, files) => {
28 if (err) throw err;
ae510306 29
6cae7b58
SR
30 files.map((filename) => path.join(base_path, filename)).forEach((filepath) => {
31 fs.lstat(filepath, (err, stats) => {
32 if (err) throw err;
ae510306 33
6cae7b58
SR
34 if (stats.isSymbolicLink()) return;
35 if (stats.isFile()) cb(filepath);
36 if (stats.isDirectory()) walkDir(filepath, cb);
ae510306
SR
37 });
38 });
39 });
6cae7b58 40};
ae510306 41
6cae7b58 42var transform_html = function (new_script) {
ae510306
SR
43 // write out the modified vnc.html file that works with the bundle
44 var src_html_path = path.resolve(__dirname, '..', 'vnc.html');
45 var out_html_path = path.resolve(out_dir_base, 'vnc.html');
6cae7b58 46 fs.readFile(src_html_path, (err, contents_raw) => {
ae510306
SR
47 if (err) { throw err; }
48
49 var contents = contents_raw.toString();
ae510306
SR
50
51 var start_marker = '<!-- begin scripts -->\n';
52 var end_marker = '<!-- end scripts -->';
53 var start_ind = contents.indexOf(start_marker) + start_marker.length;
54 var end_ind = contents.indexOf(end_marker, start_ind);
55
6cae7b58 56 contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind);
ae510306 57
6cae7b58 58 console.log(`Writing ${out_html_path}`);
ae510306
SR
59 fs.writeFile(out_html_path, contents, function (err) {
60 if (err) { throw err; }
ae510306
SR
61 });
62 });
6cae7b58 63}
ae510306 64
6cae7b58
SR
65var make_lib_files = function (import_format, source_maps, with_app_dir) {
66 if (!import_format) {
67 throw new Error("you must specify an import format to generate compiled noVNC libraries");
68 } else if (!SUPPORTED_FORMATS.has(import_format)) {
69 throw new Error(`unsupported output format "${import_format}" for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported`);
70 }
71
72 // NB: we need to make a copy of babel_opts, since babel sets some defaults on it
73 const babel_opts = () => ({
74 plugins: [`transform-es2015-modules-${import_format}`],
75 ast: false,
76 sourceMaps: source_maps,
77 });
78 const babel = require('babel-core');
79
80 var in_path;
81 if (with_app_dir) {
82 var out_path_base = out_dir_base;
83 in_path = main_path;
84 } else {
85 var out_path_base = lib_dir_base;
86 }
87
88 fse.ensureDirSync(out_path_base);
89
90 const helpers = require('./use_require_helpers');
91 const helper = helpers[import_format];
92
93 var handleDir = (js_only, in_path_base, filename) => {
94 const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
95 if(path.extname(filename) !== '.js') {
96 if (!js_only) {
97 console.log(`Writing ${out_path}`);
98 fse.copy(filename, out_path, (err) => { if (err) throw err; });
ae510306 99 }
6cae7b58 100 return; // skip non-javascript files
ae510306 101 }
ae510306 102
6cae7b58
SR
103 fse.ensureDir(path.dirname(out_path), () => {
104 const opts = babel_opts();
105 if (helper && helpers.optionsOverride) {
106 helper.optionsOverride(opts);
107 }
108 babel.transformFile(filename, babel_opts(), (err, res) => {
109 console.log(`Writing ${out_path}`);
110 if (err) throw err;
111 var {code, map, ast} = res;
112 if (source_maps === true) {
113 // append URL for external source map
114 code += `\n//# sourceMappingURL=${path.basename(out_path)}.map\n`;
115 }
116 fs.writeFile(out_path, code, (err) => { if (err) throw err; });
117 if (source_maps === true || source_maps === 'both') {
118 console.log(` and ${out_path}.map`);
119 fs.writeFile(`${out_path}.map`, JSON.stringify(map), (err) => { if (err) throw err; });
120 }
121 });
122 });
123 };
124
125 walkDir(core_path, handleDir.bind(null, true, in_path || core_path));
126 walkDir(vendor_path, handleDir.bind(null, true, in_path || main_path));
127
128 if (with_app_dir) {
129 walkDir(app_path, handleDir.bind(null, false, in_path || app_path));
130
131 const out_app_path = path.join(out_path_base, 'app.js');
132 if (helper && helper.appWriter) {
133 console.log(`Writing ${out_app_path}`);
134 let out_script = helper.appWriter(out_path_base, out_app_path);
135 transform_html(out_script);
136 } else {
137 console.error(`Unable to generate app for the ${import_format} format!`);
138 }
139 }
ae510306
SR
140};
141
6cae7b58 142make_lib_files(program.as, program.withSourceMaps, program.withApp);