Skip to content

Commit

Permalink
feat: download chrome-headless-shell by default and use it for the ol…
Browse files Browse the repository at this point in the history
…d headless mode (#11754)
  • Loading branch information
OrKoN committed Jan 25, 2024
1 parent f67b205 commit ce894a2
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 47 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -46,10 +46,10 @@ pnpm i puppeteer
```

When you install Puppeteer, it automatically downloads a recent version of
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) that is [guaranteed to
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) and a `chrome-headless-shell` binary (starting with Puppeteer v21.6.0) that is [guaranteed to
work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
by default (starting with Puppeteer v19.0.0).
by default (starting with Puppeteer v19.0.0). See [configuration](https://pptr.dev/api/puppeteer.configuration) for configuration options and environmental variables to control the download behavor.

If you deploy a project using Puppeteer to a hosting provider, such as Render or
Heroku, you might need to reconfigure the location of the cache to be within
Expand Down
26 changes: 14 additions & 12 deletions docs/api/puppeteer.configuration.md
Expand Up @@ -16,15 +16,17 @@ export interface Configuration

## Properties

| Property | Modifiers | Type | Description | Default |
| ------------------ | --------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| browserRevision | <code>optional</code> | string | <p>Specifies a certain version of the browser you'd like Puppeteer to use.</p><p>Can be overridden by <code>PUPPETEER_BROWSER_REVISION</code>.</p><p>See [puppeteer.launch](./puppeteer.puppeteernode.launch.md) on how executable path is inferred.</p> | A compatible-revision of the browser. |
| cacheDirectory | <code>optional</code> | string | <p>Defines the directory to be used by Puppeteer for caching.</p><p>Can be overridden by <code>PUPPETEER_CACHE_DIR</code>.</p> | <code>path.join(os.homedir(), '.cache', 'puppeteer')</code> |
| defaultProduct | <code>optional</code> | [Product](./puppeteer.product.md) | <p>Specifies which browser you'd like Puppeteer to use.</p><p>Can be overridden by <code>PUPPETEER_PRODUCT</code>.</p> | <code>chrome</code> |
| downloadBaseUrl | <code>optional</code> | string | <p>Specifies the URL prefix that is used to download the browser.</p><p>Can be overridden by <code>PUPPETEER_DOWNLOAD_BASE_URL</code>.</p> | Either https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing or https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central, depending on the product. |
| downloadPath | <code>optional</code> | string | <p>Specifies the path for the downloads folder.</p><p>Can be overridden by <code>PUPPETEER_DOWNLOAD_PATH</code>.</p> | <code>&lt;cacheDirectory&gt;</code> |
| executablePath | <code>optional</code> | string | <p>Specifies an executable path to be used in [puppeteer.launch](./puppeteer.puppeteernode.launch.md).</p><p>Can be overridden by <code>PUPPETEER_EXECUTABLE_PATH</code>.</p> | **Auto-computed.** |
| experiments | <code>optional</code> | [ExperimentsConfiguration](./puppeteer.experimentsconfiguration.md) | Defines experimental options for Puppeteer. | |
| logLevel | <code>optional</code> | 'silent' \| 'error' \| 'warn' | Tells Puppeteer to log at the given level. | <code>warn</code> |
| skipDownload | <code>optional</code> | boolean | <p>Tells Puppeteer to not download during installation.</p><p>Can be overridden by <code>PUPPETEER_SKIP_DOWNLOAD</code>.</p> | |
| temporaryDirectory | <code>optional</code> | string | <p>Defines the directory to be used by Puppeteer for creating temporary files.</p><p>Can be overridden by <code>PUPPETEER_TMP_DIR</code>.</p> | <code>os.tmpdir()</code> |
| Property | Modifiers | Type | Description | Default |
| ------------------------------- | --------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| browserRevision | <code>optional</code> | string | <p>Specifies a certain version of the browser you'd like Puppeteer to use.</p><p>Can be overridden by <code>PUPPETEER_BROWSER_REVISION</code>.</p><p>See [puppeteer.launch](./puppeteer.puppeteernode.launch.md) on how executable path is inferred.</p> | A compatible-revision of the browser. |
| cacheDirectory | <code>optional</code> | string | <p>Defines the directory to be used by Puppeteer for caching.</p><p>Can be overridden by <code>PUPPETEER_CACHE_DIR</code>.</p> | <code>path.join(os.homedir(), '.cache', 'puppeteer')</code> |
| defaultProduct | <code>optional</code> | [Product](./puppeteer.product.md) | <p>Specifies which browser you'd like Puppeteer to use.</p><p>Can be overridden by <code>PUPPETEER_PRODUCT</code>.</p> | <code>chrome</code> |
| downloadBaseUrl | <code>optional</code> | string | <p>Specifies the URL prefix that is used to download the browser.</p><p>Can be overridden by <code>PUPPETEER_DOWNLOAD_BASE_URL</code>.</p> | Either https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing or https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central, depending on the product. |
| downloadPath | <code>optional</code> | string | <p>Specifies the path for the downloads folder.</p><p>Can be overridden by <code>PUPPETEER_DOWNLOAD_PATH</code>.</p> | <code>&lt;cacheDirectory&gt;</code> |
| executablePath | <code>optional</code> | string | <p>Specifies an executable path to be used in [puppeteer.launch](./puppeteer.puppeteernode.launch.md).</p><p>Can be overridden by <code>PUPPETEER_EXECUTABLE_PATH</code>.</p> | **Auto-computed.** |
| experiments | <code>optional</code> | [ExperimentsConfiguration](./puppeteer.experimentsconfiguration.md) | Defines experimental options for Puppeteer. | |
| logLevel | <code>optional</code> | 'silent' \| 'error' \| 'warn' | Tells Puppeteer to log at the given level. | <code>warn</code> |
| skipChromeDownload | <code>optional</code> | boolean | <p>Tells Puppeteer to not Chrome download during installation.</p><p>Can be overridden by <code>PUPPETEER_SKIP_CHROME_DOWNLOAD</code>.</p> | |
| skipChromeHeadlessShellDownload | <code>optional</code> | boolean | <p>Tells Puppeteer to not chrome-headless-shell download during installation.</p><p>Can be overridden by <code>PUPPETEER_SKIP_CHROME_HEADLESSS_HELL_DOWNLOAD</code>.</p> | |
| skipDownload | <code>optional</code> | boolean | <p>Tells Puppeteer to not download during installation.</p><p>Can be overridden by <code>PUPPETEER_SKIP_DOWNLOAD</code>.</p> | |
| temporaryDirectory | <code>optional</code> | string | <p>Defines the directory to be used by Puppeteer for creating temporary files.</p><p>Can be overridden by <code>PUPPETEER_TMP_DIR</code>.</p> | <code>os.tmpdir()</code> |
4 changes: 2 additions & 2 deletions docs/index.md
Expand Up @@ -46,10 +46,10 @@ pnpm i puppeteer
```

When you install Puppeteer, it automatically downloads a recent version of
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) that is [guaranteed to
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) and a `chrome-headless-shell` binary (starting with Puppeteer v21.6.0) that is [guaranteed to
work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
by default (starting with Puppeteer v19.0.0).
by default (starting with Puppeteer v19.0.0). See [configuration](https://pptr.dev/api/puppeteer.configuration) for configuration options and environmental variables to control the download behavor.

If you deploy a project using Puppeteer to a hosting provider, such as Render or
Heroku, you might need to reconfigure the location of the cache to be within
Expand Down
12 changes: 12 additions & 0 deletions packages/puppeteer-core/src/common/Configuration.ts
Expand Up @@ -95,6 +95,18 @@ export interface Configuration {
* Can be overridden by `PUPPETEER_SKIP_DOWNLOAD`.
*/
skipDownload?: boolean;
/**
* Tells Puppeteer to not Chrome download during installation.
*
* Can be overridden by `PUPPETEER_SKIP_CHROME_DOWNLOAD`.
*/
skipChromeDownload?: boolean;
/**
* Tells Puppeteer to not chrome-headless-shell download during installation.
*
* Can be overridden by `PUPPETEER_SKIP_CHROME_HEADLESSS_HELL_DOWNLOAD`.
*/
skipChromeHeadlessShellDownload?: boolean;
/**
* Tells Puppeteer to log at the given level.
*
Expand Down
9 changes: 6 additions & 3 deletions packages/puppeteer-core/src/node/ChromeLauncher.ts
Expand Up @@ -146,7 +146,7 @@ export class ChromeLauncher extends ProductLauncher {
channel || !this.puppeteer._isPuppeteerCore,
`An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``
);
chromeExecutable = this.executablePath(channel);
chromeExecutable = this.executablePath(channel, options.headless ?? true);
}

return {
Expand Down Expand Up @@ -269,14 +269,17 @@ export class ChromeLauncher extends ProductLauncher {
return chromeArguments;
}

override executablePath(channel?: ChromeReleaseChannel): string {
override executablePath(
channel?: ChromeReleaseChannel,
headless?: boolean | 'new'
): string {
if (channel) {
return computeSystemExecutablePath({
browser: SupportedBrowsers.CHROME,
channel: convertPuppeteerChannelToBrowsersChannel(channel),
});
} else {
return this.resolveExecutablePath();
return this.resolveExecutablePath(headless);
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions packages/puppeteer-core/src/node/ProductLauncher.ts
Expand Up @@ -393,7 +393,7 @@ export abstract class ProductLauncher {
/**
* @internal
*/
protected resolveExecutablePath(): string {
protected resolveExecutablePath(headless?: boolean | 'new'): string {
let executablePath = this.puppeteer.configuration.executablePath;
if (executablePath) {
if (!existsSync(executablePath)) {
Expand All @@ -404,9 +404,12 @@ export abstract class ProductLauncher {
return executablePath;
}

function productToBrowser(product?: Product) {
function productToBrowser(product?: Product, headless?: boolean | 'new') {
switch (product) {
case 'chrome':
if (headless === true) {
return InstalledBrowser.CHROMEHEADLESSSHELL;
}
return InstalledBrowser.CHROME;
case 'firefox':
return InstalledBrowser.FIREFOX;
Expand All @@ -416,7 +419,7 @@ export abstract class ProductLauncher {

executablePath = computeExecutablePath({
cacheDir: this.puppeteer.defaultDownloadPath!,
browser: productToBrowser(this.product),
browser: productToBrowser(this.product, headless),
buildId: this.puppeteer.browserRevision,
});

Expand Down
1 change: 1 addition & 0 deletions packages/puppeteer-core/src/revisions.ts
Expand Up @@ -9,5 +9,6 @@
*/
export const PUPPETEER_REVISIONS = Object.freeze({
chrome: '121.0.6167.85',
'chrome-headless-shell': '121.0.6167.85',
firefox: 'latest',
});
18 changes: 18 additions & 0 deletions packages/puppeteer/src/getConfiguration.ts
Expand Up @@ -64,6 +64,24 @@ export const getConfiguration = (): Configuration => {
configuration.skipDownload
);

// Set skipChromeDownload explicitly or from default
configuration.skipChromeDownload = Boolean(
process.env['PUPPETEER_SKIP_CHROME_DOWNLOAD'] ??
process.env['npm_config_puppeteer_skip_chrome_download'] ??
process.env['npm_package_config_puppeteer_skip_chrome_download'] ??
configuration.skipChromeDownload
);

// Set skipChromeDownload explicitly or from default
configuration.skipChromeHeadlessShellDownload = Boolean(
process.env['PUPPETEER_SKIP_CHROME_HEADLESS_SHELL_DOWNLOAD'] ??
process.env['npm_config_puppeteer_skip_chrome_headless_shell_download'] ??
process.env[
'npm_package_config_puppeteer_skip_chrome_headless_shell_download'
] ??
configuration.skipChromeHeadlessShellDownload
);

// Prepare variables used in browser downloading
if (!configuration.skipDownload) {
configuration.browserRevision =
Expand Down

0 comments on commit ce894a2

Please sign in to comment.