前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!

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

作者头像
若川
发布2021-11-10 16:49:00
5340
发布2021-11-10 16:49:00
举报
文章被收录于专栏:若川视野若川视野

1. 前言

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行三个月了,大家一起交流学习,共同进步。

想学源码,极力推荐之前我写的《学习源码整体架构系列》 包含jQueryunderscorelodashvuexsentryaxiosreduxkoavue-devtoolsvuex4koa-composevue-next-releasevue-thiscreate-vue玩具vite等10余篇源码文章。

本文仓库 open-analysis,求个star^_^[1]

最近组织了源码共读活动,大家一起学习源码。于是搜寻各种值得我们学习,且代码行数不多的源码。

我们经常遇到类似场景:每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器。当然你也可能没有碰到过,但可能有这样的需求。而源码300行左右,核心源码不到100行。跟我们工作息息相关,非常值得我们学习。

之前写过据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘,也是跟本文类似原理。

阅读本文,你将学到:

代码语言:javascript
复制
1. 电脑竟然乖乖的帮我打开了浏览器原理和源码实现
2. 学会使用 Node.js 强大的 child_process 模块
3. 学会调试学习源码
4. 等等

2. 使用

2.1 在 webpack 中使用

devServer.open[2]

告诉 dev-server[3] 在服务器启动后打开浏览器。将其设置为 true 以打开您的默认浏览器。

webpack.config.js

代码语言:javascript
复制
module.exports = {
  //...
  devServer: {
    open: true,
  },
};

Usage via the CLI:

代码语言:javascript
复制
npx webpack serve --open

To disable:

代码语言:javascript
复制
npx webpack serve --no-open

现在大多数都不是直接用 webpack 配置了。而是使用脚手架。那么接着来看我们熟悉的脚手架中,打开浏览器的功能是怎么使用的。

2.2 在 vue-cli 使用

代码语言:javascript
复制
npx @vue/cli create vue3-project
# 我的 open-analysis 项目中 vue3-project 文件夹
# npm i -g yarn
# yarn serve 不会自动打开浏览器
yarn serve
# --open 参数后会自动打开浏览器
yarn serve --open

2.3 在 create-react-app 使用

代码语言:javascript
复制
npx create-react-app react-project
# 我的 open-analysis 项目中 react-project 文件夹
# npm i -g yarn
# 默认自动打开了浏览器
yarn start

为此我截了图

终端我用的是 window terminal,推荐我之前的文章:使用 ohmyzsh 打造 windows、ubuntu、mac 系统高效终端命令行工具,用过都说好。

webpackvue-clicreate-react-app,它们三者都有个特点就是不约而同的使用了open[4]

引用 open 分别的代码位置是:

  • webpack-dev-server[5]
  • vue-cli[6]
  • create-react-app[7]

接着我们来学习open原理和源码。

3. 原理

npm 之王 @sindresorhus[8]open README文档[9]中,英文描述中写了为什么使用它的几条原因。

为什么推荐使用 open

代码语言:javascript
复制
积极维护。
支持应用参数。
更安全,因为它使用 spawn 而不是 exec。
修复了大多数 node-open 的问题。
包括适用于 Linux 的最新 xdg-open 脚本。
支持 Windows 应用程序的 WSL 路径。

一句话概括open原理则是:针对不同的系统,使用Node.js的子进程 child_process 模块的spawn方法,调用系统的命令打开浏览器。

对应的系统命令简单形式则是:

代码语言:javascript
复制
# mac
open https://lxchuan12.gitee.io
# win
start https://lxchuan12.gitee.io
# linux
xdg-open https://lxchuan12.gitee.io

windows start 文档[10]

open包描述信息:open[11]

在这里可以看到有哪些 npm 包依赖了 open[12]

我们熟悉的很多 npm 包都依赖了open。这里列举几个。

  • webpack-dev-server[13]
  • react-dev-utils[14]
  • @vue/cli-shared-utils[15]
  • patch-package[16]
  • lighthouse[17]
  • release-it[18]

4. 阅读源码前的准备工作

代码语言:javascript
复制
# 推荐克隆我的项目,保证与文章同步,同时测试文件齐全
git clone https://github.com/lxchuan12/open-analysis.git
# npm i -g yarn
cd open && yarn

