Use Node.js APIs for ext build script instead of shell commands

This commit is contained in:
hensm
2018-12-06 13:16:20 +00:00
parent b7831f0b3b
commit 0ece4968cf

View File

@@ -1,65 +1,112 @@
const fs = require("fs-extra");
const path = require("path");
const { spawn } = require("child_process");
const minimist = require("minimist");
const webpack = require("webpack");
const webExt = require("web-ext").default;
const DIST_PATH = path.join(__dirname, "../dist/ext");
const UNPACKED_PATH = path.join(DIST_PATH, "unpacked");
const argv = minimist(process.argv.slice(2), {
boolean: [ "package", "watch" ]
, string: [ "mirroringAppId", "mode" ]
, default: {
package: false
, watch: false
, mirroringAppId: "19A6F4AE"
, mode: "development"
package: false // Should package with web-ext
, watch: false // Should run webpack in watch mode
, mirroringAppId: "19A6F4AE" // Chromecast mirroring receiver app ID
, mode: "development" // webpack mode
}
});
if (argv.package && argv.watch) {
console.error("Cannot package whilst watching files.");
process.exit(1);
}
// If packaging, use production mode
if (argv.package) {
argv.mode = "production";
argv.watch = false;
}
const extensionName = "fx_cast";
const extensionId = "fx_cast@matt.tf";
const extensionVersion = "0.0.1";
// Import webpack config and specify env values
const webpackConfig = require("./webpack.config.js")({
extensionName: "fx_cast"
, extensionId: "fx_cast@matt.tf"
, extensionVersion: "0.0.1"
, mirroringAppId: argv.mirroringAppId
});
// Add mode to config
webpackConfig.mode = argv.mode;
/**
* If watching files, output directly to dist. Unpacked
* directory is used as a staging area for web-ext builds.
*/
webpackConfig.output.path = argv.package
? UNPACKED_PATH
: DIST_PATH;
const DIST_PATH = path.join(__dirname, "../dist/ext");
const UNPACKED_PATH = path.join(DIST_PATH, "unpacked");
// Clean
fs.removeSync(DIST_PATH);
const buildCmd = `web-ext build --overwrite-dest `
+ `--source-dir ${UNPACKED_PATH} `
+ `--artifacts-dir ${DIST_PATH} `;
const child = spawn(
`webpack --env.extensionName=${extensionName} `
+ `--env.extensionId=${extensionId} `
+ `--env.extensionVersion=${extensionVersion} `
+ `--env.mirroringAppId=${argv.mirroringAppId} `
+ `--mode=${argv.mode} `
+ `${argv.watch ? "--watch" : ""} `
+ `${argv.package ? "&&" + buildCmd : ""} `
, { shell: true }
);
// Create webpack compiler instance
const compiler = webpack(webpackConfig);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
if (argv.watch) {
// Start webpack watch
compiler.watch({}, handleCompilerOutput);
} else {
compiler.run((...args) => {
handleCompilerOutput(...args);
child.on("exit", () => {
if (argv.package) {
fs.remove(UNPACKED_PATH);
} else {
for (const file of fs.readdirSync(UNPACKED_PATH)) {
fs.moveSync(path.join(UNPACKED_PATH, file)
, path.join(DIST_PATH, file)
, { overwrite: true });
if (argv.package) {
webExt.cmd.build({
/**
* Webpack output at sourceDir is built into an extension
* archive at artifactsDir.
*/
sourceDir: UNPACKED_PATH
, artifactsDir: DIST_PATH
, overwriteDest: true
}, {
// Prevent auto-exit
shouldExitProgram: false
}).then(() => {
// Only need the built extension archive
fs.remove(UNPACKED_PATH);
})
}
});
}
/**
* Log errors and output formatted compilation info.
*/
function handleCompilerOutput (err, stats) {
// If there are fatal errors, log and exit
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
// Remove empty unpacked directory
fs.remove(UNPACKED_PATH);
return;
}
});
// Get compilation info
const info = stats.toJson();
// Log errors/warnings
if (stats.hasErrors()) console.error(info.errors);
if (stats.hasWarnings()) console.warn(info.warnings);
// Log formatted output
console.log(stats.toString());
}