Skip to content

Commit

Permalink
[bundlephobia] add badge for the npm package size (#1481)
Browse files Browse the repository at this point in the history
* Added a shield for calculating npm bundle sizes

* Fix linting errors

* Fixed badges for bundlephobia

* Remove un-required keywords

* Simplified handler based on feedback

* Use isFileSize for validation

* Convert camel-cased error codes to space separated ones

* Updated error format

* Fixed error formatting

* Renamed gzip to minzip

* Fixes lint error

* Remove test that times out

* refactor tests to make it more readable

* meaningless change

* use trim
  • Loading branch information
tlaziuk authored and paulmelnikow committed Feb 3, 2018
1 parent cbb263b commit 8ad176d
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
14 changes: 14 additions & 0 deletions lib/all-badge-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,20 @@ const allBadgeExamples = [
'node'
]
},
{
title: 'npm bundle size (minified)',
previewUri: '/bundlephobia/min/react.svg',
keywords: [
'node'
]
},
{
title: 'npm bundle size (minified + gzip)',
previewUri: '/bundlephobia/minzip/react.svg',
keywords: [
'node'
]
},
{
title: 'node',
previewUri: '/node/v/passport.svg',
Expand Down
55 changes: 55 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7613,6 +7613,61 @@ camp.route(/^\/nsp\/npm\/(?:@([^/]+)?\/)?([^/]+)?(?:\/([^/]+)?)?\.(svg|png|gif|j
}
}));

// bundle size for npm packages
camp.route(/^\/bundlephobia\/(min|minzip)\/(?:@([^/]+)?\/)?([^/]+)?(?:\/([^/]+)?)?\.(svg|png|gif|jpg|json)?$/,
cache((data, match, sendBadge, request) => {
// A: /bundlephobia/(min|minzip)/:package.:format
// B: /bundlephobia/(min|minzip)/:package/:version.:format
// C: /bundlephobia/(min|minzip)/@:scope/:package.:format
// D: /bundlephobia/(min|minzip)/@:scope/:package/:version.:format
const resultType = match[1];
const scope = match[2];
const packageName = match[3];
const packageVersion = match[4];
const format = match[5];
const showMin = resultType === 'min';

const badgeData = getBadgeData(showMin ? 'minified size' : 'minzipped size', data);

let packageString = typeof scope === 'string' ?
`@${scope}/${packageName}` : packageName;

if(packageVersion) {
packageString += `@${packageVersion}`;
}

const requestOptions = {
url: 'https://bundlephobia.com/api/size',
qs: {
package: packageString,
},
json: true,
};

/**
* `ErrorCode` => `error code`
* @param {string} code
* @returns {string}
*/
const formatErrorCode = (code) =>
code.replace(/([A-Z])/g, ' $1').trim().toLowerCase();

request(requestOptions, (error, response, body) => {
if(typeof body !== 'object' || body === null) {
badgeData.text[1] = 'error';
badgeData.colorscheme = 'red';
} else if (error !== null || body.error) {
badgeData.text[1] = 'code' in body.error ?
formatErrorCode(body.error.code) : 'error';
badgeData.colorscheme = 'red';
} else {
badgeData.text[1] = prettyBytes(showMin ? body.size : body.gzip);
badgeData.colorscheme = 'blue';
}
sendBadge(format, badgeData);
});
}));

// Redmine plugin rating.
camp.route(/^\/redmine\/plugin\/(rating|stars)\/(.*)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
Expand Down
78 changes: 78 additions & 0 deletions service-tests/bundlephobia.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict'

const Joi = require('joi')
const ServiceTester = require('./runner/service-tester')
const { isFileSize } = require('./helpers/validators')

const t = new ServiceTester({
id: 'bundlephobia', title: 'NPM package bundle size',
})

module.exports = t

const formats = {
A: '/bundlephobia/:type/:package.:format',
B: '/bundlephobia/:type/:package/:version.:format',
C: '/bundlephobia/:type/@:scope/:package.:format',
D: '/bundlephobia/:type/@:scope/:package/:version.:format',
}

const data = [
{
format: formats.A,
get: '/min/preact.json',
expect: { name: 'minified size', value: isFileSize },
},
{
format: formats.B,
get: '/min/preact/8.0.0.json',
expect: { name: 'minified size', value: '7.94 kB' },
},
{
format: formats.C,
get: '/min/@cycle/core.json',
expect: { name: 'minified size', value: isFileSize },
},
{
format: formats.D,
get: '/min/@cycle/core/7.0.0.json',
expect: { name: 'minified size', value: '3.51 kB' },
},
{
format: formats.A,
get: '/minzip/preact.json',
expect: { name: 'minzipped size', value: isFileSize },
},
{
format: formats.B,
get: '/minzip/preact/8.0.0.json',
expect: { name: 'minzipped size', value: '3.35 kB' },
},
{
format: formats.C,
get: '/minzip/@cycle/core.json',
expect: { name: 'minzipped size', value: isFileSize },
},
{
format: formats.D,
get: '/minzip/@cycle/core/7.0.0.json',
expect: { name: 'minzipped size', value: '1.23 kB' },
},
{
format: formats.A,
get: '/min/some-no-exist.json',
expect: { name: 'minified size', value: 'package not found error' },
},
{
format: formats.C,
get: '/min/@some-no-exist/some-no-exist.json',
expect: { name: 'minified size', value: 'package not found error' },
}
]

data.forEach( ({format, get, expect }) => {
t.create(`Testing format '${format}' against '${get}'`)
.get(get)
.expectJSONTypes(Joi.object().keys(expect))
}
)

0 comments on commit 8ad176d

Please sign in to comment.