From 13ea347c7d9a1c341ed66d5ee39d383cef9148f6 Mon Sep 17 00:00:00 2001 From: lcabral37 Date: Mon, 10 Aug 2020 10:37:31 +0200 Subject: [PATCH] feat: support configuring the browser download path (#6014) By adding support for an environment variable `PUPPETEER_DOWNLOAD_PATH` it is possible to support downloading the browser binaries into a folder outside the `node_modules` folder. This makes it possible to preserve previously downloaded binaries in order to skip downloading them again. --- docs/api.md | 1 + experimental/puppeteer-firefox/install.js | 3 ++- experimental/puppeteer-firefox/lib/Launcher.js | 5 ++++- src/install.ts | 5 +++++ src/node/Launcher.ts | 6 ++++++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index abde2d163410a..8f14e5a8c55fb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -411,6 +411,7 @@ If Puppeteer doesn't find them in the environment during the installation step, - `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY` - defines HTTP proxy settings that are used to download and run Chromium. - `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD` - do not download bundled Chromium during installation step. - `PUPPETEER_DOWNLOAD_HOST` - overwrite URL prefix that is used to download Chromium. Note: this includes protocol and might even include path prefix. Defaults to `https://storage.googleapis.com`. +- `PUPPETEER_DOWNLOAD_PATH` - overwrite the path for the downloads folder. Defaults to `/.local-chromium`, where `` is puppeteer's package root. - `PUPPETEER_CHROMIUM_REVISION` - specify a certain version of Chromium you'd like Puppeteer to use. See [puppeteer.launch([options])](#puppeteerlaunchoptions) on how executable path is inferred. **BEWARE**: Puppeteer is only [guaranteed to work](https://github.com/puppeteer/puppeteer/#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk. - `PUPPETEER_EXECUTABLE_PATH` - specify an executable path to be used in `puppeteer.launch`. See [puppeteer.launch([options])](#puppeteerlaunchoptions) on how the executable path is inferred. **BEWARE**: Puppeteer is only [guaranteed to work](https://github.com/puppeteer/puppeteer/#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk. - `PUPPETEER_PRODUCT` - specify which browser you'd like Puppeteer to use. Must be one of `chrome` or `firefox`. This can also be used during installation to fetch the recommended browser binary. Setting `product` programmatically in [puppeteer.launch([options])](#puppeteerlaunchoptions) supersedes this environment variable. The product is exposed in [`puppeteer.product`](#puppeteerproduct) diff --git a/experimental/puppeteer-firefox/install.js b/experimental/puppeteer-firefox/install.js index 2ae9f414ceb19..a7ead10b3b480 100644 --- a/experimental/puppeteer-firefox/install.js +++ b/experimental/puppeteer-firefox/install.js @@ -20,9 +20,10 @@ if (require('./package.json').name === 'puppeteer-core') return; const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host || process.env.npm_package_config_puppeteer_download_host; +const downloadPath = process.env.PUPPETEER_DOWNLOAD_PATH || process.env.npm_config_puppeteer_download_path || process.env.npm_package_config_puppeteer_download_path; const puppeteer = require('./index'); -const browserFetcher = puppeteer.createBrowserFetcher({ host: downloadHost, product: 'firefox' }); +const browserFetcher = puppeteer.createBrowserFetcher({ host: downloadHost, product: 'firefox', path: downloadPath }); const revision = require('./package.json').puppeteer.firefox_revision; diff --git a/experimental/puppeteer-firefox/lib/Launcher.js b/experimental/puppeteer-firefox/lib/Launcher.js index d0fdd696ad068..77a8a7186af8c 100644 --- a/experimental/puppeteer-firefox/lib/Launcher.js +++ b/experimental/puppeteer-firefox/lib/Launcher.js @@ -231,7 +231,10 @@ class Launcher { } _resolveExecutablePath() { - const browserFetcher = new BrowserFetcher(this._projectRoot, { product: 'firefox' }); + const downloadPath = process.env.PUPPETEER_DOWNLOAD_PATH || + process.env.npm_config_puppeteer_download_path || + process.env.npm_package_config_puppeteer_download_path; + const browserFetcher = new BrowserFetcher(this._projectRoot, { product: 'firefox', path: downloadPath }); const revisionInfo = browserFetcher.revisionInfo(this._preferredRevision); const missingText = !revisionInfo.local ? `Firefox revision is not downloaded. Run "npm install" or "yarn install"` : null; return {executablePath: revisionInfo.executablePath, missingText}; diff --git a/src/install.ts b/src/install.ts index c4fb23eb53c7e..d2c9f1baa83ba 100644 --- a/src/install.ts +++ b/src/install.ts @@ -35,9 +35,14 @@ export async function downloadBrowser() { process.env.npm_config_puppeteer_product || process.env.npm_package_config_puppeteer_product || 'chrome'; + const downloadPath = + process.env.PUPPETEER_DOWNLOAD_PATH || + process.env.npm_config_puppeteer_download_path || + process.env.npm_package_config_puppeteer_download_path; const browserFetcher = puppeteer.createBrowserFetcher({ product, host: downloadHost, + path: downloadPath, }); const revision = await getRevision(); await fetchBinary(revision); diff --git a/src/node/Launcher.ts b/src/node/Launcher.ts index d352a02098104..720ee20ef1c88 100644 --- a/src/node/Launcher.ts +++ b/src/node/Launcher.ts @@ -744,6 +744,7 @@ function getWSEndpoint(browserURL: string): Promise { function resolveExecutablePath( launcher: ChromeLauncher | FirefoxLauncher ): { executablePath: string; missingText?: string } { + let downloadPath: string; // puppeteer-core doesn't take into account PUPPETEER_* env variables. if (!launcher._isPuppeteerCore) { const executablePath = @@ -757,9 +758,14 @@ function resolveExecutablePath( : null; return { executablePath, missingText }; } + downloadPath = + process.env.PUPPETEER_DOWNLOAD_PATH || + process.env.npm_config_puppeteer_download_path || + process.env.npm_package_config_puppeteer_download_path; } const browserFetcher = new BrowserFetcher(launcher._projectRoot, { product: launcher.product, + path: downloadPath, }); if (!launcher._isPuppeteerCore && launcher.product === 'chrome') { const revision = process.env['PUPPETEER_CHROMIUM_REVISION'];