有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

open 打開(kāi)瀏覽器的過(guò)程原理示例解析

 更新時(shí)間:2022年12月25日 11:26:34   作者:codeniu  
這篇文章主要為大家介紹了open 打開(kāi)瀏覽器的過(guò)程原理示例解析,
有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

啟動(dòng)項(xiàng)目時(shí),在本地服務(wù)器啟動(dòng)后會(huì)自動(dòng)幫我們打開(kāi)瀏覽器,程序是如何做到呢?又是哪些代碼在起作用呢?希望通過(guò)本章節(jié)的學(xué)習(xí),達(dá)成如下目標(biāo):

  • 學(xué)習(xí)程序自動(dòng)打開(kāi)瀏覽的原理
  • 學(xué)會(huì)使用 Node.js 強(qiáng)大的 child_process 模塊

源碼地址:sindresorhus/open

npm: open - npm (npmjs.com)

使用

配置 webpack 的 devServer 選項(xiàng):

module.exports = {
  //...
  devServer: {
    open: true,
  },
};

告訴 dev-server 在服務(wù)器啟動(dòng)后打開(kāi)瀏覽器。將其設(shè)置為 true 以打開(kāi)默認(rèn)瀏覽器。

DevServer | webpack

如果你使用的是 ue-cli,則在啟動(dòng)命令后面添加參數(shù) --open

# yarn serve 不會(huì)自動(dòng)打開(kāi)瀏覽器 
yarn serve 
# --open 參數(shù)后會(huì)自動(dòng)打開(kāi)瀏覽器 
yarn serve --open

open

無(wú)論是webpack還是vue-cli,他們能夠?qū)崿F(xiàn)在瀏覽器中打開(kāi)網(wǎng)頁(yè)的功能,主要依賴 open 這個(gè)包。

看一下他的 slogan :

Open stuff like URLs, files, executables. Cross-platform.

打開(kāi)像 URL、文件、可執(zhí)行文件之類的東西。跨平臺(tái)。

它有以下優(yōu)點(diǎn):

  • 這個(gè)倉(cāng)庫(kù)更新維護(hù)及時(shí)
  • 豐富的參數(shù)
  • 安全性
  • 解決了大多數(shù) node-open 產(chǎn)生的問(wèn)題
  • 跨平臺(tái)

得益于以上優(yōu)點(diǎn),這個(gè)包每周有兩千多萬(wàn)的下載量:

open 的實(shí)現(xiàn)原理

入口文件:

定位到 open 函數(shù):

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

可以看到核心實(shí)現(xiàn)邏輯在 baseOpen 函數(shù):

const path = require('path');
const childProcess = require('child_process');
const {promises: fs, constants: fsConstants} = require('fs');
const {platform, arch} = process;
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';
		if (options.wait) {
			cliArguments.push('--wait-apps');
		}
                // ...省略一些判斷,
	} else if (platform === 'win32' || (isWsl && !isDocker())) {
		const mountPoint = await getWslDrivesMountPoint();
		command = isWsl ?
			`${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` :
			`${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
		cliArguments.push(
			'-NoProfile',
			'-NonInteractive',
			'–ExecutionPolicy',
			'Bypass',
			'-EncodedCommand'
		);
		if (app) {
			// Double quote with double quotes to ensure the inner quotes are passed through.
			// Inner quotes are delimited for PowerShell interpretation with backticks.
			encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList');
			if (options.target) {
				appArguments.unshift(options.target);
			}
		} else if (options.target) {
			encodedArguments.push(`"${options.target}"`);
		}
		if (appArguments.length > 0) {
			appArguments = appArguments.map(arg => `"\`"${arg}\`""`);
			encodedArguments.push(appArguments.join(','));
		}
		// Using Base64-encoded command, accepted by PowerShell, to allow special characters.
		options.target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
	} else {
           // ...省略 其他情況
	}
	if (options.target) {
		cliArguments.push(options.target);
	}
	if (platform === 'darwin' && appArguments.length > 0) {
		cliArguments.push('--args', ...appArguments);
	}
	const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
	if (options.wait) {
		return new Promise((resolve, reject) => {
			subprocess.once('error', reject);
			subprocess.once('close', exitCode => {
				if (options.allowNonzeroExitCode && exitCode > 0) {
					reject(new Error(`Exited with code ${exitCode}`));
					return;
				}
				resolve(subprocess);
			});
		});
	}
	subprocess.unref();
	return subprocess;
};

首先程序,使用 Node.js 中的 process.platform 屬性來(lái)獲取當(dāng)前操作系統(tǒng)平臺(tái)的值。字符串 'darwin' 用于標(biāo)識(shí) macOS。'win32' 則表示 windows操作系統(tǒng)了。

對(duì)不同操作系統(tǒng)進(jìn)行不同的參數(shù)組織:

  • macos : 根據(jù) options 中的參數(shù)一一添加到 cliArguments 變量中
  • windows: 主要是獲取powershell程序的路徑。
    • wsl:根據(jù)子系統(tǒng)掛載點(diǎn)路徑獲取
    • win:根據(jù) process.env.SYSTEMROOT 獲取操作系統(tǒng)的根路徑

process.env.SYSTEMROOT 是一個(gè)由 Node.js 提供的全局變量,表示當(dāng)前系統(tǒng)的根目錄的路徑。 在 Windows 操作系統(tǒng)中,根目錄通常是 C:\Windows。在其他操作系統(tǒng)中,此變量的值可能為空或不存在。

之后使用 Node.js child_process 模塊中的 childProcess.spawn 函數(shù),以啟動(dòng)新的子進(jìn)程并執(zhí)行命令。

它將 commandcliArguments 變量作為參數(shù)傳遞給 childProcess.spawn,以及一個(gè)名為 childProcessOptions 的對(duì)象,該對(duì)象包含子進(jìn)程的選項(xiàng)。

childProcess.spawn 函數(shù)返回一個(gè)表示已生成子進(jìn)程的 ChildProcess 對(duì)象。如果 options.wait 屬性為 true,則代碼會(huì)返回一個(gè)新的 Promise,該P(yáng)romise 對(duì)象根據(jù)子進(jìn)程的回調(diào)函數(shù)做出reject或者resolve回應(yīng)。

兩個(gè)事件:

  • 'error' 事件偵聽(tīng) 器會(huì)監(jiān)控到發(fā)生的錯(cuò)誤,reject.
  • 'close' 事件偵聽(tīng) 器會(huì)在退出代碼為零(或 options.allowNonzeroExitCode 屬性為 true)時(shí)使用 subprocess 對(duì)象解析承諾。如果退出代碼為非零且 options.allowNonzeroExitCode 屬性為 false,則 reject('錯(cuò)誤代碼')

最后使用 subprocess.unref 方法保持子進(jìn)程運(yùn)行,目的是為了使子進(jìn)程在后臺(tái)運(yùn)行。

總結(jié)

總的來(lái)說(shuō),open原理是:針對(duì)不同的系統(tǒng),使用Node.js的子進(jìn)程 child_process 模塊的spawn方法,調(diào)用系統(tǒng)的命令打開(kāi)瀏覽器。

通過(guò)本章節(jié)課程的學(xué)習(xí),學(xué)習(xí)到了如何使用 nodejs 的內(nèi)置模塊對(duì)操作系統(tǒng)類型的判斷以及childProcess創(chuàng)建子進(jìn)程的方式,更多關(guān)于open打開(kāi)瀏覽器原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論