8000 feat: allow to use an existing Chrome instance (fixes #9) · gajus/usus@6c676b7 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 6c676b7

Browse files
committed
feat: allow to use an existing Chrome instance (fixes #9)
1 parent b727be6 commit 6c676b7

File tree

7 files changed

+98
-10
lines changed

7 files changed

+98
-10
lines changed

README.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export type UserDeviceMetricsOverrideType = {
9595
type FormatStylesType = (styles: string) => Promise<string>;
9696

9797
export type UserConfigurationType = {
98+
+chromePort?: number,
9899
+cookies?: $ReadOnlyArray<CookieType>,
99100
+delay?: number,
100101
+deviceMetricsOverride?: UserDeviceMetricsOverrideType,
@@ -113,6 +114,7 @@ The default behaviour is to return the HTML.
113114

114115
|Name|Type|Description|Default value|
115116
|---|---|---|---|
117+
|`chromePort`|`number`|Port of an existing Chrome instance. See [Controlling the Chrome instance](#controlling-the-chrome-instance).|N/A|
116118
|`cookies`|`Array<{name: string, value: string}>`|Sets a cookie with the given cookie data.|N/A|
117119
|`delay`|`number`|Defines how many milliseconds to wait after the "load" event has been fired before capturing the styles used to load the page. This is important if resources appearing on the page are being loaded asynchronously.|`number`|`5000`|
118120
|`deviceMetricsOverride`||See [`deviceMetricsOverride` configuration](#devicemetricsoverride-configuration)||
@@ -173,10 +175,39 @@ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key
173175
&& sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
174176
&& apt-get update -y \
175177
&& apt-get install google-chrome-stable -y
178+
176179
```
177180

178181
This assumes that you are extending from the base [`node` image](https://github.com/nodejs/docker-node).
179182

183+
### Controlling the Chrome instance
184+
185+
By default, ūsus creates a new instance of Chrome for every `render` operation and destroys it after completion. However, you can start Chrome independent of ūsus and re-use the same instance for multiple renderings.
186+
187+
```js
188+
import {
189+
launchChrome,
190+
render
191+
} from 'usus';
192+
193+
const chrome = await launchChrome();
194+
195+
await render('https://go2cinema.com/movies/baywatch-2017-1198354', {
196+
chromePort: chrome.port,
197+
inlineStyles: true
198+
});
199+
200+
await render('https://go2cinema.com/movies/baby-driver-2017-2257838', {
201+
chromePort: chrome.port,
202+
inlineStyles: true
203+
});
204+
205+
await chrome.kill();
206+
207+
```
208+
209+
`launchChrome` is a convenience method to launch Chrome using default ūsus configuration. If you need granular control over how Chrome is launched, refer to the [chrome-launcher](https://github.com/GoogleChrome/lighthouse/tree/master/chrome-launcher) program.
210+
180211
### Minifying the CSS
181212

182213
Use the `formatStyles` callback to minify/ format/ optimize/ remove CSS before it is inlined.
@@ -191,7 +222,7 @@ import {
191222
minify
192223
} from 'csso';
193224

194-
return render(url, {
225+
await render(url, {
195226
formatStyles: (styles: string): Promise<string> => {
196227
return minify(styles).css;
197228
},

src/bin/commands/render.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export const command = 'render';
1010
export const desc = 'Renders page using Chrome Debugging Protocol. Extracts CSS used to render the page. Renders HTML with the blocking CSS made asynchronous. Inlines the critical CSS.';
1111

1212
export const baseConfiguration = {
13+
chromePort: {
14+
description: 'Port of an existing Chrome instance. See "Controlling the Chrome instance" in the ūsus cookbook.',
15+
type: 'number'
16+
},
1317
cookies: {
1418
description: 'Sets a cookie with the given cookie data. Must be provided as key=value pairs, e.g. foo=bar.',
1519
type: 'array'

src/factories/createConfiguration.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const deviceMetricsOverrideDesktopProfile = {
1616
};
1717

1818
export default (userConfiguration: UserConfigurationType): ConfigurationType => {
19+
const chromePort = userConfiguration.chromePort;
1920
const cookies = userConfiguration.cookies || [];
2021
const delayConfiguration = userConfiguration.delay || 5000;
2122
const extractStyles = userConfiguration.extractStyles || false;
@@ -37,6 +38,7 @@ export default (userConfiguration: UserConfigurationType): ConfigurationType =>
3738
}
3839

3940
return {
41+
chromePort,
4042
cookies,
4143
delay: delayConfiguration,
4244
deviceMetricsOverride,

src/types.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type DeviceMetricsOverrideType = {
2828
type FormatStylesType = (styles: string) => Promise<string>;
2929

3030
export type UserConfigurationType = {
31+
+chromePort?: number,
3132
+cookies?: $ReadOnlyArray<CookieType>,
3233
+delay?: number,
3334
+deviceMetricsOverride?: UserDeviceMetricsOverrideType,
@@ -38,6 +39,7 @@ export type UserConfigurationType = {
3839
};
3940

4041
export type ConfigurationType = {|
42+
+chromePort?: number,
4143
+cookies: $ReadOnlyArray<CookieType>,
4244
+delay: number,
4345
+deviceMetricsOverride: DeviceMetricsOverrideType,

src/usus.js

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import type {
1616

1717
const debug = createDebug('usus');
1818

19-
const launchChrome = () => {
19+
export const launchChrome = () => {
2020
return launch({
2121
chromeFlags: [
2222
'--disable-gpu',
@@ -120,12 +120,32 @@ export const render = async (url: string, userConfiguration: UserConfigurationTy
120120

121121
debug('rendering URL %s', JSON.stringify(configuration));
122122

123-
const chrome = await launchChrome();
123+
let chrome;
124+
let chromePort;
125+
126+
if (configuration.chromePort) {
127+
debug('attempting to use the user provided instance of Chrome (port %d)', configuration.chromePort);
128+
129+
chromePort = configuration.chromePort;
130+
} else {
131+
chrome = await launchChrome();
132+
chromePort = chrome.port;
133+
}
124134

125135
const protocol = await CDP({
126-
port: chrome.port
136+
port: chromePort
127137
});
128138

139+
const end = async (): Promise<void> => {
140+
await protocol.close();
141+
142+
if (!chrome) {
143+
return;
144+
}
145+
146+
await chrome.kill();
147+
};
148+
129149
const {
130150
CSS,
131151
DOM,
@@ -170,7 +190,7 @@ export const render = async (url: string, userConfiguration: UserConfigurationTy
170190
}
171191
});
172192

173-
CSS.startRuleUsageTracking();
193+
await CSS.startRuleUsageTracking();
174194

175195
const frame = await Page.navigate({
176196
url
@@ -224,6 +244,8 @@ export const render = async (url: string, userConfiguration: UserConfigurationTy
224244
});
225245
});
226246

247+
await CSS.stopRuleUsageTracking();
248+
227249
if (configuration.formatStyles) {
228250
usedStyles = await configuration.formatStyles(usedStyles);
229251
}
@@ -269,15 +291,16 @@ export const render = async (url: string, userConfiguration: UserConfigurationTy
269291
nodeId: rootDocument.root.nodeId
270292
})).outerHTML;
271293

272-
await chrome.kill();
294+
await end();
273295

274296
return rootOuterHTMLWithInlinedStyles;
275297
}
276298

277299
if (configuration.extractStyles) {
278-
await chrome.kill();
300+
await end();
279301

280-
// @todo Document that `extractStyles` does not return inline stylesheets.
302+
// @todo Document that `extractStyles` does not return the inline stylesheets.
303+
// @todo Document that `extractStyles` does not return the alien stylesheets.
281304

282305
return usedStyles;
283306
}
@@ -286,7 +309,7 @@ export const render = async (url: string, userConfiguration: UserConfigurationTy
286309
nodeId: rootDocument.root.nodeId
287310
})).outerHTML;
288311

289-
await chrome.kill();
312+
await end();
290313

291314
return rootOuterHTML;
292315
};

test/createConfiguration.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import createConfiguration, {
77

88
const createDefaultConfiguration = () => {
99
return {
10+
chromePort: undefined,
1011
cookies: [],
1112
delay: 5000,
1213
deviceMetricsOverride: {

test/usus.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
// @flow
22

3-
import test from 'ava';
3+
import test, {
4+
after,
5+
before
6+
} from 'ava';
47
import {
8+
launchChrome,
59
render
610
} from '../src/usus';
711
import {
812
isHtmlEqual,
913
serve
1014
} from './helpers';
1115

16+
let chromeInstance;
17+
let chromePort;
18+
19+
before(async () => {
20+
const chrome = await launchChrome();
21+
22+
chromeInstance = chrome;
23+
chromePort = chrome.port;
24+
});
25+
26+
after.always(async () => {
27+
await chromeInstance.kill();
28+
});
29+
1230
test('renders HTML', async (t) => {
1331
const server = await serve(`
1432
<html>
@@ -19,6 +37,7 @@ test('renders HTML', async (t) => {
1937
`);
2038

2139
const result = await render(server.url, {
40+
chromePort,
2241
delay: 500
2342
});
2443

@@ -53,6 +72,7 @@ test('inlines CSS (preloadStyles=false)', async (t) => {
5372
`);
5473

5574
const result = await render(server.url, {
75+
chromePort,
5676
delay: 500,
5777
inlineStyles: true,
5878
preloadStyles: false
@@ -94,6 +114,7 @@ test('inlines CSS (preloadStyles=true)', async (t) => {
94114
`);
95115

96116
const result = await render(server.url, {
117+
chromePort,
97118
delay: 500,
98119
inlineStyles: true
99120
});
@@ -135,6 +156,7 @@ test('extracts CSS', async (t) => {
135156
`);
136157

137158
const result = await render(server.url, {
159+
chromePort,
138160
delay: 500,
139161
extractStyles: true
140162
});
@@ -162,6 +184,7 @@ test('does not re-inline the inline CSS', async (t) => {
162184
`);
163185

164186
const result = await render(server.url, {
187+
chromePort,
165188
delay: 500,
166189
inlineStyles: true,
167190
preloadStyles: false
@@ -202,6 +225,7 @@ test('does not inline CSS from alien frames', async (t) => {
202225
`);
203226

204227
const result = await render(server.url, {
228+
chromePort,
205229
delay: 2000,
206230
inlineStyles: true,
207231
preloadStyles: false
@@ -247,6 +271,7 @@ test('extracts only the used CSS', async (t) => {
247271
`);
248272

249273
const result = await render(server.url, {
274+
chromePort,
250275
delay: 500,
251276
extractStyles: true
252277
});

0 commit comments

Comments
 (0)
0