-
-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pptr): switched over puppeteer-core to avoid chromium install
Switched over using puppeteer-core to avoid chromium download on every install. With chrome-launcher, lib will first try to locate any Chromium instance that is installed on users system, and only if not found, it will installed preferred chromium revision that is declared on puppeteer-core pkg. fix #50
- Loading branch information
1 parent
9311962
commit 11045a1
Showing
7 changed files
with
232 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import puppeteer, { | ||
Browser, | ||
LaunchOptions, | ||
RevisionInfo, | ||
} from 'puppeteer-core'; | ||
import { | ||
launch, | ||
LaunchedChrome, | ||
Options as ChromeLauncherOptions, | ||
} from 'chrome-launcher'; | ||
import { get } from 'http'; | ||
import constants from '../config/constants'; | ||
import installer from './installer'; | ||
|
||
interface BrowserVersionInfo { | ||
Browser: string; | ||
webSocketDebuggerUrl: string; | ||
'Protocol-Version': string; | ||
'User-Agent': string; | ||
'V8-Version': string; | ||
'Webkit-Version': string; | ||
} | ||
|
||
const isPreferredBrowserRevisionInstalled = (): boolean => { | ||
const revisionInfo = installer.getPreferredBrowserRevisionInfo(); | ||
return revisionInfo.local; | ||
}; | ||
|
||
const getLocalRevisionList = (): Promise<string[]> => { | ||
return installer.getBrowserFetcher().localRevisions(); | ||
}; | ||
|
||
const getLocalRevisionInfo = async (): Promise<RevisionInfo | undefined> => { | ||
if (isPreferredBrowserRevisionInstalled()) { | ||
return installer.getPreferredBrowserRevisionInfo(); | ||
} | ||
|
||
const localRevisions = await getLocalRevisionList(); | ||
|
||
if (localRevisions.length > 0) { | ||
const lastRevision = localRevisions.pop() as string; | ||
return installer.getBrowserFetcher().revisionInfo(lastRevision); | ||
} | ||
|
||
return undefined; | ||
}; | ||
|
||
const getLocalBrowserInstance = async ( | ||
launchArgs?: LaunchOptions, | ||
): Promise<Browser> => { | ||
let revisionInfo: RevisionInfo; | ||
const localRevisionInfo = await getLocalRevisionInfo(); | ||
|
||
if (localRevisionInfo) { | ||
revisionInfo = localRevisionInfo; | ||
} else { | ||
revisionInfo = await installer.installPreferredBrowserRevision(); | ||
} | ||
|
||
return puppeteer.launch({ | ||
...launchArgs, | ||
executablePath: revisionInfo.executablePath, | ||
}); | ||
}; | ||
|
||
const launchSystemBrowser = async (): Promise<LaunchedChrome> => { | ||
const launchOptions: ChromeLauncherOptions = { | ||
chromeFlags: constants.PUPPETEER_LAUNCH_ARGS, | ||
logLevel: 'silent', | ||
}; | ||
|
||
return launch(launchOptions); | ||
}; | ||
|
||
const getLaunchedChromeVersionInfo = ( | ||
chrome: LaunchedChrome, | ||
): Promise<BrowserVersionInfo> => { | ||
return new Promise((resolve, reject) => { | ||
get(`http://localhost:${chrome.port}/json/version`, res => { | ||
let data = ''; | ||
res.setEncoding('utf8'); | ||
|
||
res.on('data', chunk => { | ||
data += chunk; | ||
}); | ||
|
||
res.on('end', () => { | ||
resolve(JSON.parse(data)); | ||
}); | ||
}).on('error', err => reject(err)); | ||
}); | ||
}; | ||
|
||
const getSystemBrowserInstance = async ( | ||
chrome: LaunchedChrome, | ||
launchArgs?: LaunchOptions, | ||
): Promise<Browser> => { | ||
const chromeVersionInfo = await getLaunchedChromeVersionInfo(chrome); | ||
|
||
const browser = await puppeteer.connect({ | ||
...launchArgs, | ||
browserWSEndpoint: chromeVersionInfo.webSocketDebuggerUrl, | ||
}); | ||
|
||
browser.on('disconnected', () => chrome.kill()); | ||
|
||
return browser; | ||
}; | ||
|
||
const getBrowserInstance = async ( | ||
launchArgs?: LaunchOptions, | ||
): Promise<Browser> => { | ||
const chrome = await launchSystemBrowser(); | ||
if (chrome && chrome.port > 0) { | ||
return getSystemBrowserInstance(chrome, launchArgs); | ||
} | ||
|
||
return getLocalBrowserInstance(launchArgs); | ||
}; | ||
|
||
export default { | ||
getBrowserInstance, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import puppeteer, { BrowserFetcher, RevisionInfo } from 'puppeteer-core'; | ||
import ProgressBar from 'progress'; | ||
import preLogger from './logger'; | ||
|
||
let browserFetcher: BrowserFetcher; | ||
|
||
const getBrowserFetcher = (): BrowserFetcher => { | ||
if (browserFetcher) { | ||
return browserFetcher; | ||
} | ||
|
||
browserFetcher = puppeteer.createBrowserFetcher(); | ||
return browserFetcher; | ||
}; | ||
|
||
const getPreferredBrowserRevisionInfo = (): RevisionInfo => { | ||
const revision = | ||
process.env.PUPPETEER_CHROMIUM_REVISION || | ||
process.env.npm_config_puppeteer_chromium_revision || | ||
process.env.npm_package_config_puppeteer_chromium_revision || | ||
require('puppeteer-core/package.json').puppeteer.chromium_revision; | ||
|
||
return getBrowserFetcher().revisionInfo(revision); | ||
}; | ||
|
||
const { revision } = getPreferredBrowserRevisionInfo(); | ||
const revisionInfo = getBrowserFetcher().revisionInfo(revision); | ||
const logger = preLogger('installer'); | ||
|
||
const toMegabytes = (bytes: number): string => { | ||
const mb = bytes / 1024 / 1024; | ||
return `${Math.round(mb * 10) / 10} Mb`; | ||
}; | ||
|
||
const cleanUpOldRevisions = (revisions: string[]): Promise<void[]> => { | ||
const localRevisions = revisions.filter(rev => revision !== rev); | ||
// Remove previous chromium revisions. | ||
const cleanupOldVersions = localRevisions.map((rev: string) => | ||
getBrowserFetcher().remove(rev), | ||
); | ||
return Promise.all([...cleanupOldVersions]); | ||
}; | ||
|
||
let progressBar: ProgressBar; | ||
let lastDownloadedBytes = 0; | ||
const onProgress = (downloadedBytes: number, totalBytes: number): void => { | ||
if (!progressBar) { | ||
progressBar = new ProgressBar( | ||
`Downloading Chromium r${revision} - ${toMegabytes( | ||
totalBytes, | ||
)} [:bar] :percent :etas `, | ||
{ | ||
complete: '=', | ||
incomplete: ' ', | ||
width: 20, | ||
total: totalBytes, | ||
}, | ||
); | ||
} | ||
const delta = downloadedBytes - lastDownloadedBytes; | ||
lastDownloadedBytes = downloadedBytes; | ||
progressBar.tick(delta); | ||
}; | ||
|
||
const installPreferredBrowserRevision = async (): Promise<RevisionInfo> => { | ||
logger.warn( | ||
`Chromium is not found on your system, gonna have to download r${revision} for you once`, | ||
); | ||
|
||
const installedRevision = await getBrowserFetcher().download( | ||
revision, | ||
onProgress, | ||
); | ||
logger.log(`Chromium downloaded to ${revisionInfo.folderPath}`); | ||
|
||
await getBrowserFetcher() | ||
.localRevisions() | ||
.then(cleanUpOldRevisions); | ||
|
||
return installedRevision; | ||
}; | ||
|
||
export default { | ||
getBrowserFetcher, | ||
installPreferredBrowserRevision, | ||
getPreferredBrowserRevisionInfo, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters