Skip to content

Commit c5a1e07

Browse files
author
Bryce Kalow
authored
Merge pull request #14 from jzxhuang/feat/custom-build-output-directory
2 parents acea387 + 9ec6626 commit c5a1e07

File tree

13 files changed

+2232
-59
lines changed

13 files changed

+2232
-59
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ Config values are written to `package.json` under the key `nextBundleAnalysis`,
2020

2121
There is one config value, `showDetails`, that is set to "true" by default. This option renders a collapsed "details" section under each section of the bundle analysis comment explaining some of the finer details of the numbers provided. If you feel like this is not necessary and you and/or those working on your project understand the details, you can set this option to `false` and that section will not render.
2222

23+
If your application [builds to a custom directory](https://nextjs.org/docs/api-reference/next.config.js/setting-a-custom-build-directory), you can specify this with the key `buildOutputDirectory`. You will also need to replace all instances of `.next` in `next_bundle_analysis.yml` with your custom output directory.
24+
25+
For example, if you build to `dist`, you should:
26+
27+
- Set `package.json.nextBundleAnalysis.buildOutputDirectory` to `"dist"`.
28+
- In `nextjs_bundle_analysis`, replace all instances of `.next` with `dist`.
29+
2330
### Caveats
2431

2532
- This plugin only analyzes the direct bundle output from next.js. If you have added any other scripts via the `<script>` tag, especially third party scripts and things like analytics or other tracking scripts, these are not included in the analysis. Scripts of this nature should _probably_ be loaded in behind a consent manager and should not make an impact on your initial load, and as long as this is how you handle them it should make no difference, but it's important to be aware of this and account for the extra size added by these scripts if they are present in your app.
File renamed without changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
distDir: 'dist',
3+
}

__tests__/__fixtures__/custom-output-directory/package-lock.json

Lines changed: 2076 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "bundle-analysis-test-fixture",
3+
"version": "1.0.0",
4+
"description": "its a test",
5+
"main": "index.js",
6+
"author": "",
7+
"license": "GPL-2.0",
8+
"dependencies": {
9+
"next": "^11.0.1",
10+
"react": "^17.0.2",
11+
"react-dom": "^17.0.2"
12+
},
13+
"scripts": {
14+
"build": "next build"
15+
},
16+
"nextBundleAnalysis": {
17+
"budget": 358400,
18+
"budgetPercentIncreaseRed": 20,
19+
"buildOutputDirectory": "dist"
20+
}
21+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function IndexPage() {
2+
return <p>hello world</p>
3+
}

__tests__/index.js

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,74 @@ const path = require('path')
22
const fs = require('fs')
33
const { execSync } = require('child_process')
44
const rimraf = require('rimraf')
5-
const { afterAll, beforeAll, expect } = require('@jest/globals')
5+
const { afterEach, beforeEach, expect } = require('@jest/globals')
66
const mkdirp = require('mkdirp')
7+
const { getBuildOutputDirectory, getOptions } = require('../utils')
78

89
const fixturesPath = path.join(__dirname, '__fixtures__')
910

10-
beforeAll(() => {
11-
process.chdir(fixturesPath)
12-
execSync('npm install')
13-
execSync('npm run build')
14-
})
11+
// Get all test suites (fixtures)
12+
const fixtures = fs
13+
.readdirSync(fixturesPath, { withFileTypes: true })
14+
.filter((dirent) => dirent.isDirectory())
15+
.map((dirent) => dirent.name)
1516

