Skip to content

Commit 6a4ecc8

Browse files
authored
chore: add bundle size metrics (#3999)
* chore: add bundle size metrics * fix script * fix script, add config & plugin * update config, cleanup modules * fix deps
1 parent 2ac8009 commit 6a4ecc8

9 files changed

Lines changed: 1737 additions & 531 deletions

File tree

.github/workflows/size-limit.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Bundle Size
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
7+
jobs:
8+
size:
9+
runs-on: ubuntu-latest
10+
env:
11+
CI_JOB_NUMBER: 1
12+
steps:
13+
- uses: actions/checkout@v2
14+
15+
- uses: actions/setup-node@v1
16+
with:
17+
node-version: 12.x
18+
19+
- name: Cache node_modules
20+
uses: actions/cache@v1
21+
id: yarn-cache-node-modules
22+
with:
23+
path: node_modules
24+
key: ${{ runner.os }}-yarn-cache-node-modules-${{ hashFiles('**/yarn.lock') }}
25+
restore-keys: |
26+
${{ runner.os }}-yarn-cache-node-modules-
27+
28+
- name: Yarn install
29+
if: steps.yarn-cache-node-modules.outputs.cache-hit != 'true'
30+
run: yarn install --frozen-lockfile
31+
32+
- uses: andresz1/size-limit-action@v1.4.0
33+
with:
34+
build_script: build:size
35+
github_token: ${{ secrets.GITHUB_TOKEN }}

.size-limit.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = require('glob')
2+
.sync('bundle-size/dist/*.size.js', {
3+
cwd: __dirname,
4+
})
5+
.map((file) => ({ path: file, gzip: false }))

bundle-size/bundle.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
const c = require('ansi-colors')
2+
const glob = require('glob')
3+
const path = require('path')
4+
const terserVersion = require('terser/package.json').version
5+
const TerserWebpackPlugin = require('terser-webpack-plugin')
6+
const webpack = require('webpack')
7+
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
8+
const { argv } = require('yargs')
9+
10+
const config = require('../config')
11+
12+
// Ensures that production settings for Babel are used
13+
process.env.NODE_ENV = 'build-es'
14+
15+
/* eslint-disable no-await-in-loop */
16+
/* eslint-disable no-console */
17+
/* eslint-disable no-restricted-syntax */
18+
19+
//
20+
// Webpack config
21+
//
22+
23+
const makeWebpackConfig = (entry) => ({
24+
devtool: false,
25+
mode: 'production',
26+
name: 'client',
27+
target: 'web',
28+
29+
entry,
30+
output: {
31+
filename: path.basename(entry),
32+
path: config.paths.base('bundle-size', 'dist'),
33+
},
34+
35+
module: {
36+
rules: [
37+
{
38+
test: /\.(js|ts)$/,
39+
loader: 'babel-loader',
40+
exclude: /node_modules/,
41+
options: {
42+
cacheDirectory: true,
43+
},
44+
},
45+
],
46+
},
47+
externals: {
48+
react: 'react',
49+
'react-dom': 'reactDOM',
50+
},
51+
52+
...(argv.debug && {
53+
optimization: {
54+
minimizer: [
55+
new TerserWebpackPlugin({
56+
cache: true,
57+
parallel: true,
58+
sourceMap: false,
59+
60+
terserOptions: {
61+
mangle: false,
62+
output: {
63+
beautify: true,
64+
comments: true,
65+
preserve_annotations: true,
66+
},
67+
},
68+
}),
69+
],
70+
},
71+
}),
72+
73+
performance: {
74+
hints: false,
75+
},
76+
plugins: [
77+
argv.debug &&
78+
new BundleAnalyzerPlugin({
79+
analyzerMode: 'static',
80+
logLevel: 'warn',
81+
openAnalyzer: false,
82+
reportFilename: `${path.basename(entry, '.js')}.html`,
83+
}),
84+
].filter(Boolean),
85+
resolve: {
86+
alias: {
87+
'semantic-ui-react': config.paths.dist('es', 'index.js'),
88+
},
89+
},
90+
})
91+
92+
function webpackAsync(webpackConfig) {
93+
return new Promise((resolve, reject) => {
94+
const compiler = webpack(webpackConfig)
95+
96+
compiler.run((err, stats) => {
97+
if (err) {
98+
reject(err)
99+
}
100+
101+
const info = stats.toJson()
102+
103+
if (stats.hasErrors()) {
104+
reject(new Error(info.errors.toString()))
105+
}
106+
if (stats.hasWarnings()) {
107+
reject(new Error(info.warnings.toString()))
108+
}
109+
110+
resolve(info)
111+
})
112+
})
113+
}
114+
115+
//
116+
//
117+
//
118+
119+
;(async () => {
120+
const fixtures = glob.sync('fixtures/*.size.js', {
121+
cwd: __dirname,
122+
})
123+
124+
console.log(c.cyan(`ℹ Using Webpack ${webpack.version} & Terser ${terserVersion}`))
125+
126+
console.log(c.cyan('ℹ Running following fixtures:'))
127+
console.log(c.cyan(fixtures.map((fixture) => ` - ${fixture}`).join('\n')))
128+
129+
for (const fixture of fixtures) {
130+
const fixturePath = config.paths.base('bundle-size', fixture)
131+
132+
await webpackAsync(makeWebpackConfig(fixturePath))
133+
console.log(c.green(`✔ Completed: ${fixture}`))
134+
}
135+
})()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Button } from 'semantic-ui-react'
2+
import React from 'react'
3+
import ReactDOM from 'react-dom'
4+
5+
function App() {
6+
return <Button>A sample button</Button>
7+
}
8+
9+
ReactDOM.render(<App />, document.querySelector('#root'))

