diff --git a/CHANGELOG.md b/CHANGELOG.md index 85eb63809e53..9228412a061e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - A bundle for Deno published on [deno.land/x/corejs](https://deno.land/x/corejs) - Updated Samsung Internet compat data mapping up to 15.0 - Updated Opera Mobile compat data mapping up to 63 +- Added `summary` option to `core-js-builder`, see more info in the [`README`](https://github.com/zloirock/core-js/blob/master/packages/core-js-builder/README.md) ##### 3.15.2 - 2021.06.29 - Worked around breakage related to `zone.js` loaded before `core-js`, [#953](https://github.com/zloirock/core-js/issues/953) diff --git a/packages/core-js-builder/README.md b/packages/core-js-builder/README.md index 9a09961e1c62..6526f0e9b7b5 100644 --- a/packages/core-js-builder/README.md +++ b/packages/core-js-builder/README.md @@ -1,14 +1,16 @@ For some cases could be useful to exclude some `core-js` features or generate a polyfill for target engines. This API helps conditionally include or exclude certain parts of [`core-js`](https://github.com/zloirock/core-js), use `browserslist` queries from [`core-js-compat`](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat) package. ```js -require('core-js-builder')({ - modules: ['es', 'esnext.reflect', 'web'], // modules / namespaces, by default - all `core-js` modules - exclude: ['es.math', 'es.number.constructor'], // a blacklist of modules / namespaces, by default - empty list - targets: '> 0.5%', // optional browserslist query - filename: './my-core-js-bundle.js', // optional target filename, if it's missed a file will not be created -}).then(code => { // code of result polyfill - // ... -}).catch(error => { - // ... +const builder = require('@core-js/builder'); + +const bundle = await builder({ + modules: ['es', 'esnext.reflect', 'web'], // modules / namespaces, by default - all `core-js` modules + exclude: ['es.math', 'es.number.constructor'], // a blacklist of modules / namespaces, by default - empty list + targets: '> 0.5%, not dead, ie 9-11', // optional browserslist or core-js-compat format query + summary: { // shows summary for the bundle, disabled by default: + console: { size: true, modules: false }, // in the console, you could specify required parts or set `true` for enable all of them + comment: { size: false, modules: true }, // in the comment in the target file, similarly to `summary.console` + }, + filename: './my-core-js-bundle.js', // optional target filename, if it's missed a file will not be created }); ``` diff --git a/packages/core-js-builder/index.js b/packages/core-js-builder/index.js index 1a506cec94eb..b510a7821e35 100644 --- a/packages/core-js-builder/index.js +++ b/packages/core-js-builder/index.js @@ -14,14 +14,31 @@ const compat = require('core-js-compat/compat'); const modulesList = require('core-js-compat/modules'); const { banner } = require('./config'); +function normalizeSummary(unit = {}) { + let size, modules; + if (typeof unit !== 'object') { + size = modules = !!unit; + } else { + size = !!unit.size; + modules = !!unit.modules; + } return { size, modules }; +} + module.exports = async function ({ blacklist, // TODO: Remove from `core-js@4` exclude = [], modules = modulesList.slice(), targets, filename, + summary = {}, } = {}) { + summary = { comment: normalizeSummary(summary.comment), console: normalizeSummary(summary.console) }; + + const TITLE = filename != null ? filename : '`core-js`'; const set = new Set(); + let script = banner; + let code = ''; + let modulesWithTargets; function filter(method, list) { for (const ns of list) { @@ -40,9 +57,11 @@ module.exports = async function ({ // eslint-disable-next-line sonarjs/no-empty-collection -- false positive modules = modulesList.filter(it => set.has(it)); - if (targets) modules = compat({ targets, filter: modules }).list; - - let script = banner; + if (targets) { + const compatResult = compat({ targets, filter: modules }); + modules = compatResult.list; + modulesWithTargets = compatResult.targets; + } if (modules.length) { const tempFileName = `core-js-${ Math.random().toString(36).slice(2) }.js`; @@ -66,12 +85,30 @@ module.exports = async function ({ await unlink(tempFile); - script += `\n!function (undefined) { 'use strict'; ${ + code = `!function (undefined) { 'use strict'; ${ // compress `__webpack_require__` with `keep_fnames` option String(file).replace(/function __webpack_require__/, 'var __webpack_require__ = function ') } }();`; } + if (summary.comment.size) script += `/*\n * size: ${ (code.length / 1024).toFixed(2) }KB w/o comments\n */`; + if (summary.comment.modules) script += `/*\n * modules list:\n${ modules.map(it => ` * ${ it }\n`).join('') } */`; + if (code) script += `\n${ code }`; + + if (summary.console.size) { + // eslint-disable-next-line no-console -- output + console.log(`\u001B[32mbundling \u001B[36m${ TITLE }\u001B[32m, size: \u001B[36m${ + (script.length / 1024).toFixed(2) + }KB\u001B[0m`); + } + + if (summary.console.modules) { + // eslint-disable-next-line no-console -- output + console.log(`\u001B[32mbundling \u001B[36m${ TITLE }\u001B[32m, modules:\u001B[0m`); + // eslint-disable-next-line no-console -- output + console.log(JSON.stringify(modulesWithTargets || modules, null, ' ')); + } + if (typeof filename != 'undefined') { await mkdirp(dirname(filename)); await writeFile(filename, script);