Skip to content

Commit ea0856b

Browse files
authored
feat!: Allow running lighthouse on other pages available in publish folder (#487)
Release-As: 4.0.0 BREAKING-CHANGE: The `path` audit input option no longer affects the served directory for an audit. Use `serveDir` instead. Use `path` to specify the sub directory or `html` file within the served directory that should be audited.
1 parent c204252 commit ea0856b

File tree

10 files changed

+115
-69
lines changed

10 files changed

+115
-69
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Audits
2-
AUDITS=[{"url":"https://www.example.com","thresholds":{"performance":0.5}},{"path":""},{"path":"route1"},{"path":"route2"}]
2+
AUDITS=[{"url":"https://www.example.com","thresholds":{"performance":0.5}},{"serveDir":""},{"serveDir":"route1"},{"path":"route2"}, {path: "contact.html"}]
33
# Ignored when a url is configured for an audit
44
PUBLISH_DIR=FULL_PATH_TO_LOCAL_BUILD_DIRECTORY
55
# JSON string of thresholds to enforce

README.md

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ A Netlify plugin to generate a Lighthouse report for every deploy
44

55
## Installation options
66

7-
You can install the plugin for your site using your `netlify.toml` file or the Netlify UI.
7+
You can install the plugin for your site using your `netlify.toml` file or the Netlify UI.
88

99
For the most customization options, we recommend installing the Lighthouse plugin with a `netlify.toml` file.
1010

1111
`netlify.toml` file-based installation allows you to:
12-
- [Run Lighthouse audits for different site paths, such as the contact page and site home page](#run-lighthouse-for-different-site-paths)
13-
- [Run Lighthouse audits for a desktop device](#run-lighthouse-for-the-desktop-experience)
14-
- [Generate Lighthouse results in a language other than English](#generate-lighthouse-results-in-other-languages)
12+
13+
- [Run Lighthouse audits for different site paths, such as the contact page and site home page](#run-lighthouse-for-different-site-paths)
14+
- [Run Lighthouse audits for a desktop device](#run-lighthouse-for-the-desktop-experience)
15+
- [Generate Lighthouse results in a language other than English](#generate-lighthouse-results-in-other-languages)
1516

1617
### Install plugin through the Netlify UI
1718

@@ -46,7 +47,7 @@ Then add the plugin to your `netlify.toml` configuration file:
4647
output_path = "reports/lighthouse.html"
4748
```
4849

49-
By default, the plugin will serve and audit the build directory of the site.
50+
By default, the plugin will serve and audit the build directory of the site, inspecting the `index.html`.
5051
You can customize the behavior via the `audits` input:
5152

5253
```toml
@@ -64,13 +65,27 @@ You can customize the behavior via the `audits` input:
6465
# you can specify output_path per audit, relative to the path
6566
output_path = "reports/route1.html"
6667

68+
# to audit an HTML file other than index.html in the build directory
69+
[[plugins.inputs.audits]]
70+
path = "contact.html"
71+
72+
# to audit an HTML file other than index.html in a sub path of the build directory
73+
[[plugins.inputs.audits]]
74+
path = "pages/contact.html"
75+
6776
# to audit a specific absolute url
6877
[[plugins.inputs.audits]]
6978
url = "https://www.example.com"
7079

7180
# you can specify thresholds per audit
7281
[plugins.inputs.audits.thresholds]
7382
performance = 0.8
83+
84+
# to serve only a sub directory of the build directory for an audit
85+
# pages/index.html will be audited, and files outside of this directory will not be served
86+
[[plugins.inputs.audits]]
87+
serveDir = "pages"
88+
7489
```
7590

7691
The lighthouse scores are automatically printed to the **Deploy log** in the Netlify UI. For example:
@@ -103,7 +118,7 @@ To customize how Lighthouse runs audits, you can make changes to the `netlify.to
103118

104119
By default, Lighthouse takes a mobile-first performance testing approach and runs audits for the mobile device experience. You can optionally run Lighthouse audits for the desktop experience by including `preset = "desktop"` in your `netlify.toml` file:
105120

106-
```
121+
```toml
107122
[[plugins]]
108123
package = "@netlify/plugin-lighthouse"
109124

@@ -117,15 +132,15 @@ To return to running Lighthouse audits for the mobile experience, just remove th
117132

118133
### Generate Lighthouse results in other languages
119134

120-
By default, Lighthouse results are generated in English. To return Lighthouse results in other languages, include the language code from any Lighthouse-supported locale in your `netlify.toml` file.
135+
By default, Lighthouse results are generated in English. To return Lighthouse results in other languages, include the language code from any Lighthouse-supported locale in your `netlify.toml` file.
121136

122137
For the latest Lighthouse supported locales or language codes, check out this [official Lighthouse code](https://github.com/GoogleChrome/lighthouse/blob/da3c865d698abc9365fa7bb087a08ce8c89b0a05/types/lhr/settings.d.ts#L9).
123138

124139
Updates to `netlify.toml` will take effect for new builds.
125140

126141
#### Example to generate Lighthouse results in Spanish
127142

128-
```
143+
```toml
129144
[[plugins]]
130145
package = "@netlify/plugin-lighthouse"
131146

@@ -146,7 +161,7 @@ yarn local
146161

147162
## Preview Lighthouse results within the Netlify UI
148163

149-
Netlify offers an experimental feature through Netlify Labs that allows you to view Lighthouse scores for each of your builds on your site's Deploy Details page with a much richer format.
164+
Netlify offers an experimental feature through Netlify Labs that allows you to view Lighthouse scores for each of your builds on your site's Deploy Details page with a much richer format.
150165

151166
You'll need to install the [Lighthouse build plugin](https://app.netlify.com/plugins/@netlify/plugin-lighthouse/install) on your site and then enable this experimental feature through Netlify Labs.
152167

example/contact.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Document</title>
8+
</head>
9+
<body>
10+
<h1>Contact</h1>
11+
</body>
12+
</html>

example/index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!DOCTYPE html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<meta charset="utf-8" />
5-
<title>Empty Site</title>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Document</title>
68
</head>
79
<body>
8-
Empty Site
10+
<h1>Example</h1>
911
</body>
1012
</html>

example/route1/index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!DOCTYPE html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<meta charset="utf-8" />
5-
<title>Route 1</title>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Document</title>
68
</head>
79
<body>
8-
Route 1
10+
<h1>Example Route 1</h1>
911
</body>
1012
</html>

example/route2/index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!DOCTYPE html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<meta charset="utf-8" />
5-
<title>Route 2</title>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Document</title>
68
</head>
79
<body>
8-
Route 2
10+
<h1>Example Route 2</h1>
911
</body>
1012
</html>

netlify.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ performance = 0.9
1616

1717
[[plugins.inputs.audits]]
1818
output_path = "reports/route1.html"
19-
path = "route1"
19+
serveDir = "route1"
2020
[[plugins.inputs.audits]]
21-
path = "route2"
21+
serveDir = "route2"
2222
[[plugins.inputs.audits]]
23-
path = ""
23+
serveDir = ""
2424

2525
[[plugins]]
2626
package = "netlify-plugin-cypress"

src/config.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
const chalk = require('chalk');
22
const { join } = require('path');
33

4-
const getServePath = (dir, path) => {
5-
if (typeof path !== 'string' || typeof dir !== 'string') {
6-
return { path: undefined };
4+
const getServePath = (dir, subDir) => {
5+
if (typeof subDir !== 'string' || typeof dir !== 'string') {
6+
return { serveDir: undefined };
77
}
88

9-
const resolvedPath = join(dir, path);
9+
const resolvedPath = join(dir, subDir);
1010
if (!resolvedPath.startsWith(dir)) {
1111
throw new Error(
1212
chalk.red(
1313
`resolved path for ${chalk.red(
14-
path,
14+
subDir,
1515
)} is outside publish directory ${chalk.red(dir)}`,
1616
),
1717
);
1818
}
1919

20-
return { path: resolvedPath };
20+
return { serveDir: resolvedPath };
2121
};
2222

2323
const getConfiguration = ({ constants, inputs } = {}) => {
@@ -57,14 +57,14 @@ const getConfiguration = ({ constants, inputs } = {}) => {
5757
}
5858

5959
if (!Array.isArray(audits)) {
60-
audits = [{ path: serveDir, url: auditUrl, thresholds, output_path }];
60+
audits = [{ serveDir, url: auditUrl, thresholds, output_path }];
6161
} else {
6262
audits = audits.map((a) => {
6363
return {
6464
...a,
6565
thresholds: a.thresholds || thresholds,
6666
output_path: a.output_path || output_path,
67-
...getServePath(serveDir, a.path),
67+
...getServePath(serveDir, a.serveDir ?? ''),
6868
};
6969
});
7070
}

src/config.test.js

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('config', () => {
2323
expect(config).toEqual({
2424
audits: [
2525
{
26-
path: undefined,
26+
serveDir: undefined,
2727
url: undefined,
2828
thresholds: {},
2929
},
@@ -40,7 +40,7 @@ describe('config', () => {
4040
expect(config).toEqual({
4141
audits: [
4242
{
43-
path: 'PUBLISH_DIR',
43+
serveDir: 'PUBLISH_DIR',
4444
url: 'AUDIT_URL',
4545
thresholds: { performance: 0.9 },
4646
},
@@ -52,14 +52,18 @@ describe('config', () => {
5252
process.env.PUBLISH_DIR = 'PUBLISH_DIR';
5353
process.env.AUDITS = JSON.stringify([
5454
{ url: 'https://www.test.com', thresholds: { performance: 0.9 } },
55-
{ path: 'route1', thresholds: { seo: 0.9 } },
55+
{ serveDir: 'route1', thresholds: { seo: 0.9 } },
5656
]);
5757
const config = getConfiguration();
5858

5959
expect(config).toEqual({
6060
audits: [
61-
{ url: 'https://www.test.com', thresholds: { performance: 0.9 } },
62-
{ path: 'PUBLISH_DIR/route1', thresholds: { seo: 0.9 } },
61+
{
62+
url: 'https://www.test.com',
63+
thresholds: { performance: 0.9 },
64+
serveDir: 'PUBLISH_DIR',
65+
},
66+
{ serveDir: 'PUBLISH_DIR/route1', thresholds: { seo: 0.9 } },
6367
],
6468
});
6569
});
@@ -87,7 +91,7 @@ describe('config', () => {
8791
expect(config).toEqual({
8892
audits: [
8993
{
90-
path: 'PUBLISH_DIR',
94+
serveDir: 'PUBLISH_DIR',
9195
url: 'url',
9296
thresholds: { seo: 1 },
9397
output_path: 'reports/lighthouse.html',
@@ -96,37 +100,40 @@ describe('config', () => {
96100
});
97101
});
98102

99-
it('should append audits path to PUBLISH_DIR', () => {
103+
it('should append audits serveDir to PUBLISH_DIR', () => {
100104
const constants = { PUBLISH_DIR: 'PUBLISH_DIR' };
101-
const inputs = { audits: [{ path: 'route1', thresholds: { seo: 1 } }] };
105+
const inputs = { audits: [{ serveDir: 'route1', thresholds: { seo: 1 } }] };
102106
const config = getConfiguration({ constants, inputs });
103107

104108
expect(config).toEqual({
105-
audits: [{ path: 'PUBLISH_DIR/route1', thresholds: { seo: 1 } }],
109+
audits: [{ serveDir: 'PUBLISH_DIR/route1', thresholds: { seo: 1 } }],
106110
});
107111
});
108112

109113
it('should use default thresholds when no audit thresholds is configured', () => {
110114
const constants = { PUBLISH_DIR: 'PUBLISH_DIR' };
111115
const inputs = {
112116
thresholds: { performance: 1 },
113-
audits: [{ path: 'route1', thresholds: { seo: 1 } }, { path: 'route2' }],
117+
audits: [
118+
{ serveDir: 'route1', thresholds: { seo: 1 } },
119+
{ serveDir: 'route2' },
120+
],
114121
};
115122
const config = getConfiguration({ constants, inputs });
116123

117124
expect(config).toEqual({
118125
audits: [
119-
{ path: 'PUBLISH_DIR/route1', thresholds: { seo: 1 } },
120-
{ path: 'PUBLISH_DIR/route2', thresholds: { performance: 1 } },
126+
{ serveDir: 'PUBLISH_DIR/route1', thresholds: { seo: 1 } },
127+
{ serveDir: 'PUBLISH_DIR/route2', thresholds: { performance: 1 } },
121128
],
122129
});
123130
});
124131

125-
it('should throw error on path traversal', () => {
132+
it('should throw error on serveDir path traversal', () => {
126133
const constants = { PUBLISH_DIR: 'PUBLISH_DIR' };
127134
const inputs = {
128135
thresholds: { performance: 1 },
129-
audits: [{ path: '../' }],
136+
audits: [{ serveDir: '../' }],
130137
};
131138

132139
expect(() => getConfiguration({ constants, inputs })).toThrow(
@@ -136,16 +143,16 @@ describe('config', () => {
136143
);
137144
});
138145

139-
it('should treat audit path as relative path', () => {
146+
it('should treat audit serveDir as relative path', () => {
140147
const constants = { PUBLISH_DIR: 'PUBLISH_DIR' };
141148
const inputs = {
142-
audits: [{ path: '/a/b' }],
149+
audits: [{ serveDir: '/a/b' }],
143150
};
144151

145152
const config = getConfiguration({ constants, inputs });
146153

147154
expect(config).toEqual({
148-
audits: [{ path: 'PUBLISH_DIR/a/b', thresholds: {} }],
155+
audits: [{ serveDir: 'PUBLISH_DIR/a/b', thresholds: {} }],
149156
});
150157
});
151158

@@ -182,21 +189,21 @@ describe('config', () => {
182189
const inputs = {
183190
output_path: 'reports/lighthouse.html',
184191
audits: [
185-
{ path: 'route1' },
186-
{ path: 'route2', output_path: 'reports/route2.html' },
192+
{ serveDir: 'route1' },
193+
{ serveDir: 'route2', output_path: 'reports/route2.html' },
187194
],
188195
};
189196
const config = getConfiguration({ constants, inputs });
190197

191198
expect(config).toEqual({
192199
audits: [
193200
{
194-
path: 'PUBLISH_DIR/route1',
201+
serveDir: 'PUBLISH_DIR/route1',
195202
output_path: 'reports/lighthouse.html',
196203
thresholds: {},
197204
},
198205
{
199-
path: 'PUBLISH_DIR/route2',
206+
serveDir: 'PUBLISH_DIR/route2',
200207
output_path: 'reports/route2.html',
201208
thresholds: {},
202209
},

0 commit comments

Comments
 (0)