每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!
1. 前言
大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行三个月了,大家一起交流学习,共同进步。
想学源码,极力推荐之前我写的《学习源码整体架构系列》 包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue-next-release
、vue-this
、create-vue
、玩具vite
等10余篇源码文章。
本文仓库 open-analysis,求个star^_^[1]
最近组织了源码共读活动,大家一起学习源码。于是搜寻各种值得我们学习,且代码行数不多的源码。
我们经常遇到类似场景:每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器。当然你也可能没有碰到过,但可能有这样的需求。而源码300行左右,核心源码不到100行。跟我们工作息息相关,非常值得我们学习。
之前写过据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘,也是跟本文类似原理。
阅读本文,你将学到:
1. 电脑竟然乖乖的帮我打开了浏览器原理和源码实现
2. 学会使用 Node.js 强大的 child_process 模块
3. 学会调试学习源码
4. 等等
2. 使用
2.1 在 webpack 中使用
devServer.open[2]
告诉 dev-server[3] 在服务器启动后打开浏览器。将其设置为 true 以打开您的默认浏览器。
webpack.config.js
module.exports = {//...devServer: {open: true,},
};
Usage via the CLI:
npx webpack serve --open
To disable:
npx webpack serve --no-open
现在大多数都不是直接用 webpack
配置了。而是使用脚手架。那么接着来看我们熟悉的脚手架中,打开浏览器的功能是怎么使用的。
2.2 在 vue-cli 使用
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 使用
npx create-react-app react-project
# 我的 open-analysis 项目中 react-project 文件夹
# npm i -g yarn
# 默认自动打开了浏览器
yarn start
终端我用的是 window terminal
,推荐我之前的文章:使用 ohmyzsh 打造 windows、ubuntu、mac 系统高效终端命令行工具,用过都说好。
webpack
、vue-cli
和create-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
积极维护。
支持应用参数。
更安全,因为它使用 spawn 而不是 exec。
修复了大多数 node-open 的问题。
包括适用于 Linux 的最新 xdg-open 脚本。
支持 Windows 应用程序的 WSL 路径。
一句话概括open
原理则是:针对不同的系统,使用Node.js
的子进程 child_process
模块的spawn
方法,调用系统的命令打开浏览器。
对应的系统命令简单形式则是:
# 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. 阅读源码前的准备工作
# 推荐克隆我的项目,保证与文章同步,同时测试文件齐全
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
。文件内容如下:
// open-analysis/examples/index.js
(async () => {const open = require('../open/index.js');await open('https://lxchuan12.gitee.io');
})();
在 await open('https://lxchuan12.gitee.io');
打上断点。在终端命令行中执行
node examples/index.js
会自动唤起调试模式。如果不支持先阅读这个官方文档配置:Node.js debugging in VS Code[19],如果还是不行,可以升级到最新版VSCode
试试。
跟着调试我们可以进入 open
函数。
4.2 open 打开函数
// 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 基础打开函数
// 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
方法,调用系统的命令打开浏览器。
对应的系统命令简单形式则是:
# 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
方法,调用系统的命令打开浏览器。
本文从日常常见的场景每次启动服务就能自动打开浏览器出发,先讲述了日常在webpack
、vue-cli
、create-react-app
如何使用该功能,最后从源码层面解读了open[20]的原理和源码实现。工作常用的知识能做到知其然,知其所以然,就比很多人厉害了。
因为文章不宜过长,所以未全面展开讲述源码中所有细节。非常建议读者朋友按照文中方法使用VSCode
调试 open
源码。学会调试源码后,源码并没有想象中的那么难。
最后可以持续关注我@若川。欢迎加我微信 ruochuan12 交流,参与 源码共读 活动,大家一起学习源码,共同进步。
参考资料
[1]
本文仓库 open-analysis,求个star^_^: https://github.com/lxchuan12/open-analysis.git
[2]
更多参考资料可以点击阅读原文查看
最近组建了一个江西人的前端交流群,如果你是江西人可以加我微信 ruochuan12 私信 江西 拉你进群。
推荐阅读
1个月,200+人,一起读了4周源码
我历时3年才写了10余篇源码文章,但收获了100w+阅读
老姚浅谈:怎么学JavaScript?
我在阿里招前端,该怎么帮你(可进面试群)
················· 若川简介 ·················
你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》10余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动,帮助1000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。
识别上方二维码加我微信、拉你进源码共读群
今日话题
略。欢迎分享、收藏、点赞、在看我的公众号文章~
每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!相关推荐
- C语言项目:别踩白块游戏(双人版),450行源码分享+详细思路
每天一个C语言小项目,提升你的编程能力! <别踩白块儿>是一款非常耐玩的休闲益智游戏,就像它的名字一样,别踩白块儿,这就是这个游戏的一个规则. 我们只需要不断踩着黑色方块前进即可,很简单吧 ...
- Manjaro启动项目及服务配置备忘
Manjaro启动项目及服务配置备忘 =============== 系统服务GUI管理 搜索 systemdgenie 并安装,类似Windows的服务管理. ================ 系统 ...
- java河南省农村多元化养老服务管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
java河南省农村多元化养老服务管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 java河南省农村多元化养老服务管理系统设计与实现计算机毕业设计MyBatis+系统+L ...
- 【爬虫实战项目】Python爬虫批量下载音乐飙升榜并保存本地(附源码)
前言 今天给大家介绍的是Python爬虫批量下载音乐飙升榜并保存本地,在这里给需要的小伙伴们代码,并且给出一点小心得. 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫,基本的是加请求头,但是 ...
- 服务网关zuul之二:过滤器--请求过滤执行过程(源码分析)
Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求. 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生成 ...
- 【爬虫实战项目】Python爬虫批量旅游景点信息数据并保存本地(附源码)
前言 今天给大家介绍的是Python爬虫批量下载旅游景点信息数据,在这里给需要的小伙伴们代码,并且给出一点小心得. 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫,基本的是加请求头,但是这样 ...
- Android小项目之--前台界面与用户交互的对接 进度条与拖动条(附源码)
都知道水果公司(苹果)是己尊重用户体验著称的公司,其设计的产品人性化十足,不得不令后来者赞叹,竞相模仿.iphone的成功就是其典型的案例,做为其移动系统的死对头 Google 想要在市场上分得一杯羹 ...
- SpringCloud微服务注册中心如何承载大型系统的千万级访问?源码及原理分析
2019独角兽企业重金招聘Python工程师标准>>> 问题起源 Spring Cloud架构体系中,Eureka是一个至关重要的组件,它扮演着微服务注册中心的角色,所有的服 ...
- [转]Asp.Net大型项目实践(11)-基于MVC Action粒度的权限管理【续】【源码在这里】(在线demo,全部源码)...
本文转自:http://www.cnblogs.com/legendxian/archive/2010/01/25/1655551.html 接上篇Asp.Net大型项目实践(10)-基于MVC Ac ...
最新文章
- 计算机视觉与深度学习 | 使用K均值聚类实现基于颜色的分割(matlab版)
- ITK:计算图像的绝对值
- [Android] 给图像添加相框、圆形圆角显示图片、图像合成知识
- 201621123003《Java程序设计》第一周学习总结
- R中数据结构与数据的输入
- jdbc防止sql注入-PreparedStatement
- ASP.NET MVC 重点教程一周年版 第三回 Controller与View
- 如何将华为备忘录转移到小米便签
- spring cloud SnakeYAML RCE 漏洞复现
- 记一次quartz定时任务不执行排雷
- Python绘制地理图--Cartopy基础
- java同一秒请求多次接口_java – 限制用户每秒发出有限的请求
- 20个用户看了每天都想打开app的登录页面模板
- 关于DBSCAN图像上小圆圈和大圆圈的问题
- IDS入侵检测系统与开源IDS-snort的安装与编写规则
- php 文件头部(header)信息详解
- Savitzky-Golay滤波器原理阐述
- 计算机音乐数字乐谱桃源恋歌,桃源恋歌钢琴简谱-数字双手-Miume・MARiA・217
- 将北斗卫星授时(GPS时钟系统)技术应用数据采集系统
- pandas删除含有空值的行