@aniyajs/rotor
Version:
基于webpack5开发的一款专注于打包、运行的工具
141 lines (126 loc) • 4.37 kB
JavaScript
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var chalk = require("chalk");
var execSync = require("child_process").execSync;
var spawn = require("cross-spawn");
var open = require("open");
// https://github.com/sindresorhus/open#app
var OSX_CHROME = "google chrome";
const Actions = Object.freeze({
NONE: 0,
BROWSER: 1,
SCRIPT: 2,
});
function getBrowserEnv() {
// 尝试遵守此环境变量。
// 它特定于操作系统。
// 有关文档,请参阅 https://github.com/sindresorhus/open#app。
const value = undefined;
const args = [];
let action = Actions.BROWSER;
return { action, value, args };
}
function executeNodeScript(scriptPath, url) {
const extraArgs = process.argv.slice(2);
const child = spawn(process.execPath, [scriptPath, ...extraArgs, url], {
stdio: "inherit",
});
child.on("close", (code) => {
if (code !== 0) {
console.log();
console.log(chalk.red("指定为 BROWSER 环境变量的脚本失败。"));
console.log(chalk.cyan(scriptPath) + "退出代码" + code + ".");
console.log();
return false;
}
});
return true;
}
function startBrowserProcess(browser, url, args) {
// 如果我们在 OS X 上,用户没有明确
// 请求不同的浏览器,我们可以尝试打开
// 带有 AppleScript 的 Chrome。这让我们重用一个
// 尽可能使用现有选项卡而不是创建新选项卡。
const shouldTryOpenChromiumWithAppleScript =
process.platform === "darwin" &&
(typeof browser !== "string" || browser === OSX_CHROME);
if (shouldTryOpenChromiumWithAppleScript) {
// 将使用从列表中找到的第一个打开的浏览器
const supportedChromiumBrowsers = [
"Google Chrome Canary",
"Google Chrome",
"Microsoft Edge",
"Brave Browser",
"Vivaldi",
"Chromium",
];
for (let chromiumBrowser of supportedChromiumBrowsers) {
try {
// 尽量重用现有的选项卡
// 在基于 OSX Chromium 的浏览器上使用 AppleScript
// eslint-disable-next-line quotes
execSync('ps cax | grep "' + chromiumBrowser + '"');
execSync(
// eslint-disable-next-line quotes
'osascript openChrome.applescript "' +
encodeURI(url) +
// eslint-disable-next-line quotes
'" "' +
chromiumBrowser +
// eslint-disable-next-line quotes
'"',
{
cwd: __dirname,
stdio: "ignore",
},
);
return true;
} catch (err) {
// 忽略错误。
}
}
}
// 另一种特殊情况:在 OS X 上,检查 BROWSER 是否已设置为“打开”。
// 在这种情况下,不是将 `open` 传递给 `opn`(这是行不通的),
// 忽略它(从而确保预期的行为,即打开系统浏览器):
// https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768
if (process.platform === "darwin" && browser === "open") {
browser = undefined;
}
// 如果有参数,它们必须作为数组传递给浏览器
if (typeof browser === "string" && args.length > 0) {
browser = [browser].concat(args);
}
// 回退打开
// (它将始终打开新标签)
try {
const options = { app: browser, wait: false, url: true };
open(url, options).catch(() => {}); // 防止 `unhandledRejection` 错误。
return true;
} catch (err) {
return false;
}
}
/**
* 读取 BROWSER 环境变量并决定如何处理它。退货
* 如果它打开浏览器或运行 node.js 脚本,则为 true,否则为 false。
*/
function openBrowser(url) {
const { action, value, args } = getBrowserEnv();
switch (action) {
case Actions.NONE:
// 特殊情况:BROWSER="none" 将阻止完全打开。
return false;
case Actions.SCRIPT:
return executeNodeScript(value, url);
case Actions.BROWSER:
return startBrowserProcess(value, url, args);
default:
throw new Error("Not implemented.");
}
}
module.exports = openBrowser;