通过 open 打开浏览器

622 阅读2分钟

我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

今天在翻阅源码课程的时候注意到一个我比较感兴趣的东西,open 打开浏览器。于是我便开始学习这个东西的源码。

open

open 的源码部分的 readme 文档里,除了介绍了对它的使用方法以外,我们也可以看到对它的一些描述。

image.png

使用方法我们就不看了,我们直接进入阅读源码部分,来了解它的原理和源码。

image.png

源码笔记

首先我们根据若川大佬的指引先来写一段测试 Demo,如下所示。

image.png

我们打开 index.js 文件,代码是比较多的,我们看关键代码即可。

open

这个是一个 open 打开函数。

const open = (target, options) => {
	if (typeof target !== 'string') {
		throw new TypeError('Expected a `target`');
	}
	return baseOpen({
		...options,
		target
	});
};

openApp

这个是和上次差不多的一个打开函数,只不过这个从字面上理解是打开 App

const openApp = (name, options) => {
    if (typeof name !== 'string') {
        throw new TypeError('Expected a `name`');
    }
    const {arguments: appArguments = []} = options || {};
    if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) {
        throw new TypeError('Expected `appArguments` as Array type');
    }
    return baseOpen({
        ...options,
        app: {
            name,
            arguments: appArguments
        }
    });
};  

baseOpen

很容易看出,函数内部的逻辑并不复杂,但是这两个函数内都调用了 baseOpen 函数,我们来看看 baseOpen 函数是怎么写的。

const baseOpen = async options => {
    options = {
        wait: false,
        background: false,
        newInstance: false,
        allowNonzeroExitCode: false,
        ...options
    };
    ......
    let command;
    const cliArguments = [];
    const childProcessOptions = {};
    ......

image.png

由于代码比较多,所以省略了一部分代码。从代码层面可以看出,对于不同的系统它使用 child_process 模块中的 spawn 方法。对于函数内部,我们还可以注意到使用了 pTryEach 方法。

pTryEach

这个函数的内部逻辑也不难,就是进行了一个简单的遍历。

const pTryEach = async (array, mapper) => {
    let latestError;                                                   
    for (const item of array) {                                        
         try {                                                              
            return await mapper(item);
         } catch (error) {                                                  
             latestError = error;  
         }                                                                  
     }                                                       
    throw latestError;           
};

总结

这次的源码学习起来还是有点吃力的,还是有很多方面没有掌握弄懂。不过没关系,还会继续学习这一部分的,以上就是我学习中的记录及笔记。

最后用若川大佬的一句话来总结一下 open:针对不同的系统,使用Node.js的子进程 child_process 模块的spawn方法,调用系统的命令打开浏览器。

参考文章:每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!