16-
afterAll(() => {
17-
rimraf.sync(path.join(fixturesPath, '.next'))
18-
})
17+
describe('sort of integration', () => {
18+
fixtures.forEach((dirName) => {
19+
describe(`fixture ${dirName}`, () => {
20+
const cwd = path.join(fixturesPath, dirName)
21+
const options = getOptions(cwd)
22+
const buildOutputDirectory = getBuildOutputDirectory(options)
23+
24+
beforeEach(() => {
25+
process.chdir(cwd)
26+
execSync('npm install')
27+
execSync('npm run build')
28+
})
29+
30+
afterEach(() => {
31+
rimraf.sync(path.join(cwd, buildOutputDirectory))
32+
})
33+
34+
test(`bundle analysis action generates report and compares artifacts correctly ${dirName}`, () => {
35+
// make sure the 'report' command works
36+
execSync('node ../../../report.js')
37+
const bundleAnalysis = fs.readFileSync(
38+
path.join(
39+
process.cwd(),
40+
buildOutputDirectory,
41+
'analyze/__bundle_analysis.json'
42+
),
43+
'utf8'
44+
)
45+
expect(bundleAnalysis.length).toBeGreaterThan(1)
46+
47+
// create a fake artifact download - in the real world this would pull from
48+
// github as part of the action flow
49+
mkdirp.sync(
50+
path.join(process.cwd(), buildOutputDirectory, 'analyze/base/bundle')
51+
)
52+
fs.writeFileSync(
53+
path.join(
54+
process.cwd(),
55+
buildOutputDirectory,
56+
'analyze/base/bundle/__bundle_analysis.json'
57+
),
58+
bundleAnalysis
59+
)
1960

20-
test('sort of integration', () => {
21-
// make sure the 'report' command works
22-
execSync('node ../../report.js')
23-
const bundleAnalysis = fs.readFileSync(
24-
path.join(process.cwd(), '.next/analyze/__bundle_analysis.json'),
25-
'utf8'
26-
)
27-
expect(bundleAnalysis.length).toBeGreaterThan(1)
28-
29-
// create a fake artifact download - in the real world this would pull from
30-
// github as part of the action flow
31-
mkdirp.sync(path.join(process.cwd(), '.next/analyze/base/bundle'))
32-
fs.writeFileSync(
33-
path.join(
34-
process.cwd(),
35-
'.next/analyze/base/bundle/__bundle_analysis.json'
36-
),
37-
bundleAnalysis
38-
)
39-
40-
// make sure the 'compare' command works
41-
execSync('node ../../compare.js')
42-
const comment = fs.readFileSync(
43-
path.join(process.cwd(), '.next/analyze/__bundle_analysis_comment.txt'),
44-
'utf8'
45-
)
46-
expect(comment).toMatch(/no changes to the javascript bundle/)
61+
// make sure the 'compare' command works
62+
execSync('node ../../../compare.js')
63+
const comment = fs.readFileSync(
64+
path.join(
65+
process.cwd(),
66+
buildOutputDirectory,
67+
'analyze/__bundle_analysis_comment.txt'
68+
),
69+
'utf8'
70+
)
71+
expect(comment).toMatch(/no changes to the javascript bundle/)
72+
})
73+
})
74+
})
4775
})

compare.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,29 @@ const filesize = require('filesize')
44
const numberToWords = require('number-to-words')
55
const fs = require('fs')
66
const path = require('path')
7-
8-
// import the current and base branch bundle stats
9-
const currentBundle = require(path.join(
10-
process.cwd(),
11-
'.next/analyze/__bundle_analysis.json'
12-
))
13-
const baseBundle = require(path.join(
14-
process.cwd(),
15-
'.next/analyze/base/bundle/__bundle_analysis.json'
16-
))
7+
const { getBuildOutputDirectory, getOptions } = require('./utils')
178

189
// Pull options from `package.json`
19-
const options = require(path.join(
20-
process.cwd(),
21-
'package.json'
22-
)).nextBundleAnalysis
10+
const options = getOptions()
2311

2412
const BUDGET = options.budget
2513
const BUDGET_PERCENT_INCREASE_RED = options.budgetPercentIncreaseRed
2614
// this must be explicitly set to false not to render
2715
const SHOW_DETAILS =
2816
options.showDetails === undefined ? true : options.showDetails
17+
const BUILD_OUTPUT_DIRECTORY = getBuildOutputDirectory(options)
18+
19+
// import the current and base branch bundle stats
20+
const currentBundle = require(path.join(
21+
process.cwd(),
22+
BUILD_OUTPUT_DIRECTORY,
23+
'analyze/__bundle_analysis.json'
24+
))
25+
const baseBundle = require(path.join(
26+
process.cwd(),
27+
BUILD_OUTPUT_DIRECTORY,
28+
'analyze/base/bundle/__bundle_analysis.json'
29+
))
2930

3031
// kick it off
3132
let output = `## 📦 Next.js Bundle Analysis
@@ -173,7 +174,11 @@ console.log(output)
173174
// and to cap it off, we write the output to a file which is later read in as comment
174175
// contents by the actions workflow.
175176
fs.writeFileSync(
176-
path.join(process.cwd(), '.next/analyze/__bundle_analysis_comment.txt'),
177+
path.join(
178+
process.cwd(),
179+
BUILD_OUTPUT_DIRECTORY,
180+
'analyze/__bundle_analysis_comment.txt'
181+
),
177182
output.trim()
178183
)
179184

0 commit comments

Comments
 (0)