2017-06-20 23:18:46 +00:00
|
|
|
/* global onmessage: true, postMessage: false */
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const fs = require('fs-extra');
|
|
|
|
const path = require('path');
|
2019-03-22 00:05:07 +00:00
|
|
|
const babel = require('@babel/core');
|
2017-06-20 23:18:46 +00:00
|
|
|
const multimatch = require('multimatch');
|
|
|
|
const options = JSON.parse(fs.readFileSync('.babelrc'));
|
|
|
|
const cluster = require('cluster');
|
2020-07-28 17:02:08 +00:00
|
|
|
const { comparePaths } = require('./utils');
|
2017-06-20 23:18:46 +00:00
|
|
|
|
|
|
|
/* exported onmessage */
|
|
|
|
async function babelWorker(ev) {
|
|
|
|
const t1 = Date.now();
|
|
|
|
const sourcefile = ev.file;
|
2019-03-22 00:05:07 +00:00
|
|
|
const localOptions = {
|
|
|
|
filename: sourcefile
|
|
|
|
};
|
2017-05-22 23:10:03 +00:00
|
|
|
const outfile = path.join('build', sourcefile.replace('.jsx', '.js'));
|
2017-06-20 23:18:46 +00:00
|
|
|
const postError = (error) => {
|
|
|
|
process.send({
|
|
|
|
sourcefile,
|
|
|
|
outfile,
|
|
|
|
error
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var isSkipped = false;
|
|
|
|
var transformed;
|
|
|
|
|
|
|
|
try {
|
|
|
|
let contents = await fs.readFile(sourcefile, 'utf8');
|
2019-03-28 09:19:41 +00:00
|
|
|
// Patch react
|
2020-07-28 17:02:08 +00:00
|
|
|
if (comparePaths(sourcefile, 'resource/react.js')) {
|
2018-12-12 10:34:39 +00:00
|
|
|
transformed = contents.replace('instanceof Error', '.constructor.name == "Error"')
|
2019-03-28 09:19:41 +00:00
|
|
|
}
|
|
|
|
// Patch react-dom
|
2020-07-28 17:02:08 +00:00
|
|
|
else if (comparePaths(sourcefile, 'resource/react-dom.js')) {
|
2018-12-12 10:34:39 +00:00
|
|
|
transformed = contents.replace(/ ownerDocument\.createElement\((.*?)\)/gi, 'ownerDocument.createElementNS(HTML_NAMESPACE, $1)')
|
|
|
|
.replace('element instanceof win.HTMLIFrameElement',
|
|
|
|
'typeof element != "undefined" && element.tagName.toLowerCase() == "iframe"')
|
2017-05-22 23:10:03 +00:00
|
|
|
.replace("isInputEventSupported = false", 'isInputEventSupported = true');
|
2019-03-28 09:19:41 +00:00
|
|
|
}
|
|
|
|
// Patch react-virtualized
|
2020-07-28 17:02:08 +00:00
|
|
|
else if (comparePaths(sourcefile, 'resource/react-virtualized.js')) {
|
2019-03-28 09:19:41 +00:00
|
|
|
transformed = contents.replace('scrollDiv = document.createElement("div")', 'scrollDiv = document.createElementNS("http://www.w3.org/1999/xhtml", "div")')
|
|
|
|
.replace('document.body.appendChild(scrollDiv)', 'document.documentElement.appendChild(scrollDiv)')
|
|
|
|
.replace('document.body.removeChild(scrollDiv)', 'document.documentElement.removeChild(scrollDiv)');
|
|
|
|
}
|
2020-07-17 22:14:10 +00:00
|
|
|
|
|
|
|
// Patch single-file
|
2020-10-23 23:39:07 +00:00
|
|
|
else if (sourcefile === 'resource/SingleFile/lib/single-file/single-file.js') {
|
2020-07-17 22:14:10 +00:00
|
|
|
// We need to add this bit that is done for the cli implementation of singleFile
|
|
|
|
// See resource/SingleFile/cli/back-ends/common/scripts.js
|
|
|
|
const WEB_SCRIPTS = [
|
|
|
|
"lib/single-file/processors/hooks/content/content-hooks-web.js",
|
|
|
|
"lib/single-file/processors/hooks/content/content-hooks-frames-web.js"
|
|
|
|
];
|
2020-10-23 23:39:07 +00:00
|
|
|
let basePath = 'resource/SingleFile/';
|
2020-07-17 22:14:10 +00:00
|
|
|
|
|
|
|
function readScriptFile(path, basePath) {
|
|
|
|
return new Promise((resolve, reject) =>
|
|
|
|
fs.readFile(basePath + path, (err, data) => {
|
|
|
|
if (err) {
|
|
|
|
reject(err);
|
|
|
|
} else {
|
|
|
|
resolve(data.toString() + "\n");
|
|
|
|
}
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const webScripts = {};
|
|
|
|
await Promise.all(
|
|
|
|
WEB_SCRIPTS.map(async path => webScripts[path] = await readScriptFile(path, basePath))
|
|
|
|
);
|
|
|
|
|
|
|
|
transformed = contents + '\n\n'
|
|
|
|
+ "this.singlefile.lib.getFileContent = filename => (" + JSON.stringify(webScripts) + ")[filename];\n";
|
|
|
|
}
|
|
|
|
|
2019-03-28 09:19:41 +00:00
|
|
|
else if ('ignore' in options && options.ignore.some(ignoreGlob => multimatch(sourcefile, ignoreGlob).length)) {
|
2017-06-20 23:18:46 +00:00
|
|
|
transformed = contents;
|
|
|
|
isSkipped = true;
|
|
|
|
} else {
|
|
|
|
try {
|
2019-03-22 00:05:07 +00:00
|
|
|
({ code: transformed } = await babel.transformAsync(
|
|
|
|
contents,
|
|
|
|
Object.assign(
|
|
|
|
localOptions,
|
|
|
|
options
|
|
|
|
)
|
|
|
|
));
|
2017-06-20 23:18:46 +00:00
|
|
|
} catch (error) { return postError(`Babel error: ${error}`);}
|
|
|
|
}
|
|
|
|
|
|
|
|
await fs.outputFile(outfile, transformed);
|
|
|
|
const t2 = Date.now();
|
|
|
|
process.send({
|
|
|
|
isSkipped,
|
|
|
|
sourcefile,
|
|
|
|
outfile,
|
|
|
|
processingTime: t2 - t1
|
|
|
|
});
|
|
|
|
} catch (error) { return postError(`I/O error: ${error}`); }
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = babelWorker;
|
|
|
|
|
|
|
|
if (cluster.isWorker) {
|
|
|
|
process.on('message', babelWorker);
|
|
|
|
}
|