bundle-size/fixtures/Icon.size.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Icon } from 'semantic-ui-react'
2+
import React from 'react'
3+
import ReactDOM from 'react-dom'
4+
5+
function App() {
6+
return <Icon name='book' />
7+
}
8+
9+
ReactDOM.render(<App />, document.querySelector('#root'))

bundle-size/fixtures/Image.size.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Image } from 'semantic-ui-react'
2+
import React from 'react'
3+
import ReactDOM from 'react-dom'
4+
5+
function App() {
6+
return <Image src='image.jpg' />
7+
}
8+
9+
ReactDOM.render(<App />, document.querySelector('#root'))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Portal } from 'semantic-ui-react'
2+
import React from 'react'
3+
import ReactDOM from 'react-dom'
4+
5+
function App() {
6+
return <Portal trigger={<button />}>Some content</Portal>
7+
}
8+
9+
ReactDOM.render(<App />, document.querySelector('#root'))

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"build:changelog": "github_changelog_generator --user Semantic-Org --project Semantic-UI-React --no-issues --no-unreleased --release-branch master --since-tag $(git describe --abbrev=0 --tags $(git rev-parse HEAD~250))",
1919
"build:docs": "cross-env NODE_ENV=production gulp build:docs",
2020
"build:docs:staging": "cross-env STAGING=true yarn build:docs && yarn serve docs/dist",
21-
"build:dist": "gulp --series build:dist",
21+
"build:dist": "gulp build:dist",
22+
"prebuild:size": "gulp build:dist:es",
23+
"build:size": "node bundle-size/bundle.js",
2224
"ci": "yarn tsd:lint && yarn tsd:test && yarn lint && yarn test",
2325
"predeploy:docs": "cross-env NODE_ENV=production yarn build:docs && gulp build:docs:cname",
2426
"deploy:changelog": "git add CHANGELOG.md && git commit -m \"docs(changelog): update changelog [ci skip]\" && git push",
@@ -103,6 +105,7 @@
103105
"@babel/register": "^7.4.4",
104106
"@babel/standalone": "^7.4.5",
105107
"@mdx-js/loader": "^0.20.3",
108+
"@size-limit/file": "^4.5.5",
106109
"@stardust-ui/docs-components": "^0.34.1",
107110
"@types/react": "^16.8.25",
108111
"anchor-js": "^4.2.0",
@@ -171,14 +174,17 @@
171174
"simulant": "^0.2.2",
172175
"sinon": "^7.2.7",
173176
"sinon-chai": "^3.3.0",
177+
"size-limit": "^4.5.5",
174178
"ta-scripts": "^2.5.2",
179+
"terser-webpack-plugin": "^3.0.7",
175180
"terser-webpack-plugin-legacy": "^1.2.3",
176181
"through2": "^3.0.1",
177182
"tslint": "^5.14.0",
178183
"tslint-config-airbnb": "^5.11.1",
179184
"typescript": "^3.3.3333",
180185
"vinyl": "^2.2.0",
181186
"webpack": "^4.28.4",
187+
"webpack-bundle-analyzer": "^3.8.0",
182188
"webpack-cli": "^3.2.1",
183189
"webpack-dev-middleware": "^3.5.0"
184190
},

0 commit comments

Comments
 (0)