# 或者克隆官方项目
git clone https://github.com/sindresorhus/open.git
# npm i -g yarn
cd open && yarn

4.1 写个例子,便于调试源码

由于测试用例相对较为复杂,我们自己动手写个简单的例子,便于我们自己调试。

根据 README,我们在 open-analysis 文件夹下新建一个文件夹 examples ,里面存放一个 index.js。文件内容如下:

代码语言:javascript
复制
// open-analysis/examples/index.js
(async () => {
    const open = require('../open/index.js');
    await open('https://lxchuan12.gitee.io');
})();

await open('https://lxchuan12.gitee.io'); 打上断点。在终端命令行中执行

代码语言:javascript
复制
node examples/index.js

会自动唤起调试模式。如果不支持先阅读这个官方文档配置:Node.js debugging in VS Code[19],如果还是不行,可以升级到最新版VSCode试试。

跟着调试我们可以进入 open 函数。

调试

VSCode 调试 Node.js 说明

4.2 open 打开函数

代码语言:javascript
复制
// open/index.js
const open = (target, options) => {
 if (typeof target !== 'string') {
  throw new TypeError('Expected a `target`');
 }

 return baseOpen({
  ...options,
  target
 });
};

跟着断点,我们来看最终调用的 baseOpen。这个函数比较长,重点可以猜到是:const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);这句,我们可以打上断点调试。

4.3 baseOpen 基础打开函数

代码语言:javascript
复制
// open/index.js
const childProcess = require('child_process');
const localXdgOpenPath = path.join(__dirname, 'xdg-open');

const {platform, arch} = process;
// 调试时我们可以自行调整修改平台,便于调试各个平台异同,比如 mac、win、linux
// const {arch} = process;
// mac
// const platform = 'darwin';
// win
// const platform = 'win32';
// const platform = '其他';

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 部分代码
    } else if (platform === 'win32' || (isWsl && !isDocker())) {
        // 省略 window 或者 window 子系统代码
        const encodedArguments = ['Start'];
    } else {
        const useSystemXdgOpen = process.versions.electron ||
            platform === 'android' || isBundled || !exeLocalXdgOpen;
        command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
        // 省略 linux 代码
    }
    // 省略部分代码
    const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
    
    // 省略部分代码
    subprocess.unref();

 return subprocess;
}

由此我们可以看出:

一句话概括open原理则是:针对不同的系统,使用Node.js的子进程 child_process 模块的spawn方法,调用系统的命令打开浏览器。

对应的系统命令简单形式则是:

代码语言:javascript
复制
# mac
open https://lxchuan12.gitee.io
# win
start https://lxchuan12.gitee.io
# linux
xdg-open https://lxchuan12.gitee.io

5. 总结

一句话概括open原理则是:针对不同的系统,使用Node.js的子进程 child_process 模块的spawn方法,调用系统的命令打开浏览器。

本文从日常常见的场景每次启动服务就能自动打开浏览器出发,先讲述了日常在webpackvue-clicreate-react-app如何使用该功能,最后从源码层面解读了open[20]的原理和源码实现。工作常用的知识能做到知其然,知其所以然,就比很多人厉害了。

因为文章不宜过长,所以未全面展开讲述源码中所有细节。非常建议读者朋友按照文中方法使用VSCode调试 open 源码。学会调试源码后,源码并没有想象中的那么难

最后可以持续关注我@若川。欢迎加我微信 ruochuan12 交流,参与 源码共读 活动,大家一起学习源码,共同进步。

参考资料

[1]

本文仓库 open-analysis,求个star^_^: https://github.com/lxchuan12/open-analysis.git

[2]

更多参考资料可以点击阅读原文查看

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 若川视野 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. 使用
    • 2.1 在 webpack 中使用
      • 2.2 在 vue-cli 使用
        • 2.3 在 create-react-app 使用
        • 3. 原理
        • 4. 阅读源码前的准备工作
          • 4.1 写个例子,便于调试源码
            • 4.2 open 打开函数
              • 4.3 baseOpen 基础打开函数
              • 5. 总结
                • 参考资料
                相关产品与服务
                命令行工具
                腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档