From c3c799457c79c6dfc75dc9c1cf28728d8eaac3e1 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Tue, 28 May 2019 11:03:07 -0400 Subject: [PATCH 1/8] First pass at modern JS output --- src/index.js | 32 ++++++++++++++++++++++++-------- src/prog.js | 2 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/index.js b/src/index.js index 657cb0b7..0c7c768e 100644 --- a/src/index.js +++ b/src/index.js @@ -418,9 +418,15 @@ function createConfig(options, entry, format, writeMeta) { : pkg['jsnext:main'] || 'x.mjs', mainNoExtension, ); + let modernMain = replaceName( + (pkg.syntax && pkg.syntax.esmodules) || pkg.esmodule || 'x.modern.mjs', + mainNoExtension, + ); let cjsMain = replaceName(pkg['cjs:main'] || 'x.js', mainNoExtension); let umdMain = replaceName(pkg['umd:main'] || 'x.umd.js', mainNoExtension); + const modern = format === 'modern'; + // let rollupName = safeVariableName(basename(entry).replace(/\.js$/, '')); let nameCache = {}; @@ -560,7 +566,11 @@ function createConfig(options, entry, format, writeMeta) { loose: true, modules: false, targets: - options.target === 'node' ? { node: '8' } : undefined, + options.target === 'node' + ? { node: '8' } + : modern + ? { esmodules: true } + : undefined, exclude: ['transform-async-to-generator'], }, ], @@ -578,7 +588,7 @@ function createConfig(options, entry, format, writeMeta) { require.resolve('babel-plugin-transform-replace-expressions'), { replace: defines }, ], - [ + !modern && [ require.resolve('babel-plugin-transform-async-to-promises'), { inlineHelpers: true, externalHelpers: true }, ], @@ -601,8 +611,8 @@ function createConfig(options, entry, format, writeMeta) { minifyOptions.compress || {}, ), warnings: true, - ecma: 5, - toplevel: format === 'cjs' || format === 'es', + ecma: modern ? 8 : 5, + toplevel: modern || format === 'cjs' || format === 'es', mangle: Object.assign({}, minifyOptions.mangle || {}), nameCache, }), @@ -644,13 +654,19 @@ function createConfig(options, entry, format, writeMeta) { get banner() { return shebang[options.name]; }, - format, + format: modern ? 'es' : format, name: options.name, file: resolve( options.cwd, - (format === 'es' && moduleMain) || - (format === 'umd' && umdMain) || - cjsMain, + { + modern: modernMain, + es: moduleMain, + umd: umdMain, + }[format] || cjsMain, + // (format === 'modern' && modernMain) || + // (format === 'es' && moduleMain) || + // (format === 'umd' && umdMain) || + // cjsMain, ), }, }; diff --git a/src/prog.js b/src/prog.js index a38298fe..d63863e9 100644 --- a/src/prog.js +++ b/src/prog.js @@ -18,7 +18,7 @@ export default handler => { .version(version) .option('--entry, -i', 'Entry module(s)') .option('--output, -o', 'Directory to place build files into') - .option('--format, -f', 'Only build specified formats', 'es,cjs,umd') + .option('--format, -f', 'Only build specified formats', 'modern,es,cjs,umd') .option('--watch, -w', 'Rebuilds on any change', false) .option('--target', 'Specify your target environment (node or web)', 'web') .option('--external', `Specify external dependencies, or 'none'`) From 836de26be952ee0ae8625ad4afc950ad0cdfeaa5 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Fri, 7 Jun 2019 15:44:48 -0400 Subject: [PATCH 2/8] update --- src/prog.js | 6 +++++- test/index.test.js | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/prog.js b/src/prog.js index d63863e9..5e09d9d3 100644 --- a/src/prog.js +++ b/src/prog.js @@ -3,6 +3,10 @@ let { version } = require('../package'); const toArray = val => (Array.isArray(val) ? val : val == null ? [] : [val]); +const ENABLE_MODERN = process.env.MICROBUNDLE_MODERN !== 'false'; + +const DEFAULT_FORMATS = ENABLE_MODERN ? 'modern,es,cjs,umd' : 'es,cjs,umd'; + export default handler => { const cmd = type => (str, opts) => { opts.watch = opts.watch || type === 'watch'; @@ -18,7 +22,7 @@ export default handler => { .version(version) .option('--entry, -i', 'Entry module(s)') .option('--output, -o', 'Directory to place build files into') - .option('--format, -f', 'Only build specified formats', 'modern,es,cjs,umd') + .option('--format, -f', 'Only build specified formats', DEFAULT_FORMATS) .option('--watch, -w', 'Rebuilds on any change', false) .option('--target', 'Specify your target environment (node or web)', 'web') .option('--external', `Specify external dependencies, or 'none'`) diff --git a/test/index.test.js b/test/index.test.js index e7ee2697..db999401 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -4,6 +4,8 @@ import dirTree from 'directory-tree'; import { strip } from './lib/util'; import { buildDirectory, getBuildScript } from '../tools/build-fixture'; +process.env.MICROBUNDLE_MODERN = 'false'; + const FIXTURES_DIR = `${__dirname}/fixtures`; const DEFAULT_SCRIPT = 'microbundle'; const TEST_TIMEOUT = 11000; @@ -58,6 +60,7 @@ describe('fixtures', () => { // we don't realy care about the content of a sourcemap files .filter(file => !/\.map$/.test(file)) + .sort(file => (/modern/.test(file) ? 1 : 0)) .forEach(file => { expect( fs.readFileSync(resolve(dist, file)).toString('utf8'), From 170bc08c3e62752ce583a54c752d550d072a46ea Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Tue, 11 Jun 2019 01:06:57 -0400 Subject: [PATCH 3/8] Modern build with passing tests! --- src/index.js | 2 +- src/prog.js | 6 +- test/__snapshots__/index.test.js.snap | 190 ++++++++++++++++++++++++++ test/fixtures/modern/package.json | 6 + test/fixtures/modern/src/index.js | 5 + test/fixtures/modern/src/two.js | 3 + test/index.test.js | 2 - tools/build-fixture.js | 11 +- 8 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/modern/package.json create mode 100644 test/fixtures/modern/src/index.js create mode 100644 test/fixtures/modern/src/two.js diff --git a/src/index.js b/src/index.js index 0c7c768e..244e4793 100644 --- a/src/index.js +++ b/src/index.js @@ -596,7 +596,7 @@ function createConfig(options, entry, format, writeMeta) { require.resolve('@babel/plugin-proposal-class-properties'), { loose: true }, ], - ], + ].filter(Boolean), }), options.compress !== false && [ terser({ diff --git a/src/prog.js b/src/prog.js index 5e09d9d3..0cc51fe7 100644 --- a/src/prog.js +++ b/src/prog.js @@ -3,11 +3,11 @@ let { version } = require('../package'); const toArray = val => (Array.isArray(val) ? val : val == null ? [] : [val]); -const ENABLE_MODERN = process.env.MICROBUNDLE_MODERN !== 'false'; +export default handler => { + const ENABLE_MODERN = process.env.MICROBUNDLE_MODERN !== 'false'; -const DEFAULT_FORMATS = ENABLE_MODERN ? 'modern,es,cjs,umd' : 'es,cjs,umd'; + const DEFAULT_FORMATS = ENABLE_MODERN ? 'modern,es,cjs,umd' : 'es,cjs,umd'; -export default handler => { const cmd = type => (str, opts) => { opts.watch = opts.watch || type === 'watch'; opts.compress = diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index 538a788c..32a8236c 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -95,6 +95,12 @@ exports[`fixtures build async-iife-ts with microbundle 5`] = ` exports[`fixtures build async-iife-ts with microbundle 6`] = `""`; +exports[`fixtures build async-iife-ts with microbundle 7`] = ` +"!function(){try{console.log(\\"foo\\")}catch(o){return Promise.reject(o)}}(); +//# sourceMappingURL=async-iife-ts.modern.mjs.map +" +`; + exports[`fixtures build async-ts with microbundle 1`] = ` "Used script: microbundle @@ -152,6 +158,12 @@ exports[`fixtures build async-ts with microbundle 6`] = ` " `; +exports[`fixtures build async-ts with microbundle 7`] = ` +"var o=function(){function o(){}return o.prototype.foo=function(){},o}();export{o as MyClass}; +//# sourceMappingURL=async-ts.modern.mjs.map +" +`; + exports[`fixtures build basic with microbundle 1`] = ` "Used script: microbundle @@ -200,6 +212,12 @@ exports[`fixtures build basic with microbundle 5`] = ` " `; +exports[`fixtures build basic with microbundle 6`] = ` +"var r=function(){try{for(var r=arguments.length,e=new Array(r),t=0;t2?e-2:0),o=2;o=0;f--)(o=e[f])&&(l=(c<3?o(l):c>3?o(t,r,l):o(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\"); +//# sourceMappingURL=class-decorators-ts.modern.mjs.map +" +`; + exports[`fixtures build class-properties with microbundle 1`] = ` "Used script: microbundle @@ -705,6 +777,12 @@ exports[`fixtures build class-properties with microbundle 5`] = ` " `; +exports[`fixtures build class-properties with microbundle 6`] = ` +"var t=function(){this.baz=3};t.bar=2;export default new t;export{t as Foo}; +//# sourceMappingURL=class-properties.modern.mjs.map +" +`; + exports[`fixtures build custom-source with microbundle 1`] = ` "Used script: microbundle @@ -753,6 +831,12 @@ exports[`fixtures build custom-source with microbundle 5`] = ` " `; +exports[`fixtures build custom-source with microbundle 6`] = ` +"var r=function(){try{for(var r=arguments.length,e=new Array(r),t=0;t2?e-2:0),l=2;ln+r,0)}export default async function(){return[await n(...arguments),await n(...arguments)]} +//# sourceMappingURL=basic-lib.modern.mjs.map +" +`; + exports[`fixtures build name-custom-amd with microbundle 1`] = ` "Used script: microbundle @@ -1037,6 +1178,12 @@ exports[`fixtures build name-custom-amd with microbundle 5`] = ` " `; +exports[`fixtures build name-custom-amd with microbundle 6`] = ` +"var r=function(){try{for(var r=arguments.length,e=new Array(r),t=0;t total + value, 0); +} diff --git a/test/index.test.js b/test/index.test.js index db999401..ad6baabe 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -4,8 +4,6 @@ import dirTree from 'directory-tree'; import { strip } from './lib/util'; import { buildDirectory, getBuildScript } from '../tools/build-fixture'; -process.env.MICROBUNDLE_MODERN = 'false'; - const FIXTURES_DIR = `${__dirname}/fixtures`; const DEFAULT_SCRIPT = 'microbundle'; const TEST_TIMEOUT = 11000; diff --git a/tools/build-fixture.js b/tools/build-fixture.js index 60c522eb..cf4145f0 100644 --- a/tools/build-fixture.js +++ b/tools/build-fixture.js @@ -12,13 +12,18 @@ const FIXTURES_DIR = resolve(`${__dirname}/../test/fixtures`); const DEFAULT_SCRIPT = 'microbundle'; const parseScript = (() => { - let parsed; - const prog = createProg(_parsed => (parsed = _parsed)); - return script => { + let parsed; + const prog = createProg(_parsed => (parsed = _parsed)); const argv = shellQuote.parse(`node ${script}`); + + // default to non-modern formats + let hasFormats = argv.some(arg => /^(--format|-f)$/.test(arg)); + if (!hasFormats) argv.push('-f', 'es,cjs,umd'); + // assuming {op: 'glob', pattern} for non-string args prog(argv.map(arg => (typeof arg === 'string' ? arg : arg.pattern))); + return parsed; }; })(); From ec3b8c3a7bab6ace0370942cd3cc92e09df33302 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Tue, 11 Jun 2019 01:32:07 -0400 Subject: [PATCH 4/8] update snapshots --- package.json | 2 +- test/__snapshots__/index.test.js.snap | 198 +++----------------------- 2 files changed, 19 insertions(+), 181 deletions(-) diff --git a/package.json b/package.json index b68b5200..4f7780c9 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@babel/preset-flow": "^7.0.0", "asyncro": "^3.0.0", "autoprefixer": "^9.5.1", - "babel-plugin-transform-async-to-promises": "^0.8.10", + "babel-plugin-transform-async-to-promises": "^0.8.11", "babel-plugin-transform-replace-expressions": "^0.2.0", "brotli-size": "^0.1.0", "camelcase": "^5.3.1", diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index 32a8236c..2145cefb 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -65,42 +65,36 @@ async-iife-ts Build \\"asyncIifeTs\\" to dist: -93 B: async-iife-ts.js.gz -74 B: async-iife-ts.js.br -93 B: async-iife-ts.mjs.gz -74 B: async-iife-ts.mjs.br -136 B: async-iife-ts.umd.js.gz -106 B: async-iife-ts.umd.js.br" +100 B: async-iife-ts.js.gz +78 B: async-iife-ts.js.br +100 B: async-iife-ts.mjs.gz +78 B: async-iife-ts.mjs.br +142 B: async-iife-ts.umd.js.gz +105 B: async-iife-ts.umd.js.br" `; exports[`fixtures build async-iife-ts with microbundle 2`] = `7`; exports[`fixtures build async-iife-ts with microbundle 3`] = ` -"!function(){try{console.log(\\"foo\\")}catch(o){return Promise.reject(o)}}(); +"!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(o){return Promise.reject(o)}}(); //# sourceMappingURL=async-iife-ts.js.map " `; exports[`fixtures build async-iife-ts with microbundle 4`] = ` -"!function(){try{console.log(\\"foo\\")}catch(o){return Promise.reject(o)}}(); +"!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(o){return Promise.reject(o)}}(); //# sourceMappingURL=async-iife-ts.mjs.map " `; exports[`fixtures build async-iife-ts with microbundle 5`] = ` -"!function(n){\\"function\\"==typeof define&&define.amd?define(n):n()}(function(){!function(){try{console.log(\\"foo\\")}catch(n){return Promise.reject(n)}}()}); +"!function(e){\\"function\\"==typeof define&&define.amd?define(e):e()}(function(){!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(e){return Promise.reject(e)}}()}); //# sourceMappingURL=async-iife-ts.umd.js.map " `; exports[`fixtures build async-iife-ts with microbundle 6`] = `""`; -exports[`fixtures build async-iife-ts with microbundle 7`] = ` -"!function(){try{console.log(\\"foo\\")}catch(o){return Promise.reject(o)}}(); -//# sourceMappingURL=async-iife-ts.modern.mjs.map -" -`; - exports[`fixtures build async-ts with microbundle 1`] = ` "Used script: microbundle @@ -158,12 +152,6 @@ exports[`fixtures build async-ts with microbundle 6`] = ` " `; -exports[`fixtures build async-ts with microbundle 7`] = ` -"var o=function(){function o(){}return o.prototype.foo=function(){},o}();export{o as MyClass}; -//# sourceMappingURL=async-ts.modern.mjs.map -" -`; - exports[`fixtures build basic with microbundle 1`] = ` "Used script: microbundle @@ -212,12 +200,6 @@ exports[`fixtures build basic with microbundle 5`] = ` " `; -exports[`fixtures build basic with microbundle 6`] = ` -"var r=function(){try{for(var r=arguments.length,e=new Array(r),t=0;t2?e-2:0),o=2;o=0;f--)(o=e[f])&&(l=(c<3?o(l):c>3?o(t,r,l):o(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\"); -//# sourceMappingURL=class-decorators-ts.modern.mjs.map -" -`; - exports[`fixtures build class-properties with microbundle 1`] = ` "Used script: microbundle @@ -777,12 +705,6 @@ exports[`fixtures build class-properties with microbundle 5`] = ` " `; -exports[`fixtures build class-properties with microbundle 6`] = ` -"var t=function(){this.baz=3};t.bar=2;export default new t;export{t as Foo}; -//# sourceMappingURL=class-properties.modern.mjs.map -" -`; - exports[`fixtures build custom-source with microbundle 1`] = ` "Used script: microbundle @@ -831,12 +753,6 @@ exports[`fixtures build custom-source with microbundle 5`] = ` " `; -exports[`fixtures build custom-source with microbundle 6`] = ` -"var r=function(){try{for(var r=arguments.length,e=new Array(r),t=0;t2?e-2:0),l=2;l Date: Wed, 12 Jun 2019 15:23:48 -0400 Subject: [PATCH 5/8] Update upstream async-to-promises dep! --- package.json | 2 +- test/__snapshots__/index.test.js.snap | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 4f7780c9..f155a545 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@babel/preset-flow": "^7.0.0", "asyncro": "^3.0.0", "autoprefixer": "^9.5.1", - "babel-plugin-transform-async-to-promises": "^0.8.11", + "babel-plugin-transform-async-to-promises": "^0.8.12", "babel-plugin-transform-replace-expressions": "^0.2.0", "brotli-size": "^0.1.0", "camelcase": "^5.3.1", diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index 2145cefb..c5338bc6 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -65,30 +65,30 @@ async-iife-ts Build \\"asyncIifeTs\\" to dist: -100 B: async-iife-ts.js.gz -78 B: async-iife-ts.js.br -100 B: async-iife-ts.mjs.gz -78 B: async-iife-ts.mjs.br -142 B: async-iife-ts.umd.js.gz -105 B: async-iife-ts.umd.js.br" +70 B: async-iife-ts.js.gz +55 B: async-iife-ts.js.br +70 B: async-iife-ts.mjs.gz +55 B: async-iife-ts.mjs.br +125 B: async-iife-ts.umd.js.gz +95 B: async-iife-ts.umd.js.br" `; exports[`fixtures build async-iife-ts with microbundle 2`] = `7`; exports[`fixtures build async-iife-ts with microbundle 3`] = ` -"!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(o){return Promise.reject(o)}}(); +"try{console.log(\\"foo\\")}catch(o){Promise.reject(o)} //# sourceMappingURL=async-iife-ts.js.map " `; exports[`fixtures build async-iife-ts with microbundle 4`] = ` -"!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(o){return Promise.reject(o)}}(); +"try{console.log(\\"foo\\")}catch(o){Promise.reject(o)} //# sourceMappingURL=async-iife-ts.mjs.map " `; exports[`fixtures build async-iife-ts with microbundle 5`] = ` -"!function(e){\\"function\\"==typeof define&&define.amd?define(e):e()}(function(){!function(){try{console.log(\\"foo\\"),Promise.resolve()}catch(e){return Promise.reject(e)}}()}); +"!function(e){\\"function\\"==typeof define&&define.amd?define(e):e()}(function(){try{console.log(\\"foo\\")}catch(e){Promise.reject(e)}}); //# sourceMappingURL=async-iife-ts.umd.js.map " `; From ea2cccd61869d70a59f51b3cc703c68b03659a75 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Thu, 13 Jun 2019 17:03:46 -0400 Subject: [PATCH 6/8] Fix modern JS output after extracting babel config. --- package.json | 1 - src/index.js | 16 ++------- src/lib/babel-custom.js | 47 +++++++++++++++++--------- test/__snapshots__/index.test.js.snap | 48 +++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 0ce1fe7b..5f88df72 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "@babel/polyfill": "^7.4.4", "@babel/preset-flow": "^7.0.0", "asyncro": "^3.0.0", - "autoprefixer": "^9.5.1", "autoprefixer": "^9.6.0", "babel-plugin-macros": "^2.4.2", "babel-plugin-transform-async-to-promises": "^0.8.12", diff --git a/src/index.js b/src/index.js index e22c7912..95f7e854 100644 --- a/src/index.js +++ b/src/index.js @@ -570,12 +570,9 @@ function createConfig(options, entry, format, writeMeta) { passPerPreset: true, // @see https://babeljs.io/docs/en/options#passperpreset custom: { defines, - targets: - options.target === 'node' - ? { node: '8' } - : modern - ? { esmodules: true } - : undefined, + modern, + compress: options.compress !== false, + targets: options.target === 'node' ? { node: '8' } : undefined, pragma: options.jsx || 'h', pragmaFrag: options.jsxFragment || 'Fragment', typescript: !!useTypescript, @@ -584,9 +581,6 @@ function createConfig(options, entry, format, writeMeta) { options.compress !== false && [ terser({ sourcemap: true, - output: { - comments: (node, comment) => /[@#]__PURE__/.test(comment.value), - }, compress: Object.assign( { keep_infinity: true, @@ -648,10 +642,6 @@ function createConfig(options, entry, format, writeMeta) { es: moduleMain, umd: umdMain, }[format] || cjsMain, - // (format === 'modern' && modernMain) || - // (format === 'es' && moduleMain) || - // (format === 'umd' && umdMain) || - // cjsMain, ), }, }; diff --git a/src/lib/babel-custom.js b/src/lib/babel-custom.js index 4bd58523..6c5728cd 100644 --- a/src/lib/babel-custom.js +++ b/src/lib/babel-custom.js @@ -3,6 +3,10 @@ import babelPlugin from 'rollup-plugin-babel'; import merge from 'lodash.merge'; import { isTruthy } from '../utils'; +const ESMODULES_TARGET = { + esmodules: true, +}; + const mergeConfigItems = (type, ...configItemsToMerge) => { const mergedItems = []; @@ -64,7 +68,7 @@ export default babelPlugin.custom(babelCore => { name: 'babel-plugin-transform-replace-expressions', replace: customOptions.defines, }, - { + !customOptions.modern && { name: 'babel-plugin-transform-async-to-promises', inlineHelpers: true, externalHelpers: true, @@ -73,7 +77,7 @@ export default babelPlugin.custom(babelCore => { name: '@babel/plugin-proposal-class-properties', loose: true, }, - { + !customOptions.modern && { name: '@babel/plugin-transform-regenerator', async: false, }, @@ -94,19 +98,22 @@ export default babelPlugin.custom(babelCore => { babelOptions.presets[envIdx] = createConfigItem( [ preset.file.resolved, - merge( - { - loose: true, - targets: customOptions.targets, - }, - preset.options, - { - modules: false, - exclude: merge( - ['transform-async-to-generator', 'transform-regenerator'], - preset.options.exclude || [], - ), - }, + Object.assign( + merge( + { + loose: true, + targets: customOptions.targets, + }, + preset.options, + { + modules: false, + exclude: merge( + ['transform-async-to-generator', 'transform-regenerator'], + preset.options.exclude || [], + ), + }, + ), + customOptions.modern ? ESMODULES_TARGET : {}, ), ], { @@ -117,7 +124,9 @@ export default babelPlugin.custom(babelCore => { babelOptions.presets = createConfigItems('preset', [ { name: '@babel/preset-env', - targets: customOptions.targets, + targets: customOptions.modern + ? ESMODULES_TARGET + : customOptions.targets, modules: false, loose: true, exclude: ['transform-async-to-generator', 'transform-regenerator'], @@ -132,6 +141,12 @@ export default babelPlugin.custom(babelCore => { babelOptions.plugins || [], ); + babelOptions.generatorOpts = { + minified: customOptions.compress, + compact: customOptions.compress, + shouldPrintComment: comment => /[@#]__PURE__/.test(comment), + }; + return babelOptions; }, }; diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index 67eea565..a30c18c6 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -1356,6 +1356,54 @@ return function(){function t(){}return t.prototype.render=function(){return n(\\ " `; +exports[`fixtures build macro with microbundle 1`] = ` +"Used script: microbundle + +Directory tree: + +macro + dist + macro-lib.js + macro-lib.js.map + macro-lib.mjs + macro-lib.mjs.map + macro-lib.umd.js + macro-lib.umd.js.map + package.json + src + index.js + macro.js + + +Build \\"macroLib\\" to dist: +49 B: macro-lib.js.gz +33 B: macro-lib.js.br +48 B: macro-lib.mjs.gz +32 B: macro-lib.mjs.br +157 B: macro-lib.umd.js.gz +125 B: macro-lib.umd.js.br" +`; + +exports[`fixtures build macro with microbundle 2`] = `6`; + +exports[`fixtures build macro with microbundle 3`] = ` +"module.exports=\\"name-macro\\"; +//# sourceMappingURL=macro-lib.js.map +" +`; + +exports[`fixtures build macro with microbundle 4`] = ` +"export default\\"name-macro\\"; +//# sourceMappingURL=macro-lib.mjs.map +" +`; + +exports[`fixtures build macro with microbundle 5`] = ` +"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=\\"name-macro\\":\\"function\\"==typeof define&&define.amd?define(function(){return\\"name-macro\\"}):(e=e||self).macroLib=\\"name-macro\\"}(this); +//# sourceMappingURL=macro-lib.umd.js.map +" +`; + exports[`fixtures build modern with microbundle 1`] = ` "Used script: microbundle -f modern From ef7c8d01af36dbecf187b283210c90883b415d5a Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Thu, 13 Jun 2019 17:11:21 -0400 Subject: [PATCH 7/8] update snaps --- test/__snapshots__/index.test.js.snap | 160 ++++++++++---------------- 1 file changed, 62 insertions(+), 98 deletions(-) diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index a30c18c6..fb2fadbf 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -117,36 +117,30 @@ async-ts Build \\"asyncTs\\" to dist: -111 B: async-ts.js.gz -85 B: async-ts.js.br -120 B: async-ts.mjs.gz -105 B: async-ts.mjs.br -207 B: async-ts.umd.js.gz -161 B: async-ts.umd.js.br" +103 B: async-ts.js.gz +72 B: async-ts.js.br +112 B: async-ts.mjs.gz +91 B: async-ts.mjs.br +202 B: async-ts.umd.js.gz +159 B: async-ts.umd.js.br" `; exports[`fixtures build async-ts with microbundle 2`] = `7`; exports[`fixtures build async-ts with microbundle 3`] = ` -"exports.MyClass= -/* */ -function(){function o(){}return o.prototype.foo=function(){return Promise.resolve()},o}(); +"exports.MyClass=function(){function o(){}return o.prototype.foo=function(){return Promise.resolve()},o}(); //# sourceMappingURL=async-ts.js.map " `; exports[`fixtures build async-ts with microbundle 4`] = ` -"var o= -/* */ -function(){function o(){}return o.prototype.foo=function(){return Promise.resolve()},o}();export{o as MyClass}; +"var o=function(){function o(){}return o.prototype.foo=function(){return Promise.resolve()},o}();export{o as MyClass}; //# sourceMappingURL=async-ts.mjs.map " `; exports[`fixtures build async-ts with microbundle 5`] = ` -"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?n(exports):\\"function\\"==typeof define&&define.amd?define([\\"exports\\"],n):n((e=e||self).asyncTs={})}(this,function(e){e.MyClass= -/* */ -function(){function e(){}return e.prototype.foo=function(){return Promise.resolve()},e}()}); +"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?n(exports):\\"function\\"==typeof define&&define.amd?define([\\"exports\\"],n):n((e=e||self).asyncTs={})}(this,function(e){e.MyClass=function(){function e(){}return e.prototype.foo=function(){return Promise.resolve()},e}()}); //# sourceMappingURL=async-ts.umd.js.map " `; @@ -743,36 +737,30 @@ basic-ts Build \\"basicLibTs\\" to dist: -110 B: basic-lib-ts.js.gz -86 B: basic-lib-ts.js.br -104 B: basic-lib-ts.mjs.gz -84 B: basic-lib-ts.mjs.br -193 B: basic-lib-ts.umd.js.gz -150 B: basic-lib-ts.umd.js.br" +104 B: basic-lib-ts.js.gz +76 B: basic-lib-ts.js.br +97 B: basic-lib-ts.mjs.gz +73 B: basic-lib-ts.mjs.br +187 B: basic-lib-ts.umd.js.gz +144 B: basic-lib-ts.umd.js.br" `; exports[`fixtures build basic-ts with microbundle 2`] = `8`; exports[`fixtures build basic-ts with microbundle 3`] = ` -"var n=new( -/* */ -function(){function n(){}return n.prototype.drive=function(n){return!0},n}());module.exports=n; +"var n=new(function(){function n(){}return n.prototype.drive=function(n){return!0},n}());module.exports=n; //# sourceMappingURL=basic-lib-ts.js.map " `; exports[`fixtures build basic-ts with microbundle 4`] = ` -"export default new( -/* */ -function(){function n(){}return n.prototype.drive=function(n){return!0},n}()); +"export default new(function(){function n(){}return n.prototype.drive=function(n){return!0},n}()); //# sourceMappingURL=basic-lib-ts.mjs.map " `; exports[`fixtures build basic-ts with microbundle 5`] = ` -"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=n():\\"function\\"==typeof define&&define.amd?define(n):(e=e||self).basicLibTs=n()}(this,function(){return new( -/* */ -function(){function e(){}return e.prototype.drive=function(e){return!0},e}())}); +"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=n():\\"function\\"==typeof define&&define.amd?define(n):(e=e||self).basicLibTs=n()}(this,function(){return new(function(){function e(){}return e.prototype.drive=function(e){return!0},e}())}); //# sourceMappingURL=basic-lib-ts.umd.js.map " `; @@ -816,36 +804,30 @@ basic-tsx Build \\"basicLibTsx\\" to dist: -245 B: basic-lib-tsx.js.gz -230 B: basic-lib-tsx.js.br -246 B: basic-lib-tsx.mjs.gz -207 B: basic-lib-tsx.mjs.br -324 B: basic-lib-tsx.umd.js.gz -273 B: basic-lib-tsx.umd.js.br" +235 B: basic-lib-tsx.js.gz +188 B: basic-lib-tsx.js.br +239 B: basic-lib-tsx.mjs.gz +191 B: basic-lib-tsx.mjs.br +317 B: basic-lib-tsx.umd.js.gz +260 B: basic-lib-tsx.umd.js.br" `; exports[`fixtures build basic-tsx with microbundle 2`] = `7`; exports[`fixtures build basic-tsx with microbundle 3`] = ` -"var r=function(r,n){for(var e=arguments.length,o=new Array(e>2?e-2:0),t=2;t2?e-2:0),t=2;t2?e-2:0),o=2;o2?e-2:0),o=2;o2?o-2:0),r=2;r2?o-2:0),r=2;r=0;f--)(n=e[f])&&(l=(c<3?n(l):c>3?n(t,r,l):n(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\");module.exports=t; +"var e=function(){function e(e){this.greeting=e}return e.prototype.greet=function(){return\\"Hello, \\"+this.greeting},e}(),t=new(e=function(e,t,r,o){var n,c=arguments.length,l=c<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,r):o;if(\\"object\\"==typeof Reflect&&\\"function\\"==typeof Reflect.decorate)l=Reflect.decorate(e,t,r,o);else for(var f=e.length-1;f>=0;f--)(n=e[f])&&(l=(c<3?n(l):c>3?n(t,r,l):n(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\");module.exports=t; //# sourceMappingURL=class-decorators-ts.js.map " `; exports[`fixtures build class-decorators-ts with microbundle 4`] = ` -"var e= -/* */ -function(){function e(e){this.greeting=e}return e.prototype.greet=function(){return\\"Hello, \\"+this.greeting},e}();export default new(e=function(e,t,r,n){var o,c=arguments.length,l=c<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if(\\"object\\"==typeof Reflect&&\\"function\\"==typeof Reflect.decorate)l=Reflect.decorate(e,t,r,n);else for(var f=e.length-1;f>=0;f--)(o=e[f])&&(l=(c<3?o(l):c>3?o(t,r,l):o(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\"); +"var e=function(){function e(e){this.greeting=e}return e.prototype.greet=function(){return\\"Hello, \\"+this.greeting},e}();export default new(e=function(e,t,r,n){var o,c=arguments.length,l=c<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if(\\"object\\"==typeof Reflect&&\\"function\\"==typeof Reflect.decorate)l=Reflect.decorate(e,t,r,n);else for(var f=e.length-1;f>=0;f--)(o=e[f])&&(l=(c<3?o(l):c>3?o(t,r,l):o(t,r))||l);return c>3&&l&&Object.defineProperty(t,r,l),l}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\"); //# sourceMappingURL=class-decorators-ts.mjs.map " `; exports[`fixtures build class-decorators-ts with microbundle 5`] = ` -"!function(e,t){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=t():\\"function\\"==typeof define&&define.amd?define(t):(e=e||self).classDecoratorsTs=t()}(this,function(){var e= -/* */ -function(){function e(e){this.greeting=e}return e.prototype.greet=function(){return\\"Hello, \\"+this.greeting},e}();return new(e=function(e,t,n,o){var r,f=arguments.length,c=f<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if(\\"object\\"==typeof Reflect&&\\"function\\"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var i=e.length-1;i>=0;i--)(r=e[i])&&(c=(f<3?r(c):f>3?r(t,n,c):r(t,n))||c);return f>3&&c&&Object.defineProperty(t,n,c),c}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\")}); +"!function(e,t){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=t():\\"function\\"==typeof define&&define.amd?define(t):(e=e||self).classDecoratorsTs=t()}(this,function(){var e=function(){function e(e){this.greeting=e}return e.prototype.greet=function(){return\\"Hello, \\"+this.greeting},e}();return new(e=function(e,t,n,o){var r,f=arguments.length,c=f<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if(\\"object\\"==typeof Reflect&&\\"function\\"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var i=e.length-1;i>=0;i--)(r=e[i])&&(c=(f<3?r(c):f>3?r(t,n,c):r(t,n))||c);return f>3&&c&&Object.defineProperty(t,n,c),c}([function(e){Object.seal(e),Object.seal(e.prototype)}],e))(\\"Hello World\\")}); //# sourceMappingURL=class-decorators-ts.umd.js.map " `; @@ -1271,30 +1247,30 @@ esnext-ts Build \\"esnextTs\\" to dist: -878 B: esnext-ts.js.gz -786 B: esnext-ts.js.br -877 B: esnext-ts.mjs.gz -786 B: esnext-ts.mjs.br -938 B: esnext-ts.umd.js.gz -841 B: esnext-ts.umd.js.br" +1022 B: esnext-ts.js.gz +926 B: esnext-ts.js.br +1022 B: esnext-ts.mjs.gz +925 B: esnext-ts.mjs.br +1081 B: esnext-ts.umd.js.gz +982 B: esnext-ts.umd.js.br" `; exports[`fixtures build esnext-ts with microbundle 2`] = `7`; exports[`fixtures build esnext-ts with microbundle 3`] = ` -"var n=function(){function n(){}return n.prototype.then=function(r,e){var o=new n,i=this.s;if(i){var u=1&i?r:e;if(u){try{t(o,1,u(this.v))}catch(n){t(o,2,n)}return o}return this}return this.o=function(n){try{var i=n.v;1&n.s?t(o,1,r?r(i):i):e?t(o,1,e(i)):t(o,2,i)}catch(n){t(o,2,n)}},o},n}();function t(r,e,o){if(!r.s){if(o instanceof n){if(!o.s)return void(o.o=t.bind(null,r,e));1&e&&(e=o.s),o=o.v}if(o&&o.then)return void o.then(t.bind(null,r,e),t.bind(null,r,2));r.s=e,r.v=o;var i=r.o;i&&i(r)}}function r(t){return t instanceof n&&1&t.s}var e=\\"undefined\\"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol(\\"Symbol.iterator\\")):\\"@@iterator\\",o=\\"undefined\\"!=typeof Symbol?Symbol.asyncIterator||(Symbol.asyncIterator=Symbol(\\"Symbol.asyncIterator\\")):\\"@@asyncIterator\\",i=function(){try{var i=[],u=function(i,u,f){if(\\"function\\"==typeof i[o]){var c=function(n){s.next().then(a).then(void 0,h)},a=function(n){n.done?t(l,1):Promise.resolve(u(n.value)).then(c).then(void 0,h)},h=function(n){t(l,2,s.return?s.return().then(function(){return n}):n)},l=new n,s=i[asyncIteratorSymbol]();return s.next().then(a).then(void 0,h),l}return Promise.resolve(function(o,i,u){if(\\"function\\"==typeof o[e]){var f,c,a,h=o[e]();if(function e(o){try{for(;!(f=h.next()).done;)if((o=i(f.value))&&o.then){if(!r(o))return void o.then(e,a||(a=t.bind(null,c=new n,2)));o=o.v}c?t(c,1,o):c=o}catch(n){t(c||(c=new Pact),2,n)}}(),h.return){var l=function(n){try{f.done||h.return()}catch(n){}return n};if(c&&c.then)return c.then(l,function(n){throw l(n)});l()}return c}if(!(\\"length\\"in o))throw new TypeError(\\"Object is not iterable\\");for(var s=[],v=0;v2?e-2:0),l=2;l2?e-2:0),l=2;l2?e-2:0),l=2;l2?e-2:0),l=2;l2?t-2:0),o=2;o2?t-2:0),o=2;o Date: Fri, 14 Jun 2019 16:05:57 -0400 Subject: [PATCH 8/8] fixes and readme update --- README.md | 115 ++++++++++++++++++++++++++-------------- src/index.js | 4 +- src/lib/babel-custom.js | 2 +- 3 files changed, 80 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 39b1c85f..5fb6e5ee 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,42 @@ } ``` +### New: Modern JS + +Microbundle now has a new `modern` format (`microbundle -f modern`). +Modern output still bundles and compresses your code, but it keeps useful syntax +around that actually helps compression: + +```js +// Our source, "src/make-dom.js": +export default async function makeDom(tag, props, children) { + const el = document.createElement(tag); + el.append(...(await children)); + return Object.assign(el, props); +} +``` + +Microbundle compiles the above to this: + +```js +export default async (e, t, a) => { + const n = document.createElement(e); + return n.append(...(await a)), Object.assign(n, t); +}; +``` + +This is enabled by default - all you have to do is add the field to your `package.json`. You might choose to ship modern JS using the "module" field: + +```js +{ + "main": "dist/foo.umd.js", // legacy UMD bundle (for Node & CDN's) + "module": "dist/foo.modern.mjs", // modern ES2017 bundle + "scripts": { + "build": "microbundle src/foo.js -f modern,umd" + } +} +``` + ## 📦 Usage Microbundle includes two commands - `build` (the default) and `watch`. Neither require any options, but you can tailor things to suit your needs a bit if you like. @@ -76,50 +112,51 @@ Libraries often wish to rename internal object properties or class members to sm ```json { - "mangle": { - "regex": "^_" - } + "mangle": { + "regex": "^_" + } } ``` + ### All CLI Options ``` - Usage - $ microbundle [options] - - Available Commands - build Build once and exit - watch Rebuilds on any change - - For more info, run any command with the `--help` flag - $ microbundle build --help - $ microbundle watch --help - - Options - -v, --version Displays current version - -i, --entry Entry module(s) - -o, --output Directory to place build files into - -f, --format Only build specified formats (default es,cjs,umd) - -w, --watch Rebuilds on any change (default false) - --target Specify your target environment (node or web, default web) - --external Specify external dependencies, or 'none' - --globals Specify globals dependencies, or 'none' - --define Replace constants with hard-coded values - --alias Map imports to different modules - --compress Compress output using Terser (default true) - --strict Enforce undefined global context and add "use strict" - --name Specify name exposed in UMD builds - --cwd Use an alternative working directory (default .) - --sourcemap Generate source map (default true) - --raw Show raw byte size (default false) - --jsx A custom JSX pragma like React.createElement (default: h) - -h, --help Displays this message - - Examples - $ microbundle build --globals react=React,jquery=$ - $ microbundle build --define API_KEY=1234 - $ microbundle build --alias react=preact - $ microbundle build --no-sourcemap # don't generate sourcemaps +Usage + $ microbundle [options] + +Available Commands + build Build once and exit + watch Rebuilds on any change + +For more info, run any command with the `--help` flag + $ microbundle build --help + $ microbundle watch --help + +Options + -v, --version Displays current version + -i, --entry Entry module(s) + -o, --output Directory to place build files into + -f, --format Only build specified formats (default modern,es,cjs,umd) + -w, --watch Rebuilds on any change (default false) + --target Specify your target environment (node or web) (default web) + --external Specify external dependencies, or 'none' + --globals Specify globals dependencies, or 'none' + --define Replace constants with hard-coded values + --alias Map imports to different modules + --compress Compress output using Terser + --strict Enforce undefined global context and add "use strict" + --name Specify name exposed in UMD builds + --cwd Use an alternative working directory (default .) + --sourcemap Generate source map (default true) + --raw Show raw byte size (default false) + --jsx A custom JSX pragma like React.createElement (default: h) + -h, --help Displays this message + +Examples + $ microbundle microbundle --globals react=React,jquery=$ + $ microbundle microbundle --define API_KEY=1234 + $ microbundle microbundle --alias react=preact + $ microbundle microbundle --no-sourcemap # don't generate sourcemaps ``` ## 🛣 Roadmap diff --git a/src/index.js b/src/index.js index 95f7e854..52f5fddd 100644 --- a/src/index.js +++ b/src/index.js @@ -585,12 +585,14 @@ function createConfig(options, entry, format, writeMeta) { { keep_infinity: true, pure_getters: true, + // Ideally we'd just get Terser to respect existing Arrow functions... + // unsafe_arrows: true, passes: 10, }, minifyOptions.compress || {}, ), warnings: true, - ecma: modern ? 8 : 5, + ecma: modern ? 9 : 5, toplevel: modern || format === 'cjs' || format === 'es', mangle: Object.assign({}, minifyOptions.mangle || {}), nameCache, diff --git a/src/lib/babel-custom.js b/src/lib/babel-custom.js index 6c5728cd..ce9e9477 100644 --- a/src/lib/babel-custom.js +++ b/src/lib/babel-custom.js @@ -113,7 +113,7 @@ export default babelPlugin.custom(babelCore => { ), }, ), - customOptions.modern ? ESMODULES_TARGET : {}, + customOptions.modern ? { targets: ESMODULES_TARGET } : {}, ), ], {