【若川视野 x 源码共读】第13期 | open 打开浏览器

262 阅读1分钟

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

测试用例

(async () => {
    const open = require('../index');
    await open('https://lxchuan12.gitee.io');
})();

部分源码

open方法内调用baseOpen方法

// 传入一个地址,和其他配置
const open = (target, options) => {
    if (typeof target !== 'string') {
        throw new TypeError('Expected a `target`');
    }
    return baseOpen({
        ...options,
        target
    });
};
const baseOpen = async options => {
    options = {  // 设置一些默认值
        wait: false,
        background: false,
        newInstance: false,
        allowNonzeroExitCode: false,
        ...options
    };
    let command;
    const cliArguments = [];  // 在这里面根据不同环境判断,会塞进去不同的命令。
    const childProcessOptions = {};
    //...传了其他参数做了一些处理,忽略...有兴趣可以去看源码
    if (platform === 'darwin') {
        command = 'open';
        // 如果是mac...传了一些options然后做了一些处理
    } else if (platform === 'win32' || (isWsl && !isDocker())) {
    // const isWsl = require('is-wsl');  判断是否是win中的linux环境
    // const isDocker = require('is-docker');  判断是否是docker环境
    command = isWsl ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` :`${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
        // 如果是win...处理
    } else {
        command = 'xdg-open';
        // 如果是其他...处理
    }
    // 这个就是都需要的命令,放外面处理。target就是传入的url
    if (options.target) {
       cliArguments.push(options.target);
    }
    // 调用childProcess.spawn,传入已经整理好的参数。
    const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
    subprocess.unref();

    return subprocess;
}

总结

不同系统终端打开方式

mac: open https://www.baidu.com
win: start https://www.baidu.com
其他: xdg-open https://www.baidu.com

child_process.spawn

nodejs.cn/api/child_p…

subprocess

nodejs.cn/api/child_p…

const { spawn } = require('child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore'  // 这里要设置成忽略
});

subprocess.unref(); // 允许父进程独立于子进程退出

参考文档

据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