diff --git a/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap b/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap index e64ebf497a..4dcfd81abf 100644 --- a/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap +++ b/packages/metro-config/src/__tests__/__snapshots__/loadConfig-test.js.snap @@ -131,6 +131,7 @@ Object { }, "output": Object { "ascii_only": true, + "comments": false, "quote_style": 3, "wrap_iife": true, }, @@ -308,6 +309,7 @@ Object { }, "output": Object { "ascii_only": true, + "comments": false, "quote_style": 3, "wrap_iife": true, }, @@ -485,6 +487,7 @@ Object { }, "output": Object { "ascii_only": true, + "comments": false, "quote_style": 3, "wrap_iife": true, }, @@ -662,6 +665,7 @@ Object { }, "output": Object { "ascii_only": true, + "comments": false, "quote_style": 3, "wrap_iife": true, }, diff --git a/packages/metro-config/src/defaults/index.js b/packages/metro-config/src/defaults/index.js index 59142eeb04..4e4cefd124 100644 --- a/packages/metro-config/src/defaults/index.js +++ b/packages/metro-config/src/defaults/index.js @@ -110,6 +110,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({ }, output: { ascii_only: true, + comments: false, quote_style: 3, wrap_iife: true, }, diff --git a/packages/metro-transform-worker/src/__tests__/index-test.js b/packages/metro-transform-worker/src/__tests__/index-test.js index d030e5d6d4..61399ed10a 100644 --- a/packages/metro-transform-worker/src/__tests__/index-test.js +++ b/packages/metro-transform-worker/src/__tests__/index-test.js @@ -12,10 +12,15 @@ 'use strict'; jest - .mock('../utils/getMinifier', () => () => ({code, map}) => ({ - code: code.replace('arbitrary(code)', 'minified(code)'), - map, - })) + .mock('../utils/getMinifier', () => () => ({code, map, config}) => { + const trimmed = config.output.comments + ? code + : code.replace('/*#__PURE__*/', ''); + return { + code: trimmed.replace('arbitrary(code)', 'minified(code)'), + map, + }; + }) .mock('metro-transform-plugins', () => ({ ...jest.requireActual('metro-transform-plugins'), inlinePlugin: () => ({}), @@ -23,7 +28,7 @@ jest })) .mock('metro-minify-terser'); -import type {JsTransformerConfig} from '../index'; +import type {JsTransformerConfig, JsTransformOptions} from '../index'; import typeof TransformerType from '../index'; import typeof FSType from 'fs'; @@ -54,7 +59,7 @@ const baseConfig: JsTransformerConfig = { enableBabelRuntime: true, globalPrefix: '', hermesParser: false, - minifierConfig: {}, + minifierConfig: {output: {comments: false}}, minifierPath: 'minifyModulePath', optimizationSizeLimit: 100000, publicPath: '/assets', @@ -65,6 +70,17 @@ const baseConfig: JsTransformerConfig = { unstable_allowRequireContext: false, }; +const baseTransformOptions: JsTransformOptions = { + dev: true, + hot: false, + inlinePlatform: false, + inlineRequires: false, + minify: false, + platform: 'ios', + type: 'module', + unstable_transformProfile: 'default', +}; + beforeEach(() => { jest.resetModules(); @@ -86,11 +102,7 @@ it('transforms a simple script', async () => { '/root', 'local/file.js', Buffer.from('someReallyArbitrary(code)', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'script', - }, + {...baseTransformOptions, type: 'script'}, ); expect(result.output[0].type).toBe('js/script'); @@ -112,11 +124,7 @@ it('transforms a simple module', async () => { '/root', 'local/file.js', Buffer.from('arbitrary(code)', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); expect(result.output[0].type).toBe('js/module'); @@ -142,11 +150,7 @@ it('transforms a module with dependencies', async () => { '/root', 'local/file.js', Buffer.from(contents, 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); expect(result.output[0].type).toBe('js/module'); @@ -182,11 +186,7 @@ it('transforms an es module with asyncToGenerator', async () => { '/root', 'local/file.js', Buffer.from('export async function test() {}', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); expect(result.output[0].type).toBe('js/module'); @@ -211,11 +211,7 @@ it('transforms async generators', async () => { '/root', 'local/file.js', Buffer.from('export async function* test() { yield "ok"; }', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); expect(result.output[0].data.code).toMatchSnapshot(); @@ -243,12 +239,7 @@ it('transforms import/export syntax when experimental flag is on', async () => { '/root', 'local/file.js', Buffer.from(contents, 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - experimentalImportSupport: true, - type: 'module', - }, + {...baseTransformOptions, experimentalImportSupport: true}, ); expect(result.output[0].type).toBe('js/module'); @@ -279,12 +270,7 @@ it('does not add "use strict" on non-modules', async () => { '/root', 'node_modules/local/file.js', Buffer.from('module.exports = {};', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - experimentalImportSupport: true, - type: 'module', - }, + {...baseTransformOptions, experimentalImportSupport: true}, ); expect(result.output[0].type).toBe('js/module'); @@ -304,11 +290,7 @@ it('preserves require() calls when module wrapping is disabled', async () => { '/root', 'local/file.js', Buffer.from(contents, 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); expect(result.output[0].type).toBe('js/module'); @@ -328,11 +310,7 @@ it('reports filename when encountering unsupported dynamic dependency', async () '/root', 'local/file.js', Buffer.from(contents, 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ); throw new Error('should not reach this'); } catch (error) { @@ -351,11 +329,7 @@ it('supports dynamic dependencies from within `node_modules`', async () => { '/root', 'node_modules/foo/bar.js', Buffer.from('require(foo.bar);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ) ).output[0].data.code, ).toBe( @@ -377,12 +351,7 @@ it('minifies the code correctly', async () => { '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - minify: true, - type: 'module', - }, + {...baseTransformOptions, minify: true}, ) ).output[0].data.code, ).toBe([HEADER_PROD, ' minified(code);', '});'].join('\n')); @@ -396,12 +365,7 @@ it('minifies a JSON file', async () => { '/root', 'local/file.json', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - minify: true, - type: 'module', - }, + {...baseTransformOptions, minify: true}, ) ).output[0].data.code, ).toBe( @@ -424,11 +388,7 @@ it('does not wrap a JSON file when disableModuleWrapping is enabled', async () = '/root', 'local/file.json', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: true, - type: 'module', - }, + baseTransformOptions, ) ).output[0].data.code, ).toBe('module.exports = arbitrary(code);;'); @@ -440,12 +400,7 @@ it('uses a reserved dependency map name and prevents it from being minified', as '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: false, - minify: true, - type: 'module', - }, + {...baseTransformOptions, dev: false, minify: true}, ); expect(result.output[0].data.code).toMatchInlineSnapshot(` "__d(function (g, r, i, a, m, e, THE_DEP_MAP) { @@ -464,12 +419,7 @@ it('throws if the reserved dependency map name appears in the input', async () = 'arbitrary(code); /* the code is not allowed to mention THE_DEP_MAP, even in a comment */', 'utf8', ), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: false, - minify: true, - type: 'module', - }, + {...baseTransformOptions, dev: false, minify: true}, ), ).rejects.toThrowErrorMatchingInlineSnapshot( `"Source code contains the reserved string \`THE_DEP_MAP\` at character offset 55"`, @@ -482,12 +432,7 @@ it('allows disabling the normalizePseudoGlobals pass when minifying', async () = '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: false, - minify: true, - type: 'module', - }, + {...baseTransformOptions, dev: false, minify: true}, ); expect(result.output[0].data.code).toMatchInlineSnapshot(` "__d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) { @@ -502,12 +447,7 @@ it('allows emitting compact code when not minifying', async () => { '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: false, - minify: false, - type: 'module', - }, + {...baseTransformOptions, dev: false, minify: false}, ); expect(result.output[0].data.code).toMatchInlineSnapshot( `"__d(function(global,_$$_REQUIRE,_$$_IMPORT_DEFAULT,_$$_IMPORT_ALL,module,exports,_dependencyMap){arbitrary(code);});"`, @@ -520,11 +460,10 @@ it('skips minification in Hermes stable transform profile', async () => { '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. { + ...baseTransformOptions, dev: false, minify: true, - type: 'module', unstable_transformProfile: 'hermes-canary', }, ); @@ -541,11 +480,10 @@ it('skips minification in Hermes canary transform profile', async () => { '/root', 'local/file.js', Buffer.from('arbitrary(code);', 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. { + ...baseTransformOptions, dev: false, minify: true, - type: 'module', unstable_transformProfile: 'hermes-canary', }, ); @@ -563,12 +501,7 @@ it('counts all line endings correctly', async () => { '/root', 'local/file.js', Buffer.from(str, 'utf8'), - // $FlowFixMe[prop-missing] Added when annotating Transformer. - { - dev: false, - minify: false, - type: 'module', - }, + {...baseTransformOptions, dev: false, minify: false}, ); const differentEndingsResult = await transformStr( @@ -583,3 +516,48 @@ it('counts all line endings correctly', async () => { standardEndingsResult.output[0].data.lineCount, ); }); + +it('outputs comments when `minify: false`', async () => { + const result = await Transformer.transform( + baseConfig, + '/root', + 'local/file.js', + Buffer.from('/*#__PURE__*/arbitrary(code);', 'utf8'), + {...baseTransformOptions, dev: false, minify: false}, + ); + expect(result.output[0].data.code).toMatchInlineSnapshot(` + "__d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) { + /*#__PURE__*/arbitrary(code); + });" + `); +}); + +it('omits comments when `minify: true`', async () => { + const result = await Transformer.transform( + baseConfig, + '/root', + 'local/file.js', + Buffer.from('/*#__PURE__*/arbitrary(code);', 'utf8'), + {...baseTransformOptions, dev: false, minify: true}, + ); + expect(result.output[0].data.code).toMatchInlineSnapshot(` + "__d(function (g, r, i, a, m, e, d) { + minified(code); + });" + `); +}); + +it('allows outputting comments when `minify: true`', async () => { + const result = await Transformer.transform( + {...baseConfig, minifierConfig: {output: {comments: true}}}, + '/root', + 'local/file.js', + Buffer.from('/*#__PURE__*/arbitrary(code);', 'utf8'), + {...baseTransformOptions, dev: false, minify: true}, + ); + expect(result.output[0].data.code).toMatchInlineSnapshot(` + "__d(function (g, r, i, a, m, e, d) { + /*#__PURE__*/minified(code); + });" + `); +}); diff --git a/packages/metro-transform-worker/src/index.js b/packages/metro-transform-worker/src/index.js index 28c05261e0..f369411576 100644 --- a/packages/metro-transform-worker/src/index.js +++ b/packages/metro-transform-worker/src/index.js @@ -299,7 +299,7 @@ async function transformJS( babelrc: false, code: false, configFile: false, - comments: false, + comments: true, filename: file.filename, plugins, sourceMaps: false, @@ -322,7 +322,7 @@ async function transformJS( babelrc: false, code: false, configFile: false, - comments: false, + comments: true, filename: file.filename, plugins: [ [metroTransformPlugins.constantFoldingPlugin, babelPluginOpts], @@ -407,7 +407,7 @@ async function transformJS( const result = generate( wrappedAst, { - comments: false, + comments: true, compact: config.unstable_compactOutput, filename: file.filename, retainLines: false, diff --git a/packages/metro/src/integration_tests/__tests__/__snapshots__/buildGraph-test.js.snap b/packages/metro/src/integration_tests/__tests__/__snapshots__/buildGraph-test.js.snap index 40e783d11a..386f55e8e6 100644 --- a/packages/metro/src/integration_tests/__tests__/__snapshots__/buildGraph-test.js.snap +++ b/packages/metro/src/integration_tests/__tests__/__snapshots__/buildGraph-test.js.snap @@ -5,10 +5,21 @@ Array [ Object { "data": Object { "code": "__d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) { + /** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * + */ + 'use strict'; var Bar = _$$_REQUIRE(_dependencyMap[0]); var Foo = _$$_REQUIRE(_dependencyMap[1]); + // $FlowFixMe: Flow doesn't understand TypeScript var TypeScript = _$$_REQUIRE(_dependencyMap[2]); Object.keys(Object.assign({}, Bar)); module.exports = { @@ -23,297 +34,357 @@ Array [ "", ], }, - "lineCount": 13, + "lineCount": 24, "map": Array [ Array [ 2, 2, - 11, + 1, + 0, + ], + Array [ + 3, + 0, + 2, + 0, + ], + Array [ + 4, + 0, + 3, + 0, + ], + Array [ + 5, + 0, + 4, + 0, + ], + Array [ + 6, + 0, + 5, + 0, + ], + Array [ + 7, + 0, + 6, + 0, + ], + Array [ + 8, + 0, + 7, + 0, + ], + Array [ + 9, + 0, + 8, 0, ], Array [ + 10, + 0, + 9, + 0, + ], + Array [ + 12, 2, + 11, + 0, + ], + Array [ + 12, 14, 11, 12, ], Array [ - 4, + 14, 2, 13, 0, ], Array [ - 4, + 14, 6, 13, 6, "Bar", ], Array [ - 4, + 14, 9, 13, 9, ], Array [ - 4, + 14, 12, 13, 12, "require", ], Array [ - 4, + 14, 23, 13, 19, ], Array [ - 4, + 14, 42, 13, 28, ], Array [ - 5, + 15, 2, 14, 0, ], Array [ - 5, + 15, 6, 14, 6, "Foo", ], Array [ - 5, + 15, 9, 14, 9, ], Array [ - 5, + 15, 12, 14, 12, "require", ], Array [ - 5, + 15, 23, 14, 19, ], Array [ - 5, + 15, 42, 14, 28, ], Array [ - 6, + 16, + 2, + 15, + 0, + ], + Array [ + 17, 2, 16, 0, ], Array [ - 6, + 17, 6, 16, 6, "TypeScript", ], Array [ - 6, + 17, 16, 16, 16, ], Array [ - 6, + 17, 19, 16, 19, "require", ], Array [ - 6, + 17, 30, 16, 26, ], Array [ - 6, + 17, 49, 16, 42, ], Array [ - 7, + 18, 2, 18, 0, "Object", ], Array [ - 7, + 18, 8, 18, 6, ], Array [ - 7, + 18, 9, 18, 7, "keys", ], Array [ - 7, + 18, 13, 18, 11, ], Array [ - 7, + 18, 32, 18, 16, "Bar", ], Array [ - 7, + 18, 35, 18, 19, ], Array [ - 7, + 18, 37, 18, 21, ], Array [ - 8, + 19, 2, 20, 0, "module", ], Array [ - 8, + 19, 8, 20, 6, ], Array [ - 8, + 19, 9, 20, 7, "exports", ], Array [ - 8, + 19, 16, 20, 14, ], Array [ - 8, + 19, 19, 20, 17, ], Array [ - 9, + 20, 4, 20, 18, "Foo", ], Array [ - 9, + 20, 7, 20, 21, ], Array [ - 9, + 20, 9, 20, 18, "Foo", ], Array [ - 9, + 20, 12, 20, 21, ], Array [ - 10, + 21, 4, 20, 23, "Bar", ], Array [ - 10, + 21, 7, 20, 26, ], Array [ - 10, + 21, 9, 20, 23, "Bar", ], Array [ - 10, + 21, 12, 20, 26, ], Array [ - 11, + 22, 4, 20, 28, "TypeScript", ], Array [ - 11, + 22, 14, 20, 38, ], Array [ - 11, + 22, 16, 20, 28, "TypeScript", ], Array [ - 12, + 23, 2, 20, 38, ], Array [ - 12, + 23, 3, 20, 39, ], Array [ - 13, + 24, 0, 20, 40,