mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Fixes https://github.com/facebook/react/issues/26911, https://github.com/facebook/react/issues/26860. Currently, we are parsing user agent string to determine which browser is running the extension. This doesn't work well with custom user agents, and sometimes when user turns on mobile dev mode in Firefox, we stop resolving that this is a Firefox browser, extension starts to use Chrome API's and fails to inject. Changes: Since we are building different extensions for all supported browsers (Chrome, Firefox, Edge), we predefine env variables for browser resolution, which are populated in a build step.
176 lines
5.5 KiB
JavaScript
176 lines
5.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
const archiver = require('archiver');
|
|
const {execSync} = require('child_process');
|
|
const {readFileSync, writeFileSync, createWriteStream} = require('fs');
|
|
const {copy, ensureDir, move, remove, pathExistsSync} = require('fs-extra');
|
|
const {join, resolve} = require('path');
|
|
const {getGitCommit} = require('./utils');
|
|
|
|
// These files are copied along with Webpack-bundled files
|
|
// to produce the final web extension
|
|
const STATIC_FILES = ['icons', 'popups', 'main.html', 'panel.html'];
|
|
|
|
/**
|
|
* Ensures that a local build of the dependencies exist either by downloading
|
|
* or running a local build via one of the `react-build-fordevtools*` scripts.
|
|
*/
|
|
const ensureLocalBuild = async () => {
|
|
const buildDir = resolve(__dirname, '..', '..', 'build');
|
|
const nodeModulesDir = join(buildDir, 'node_modules');
|
|
|
|
// TODO: remove this check whenever the CI pipeline is complete.
|
|
// See build-all-release-channels.js
|
|
const currentBuildDir = resolve(
|
|
__dirname,
|
|
'..',
|
|
'..',
|
|
'build',
|
|
'oss-experimental',
|
|
);
|
|
|
|
if (pathExistsSync(buildDir)) {
|
|
return; // all good.
|
|
}
|
|
|
|
if (pathExistsSync(currentBuildDir)) {
|
|
await ensureDir(buildDir);
|
|
await copy(currentBuildDir, nodeModulesDir);
|
|
return; // all good.
|
|
}
|
|
|
|
throw Error(
|
|
'Could not find build artifacts in repo root. See README for prerequisites.',
|
|
);
|
|
};
|
|
|
|
const preProcess = async (destinationPath, tempPath) => {
|
|
await remove(destinationPath); // Clean up from previously completed builds
|
|
await remove(tempPath); // Clean up from any previously failed builds
|
|
await ensureDir(tempPath); // Create temp dir for this new build
|
|
};
|
|
|
|
const build = async (tempPath, manifestPath, envExtension = {}) => {
|
|
const binPath = join(tempPath, 'bin');
|
|
const zipPath = join(tempPath, 'zip');
|
|
const mergedEnv = {...process.env, ...envExtension};
|
|
|
|
const webpackPath = join(__dirname, 'node_modules', '.bin', 'webpack');
|
|
execSync(
|
|
`${webpackPath} --config webpack.config.js --output-path ${binPath}`,
|
|
{
|
|
cwd: __dirname,
|
|
env: mergedEnv,
|
|
stdio: 'inherit',
|
|
},
|
|
);
|
|
execSync(
|
|
`${webpackPath} --config webpack.backend.js --output-path ${binPath}`,
|
|
{
|
|
cwd: __dirname,
|
|
env: mergedEnv,
|
|
stdio: 'inherit',
|
|
},
|
|
);
|
|
|
|
// Make temp dir
|
|
await ensureDir(zipPath);
|
|
|
|
const copiedManifestPath = join(zipPath, 'manifest.json');
|
|
|
|
// Copy unbuilt source files to zip dir to be packaged:
|
|
await copy(binPath, join(zipPath, 'build'));
|
|
await copy(manifestPath, copiedManifestPath);
|
|
await Promise.all(
|
|
STATIC_FILES.map(file => copy(join(__dirname, file), join(zipPath, file))),
|
|
);
|
|
|
|
const commit = getGitCommit();
|
|
const dateString = new Date().toLocaleDateString();
|
|
const manifest = JSON.parse(readFileSync(copiedManifestPath).toString());
|
|
const versionDateString = `${manifest.version} (${dateString})`;
|
|
if (manifest.version_name) {
|
|
manifest.version_name = versionDateString;
|
|
}
|
|
manifest.description += `\n\nCreated from revision ${commit} on ${dateString}.`;
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
// When building the local development version of the
|
|
// extension we want to be able to have a stable extension ID
|
|
// for the local build (in order to be able to reliably detect
|
|
// duplicate installations of DevTools).
|
|
// By specifying a key in the built manifest.json file,
|
|
// we can make it so the generated extension ID is stable.
|
|
// For more details see the docs here: https://developer.chrome.com/docs/extensions/mv2/manifest/key/
|
|
manifest.key = 'reactdevtoolslocalbuilduniquekey';
|
|
}
|
|
|
|
writeFileSync(copiedManifestPath, JSON.stringify(manifest, null, 2));
|
|
|
|
// Pack the extension
|
|
const archive = archiver('zip', {zlib: {level: 9}});
|
|
const zipStream = createWriteStream(join(tempPath, 'ReactDevTools.zip'));
|
|
await new Promise((resolvePromise, rejectPromise) => {
|
|
archive
|
|
.directory(zipPath, false)
|
|
.on('error', err => rejectPromise(err))
|
|
.pipe(zipStream);
|
|
archive.finalize();
|
|
zipStream.on('close', () => resolvePromise());
|
|
});
|
|
};
|
|
|
|
const postProcess = async (tempPath, destinationPath) => {
|
|
const unpackedSourcePath = join(tempPath, 'zip');
|
|
const packedSourcePath = join(tempPath, 'ReactDevTools.zip');
|
|
const packedDestPath = join(destinationPath, 'ReactDevTools.zip');
|
|
const unpackedDestPath = join(destinationPath, 'unpacked');
|
|
|
|
await move(unpackedSourcePath, unpackedDestPath); // Copy built files to destination
|
|
await move(packedSourcePath, packedDestPath); // Copy built files to destination
|
|
await remove(tempPath); // Clean up temp directory and files
|
|
};
|
|
|
|
const SUPPORTED_BUILDS = ['chrome', 'firefox', 'edge'];
|
|
|
|
const main = async buildId => {
|
|
if (!SUPPORTED_BUILDS.includes(buildId)) {
|
|
throw new Error(
|
|
`Unexpected build id - "${buildId}". Use one of ${JSON.stringify(
|
|
SUPPORTED_BUILDS,
|
|
)}.`,
|
|
);
|
|
}
|
|
|
|
const root = join(__dirname, buildId);
|
|
const manifestPath = join(root, 'manifest.json');
|
|
const destinationPath = join(root, 'build');
|
|
|
|
const envExtension = {
|
|
IS_CHROME: buildId === 'chrome',
|
|
IS_FIREFOX: buildId === 'firefox',
|
|
IS_EDGE: buildId === 'edge',
|
|
};
|
|
|
|
try {
|
|
const tempPath = join(__dirname, 'build', buildId);
|
|
await ensureLocalBuild();
|
|
await preProcess(destinationPath, tempPath);
|
|
await build(tempPath, manifestPath, envExtension);
|
|
|
|
const builtUnpackedPath = join(destinationPath, 'unpacked');
|
|
await postProcess(tempPath, destinationPath);
|
|
|
|
return builtUnpackedPath;
|
|
} catch (error) {
|
|
console.error(error);
|
|
process.exit(1);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
module.exports = main;
|