@@ -11,6 +11,7 @@ const stripBanner = require('rollup-plugin-strip-banner');
1111const chalk = require ( 'chalk' ) ;
1212const resolve = require ( '@rollup/plugin-node-resolve' ) . nodeResolve ;
1313const fs = require ( 'fs' ) ;
14+ const path = require ( 'path' ) ;
1415const argv = require ( 'minimist' ) ( process . argv . slice ( 2 ) ) ;
1516const Modules = require ( './modules' ) ;
1617const Bundles = require ( './bundles' ) ;
@@ -148,6 +149,7 @@ function getBabelConfig(
148149 presets : [ ] ,
149150 plugins : [ ...babelPlugins ] ,
150151 babelHelpers : 'bundled' ,
152+ sourcemap : false ,
151153 } ;
152154 if ( isDevelopment ) {
153155 options . plugins . push (
@@ -386,6 +388,25 @@ function getPlugins(
386388
387389 const { isUMDBundle, shouldStayReadable} = getBundleTypeFlags ( bundleType ) ;
388390
391+ const needsMinifiedByClosure = isProduction && bundleType !== ESM_PROD ;
392+
393+ // Any other packages that should specifically _not_ have sourcemaps
394+ const sourcemapPackageExcludes = [
395+ // Having `//#sourceMappingUrl` in this file breaks `ReactDevToolsHooksIntegration-test.js`,
396+ // and this is an internal-only package that doesn't need sourcemaps anyway
397+ 'react-debug-tools' ,
398+ ] ;
399+
400+ // Only generate sourcemaps for true "production" build artifacts
401+ // that will be used by bundlers, such as `react-dom.production.min.js`.
402+ // UMD and "profiling" builds are rarely used and not worth having sourcemaps.
403+ const needsSourcemaps =
404+ needsMinifiedByClosure &&
405+ ! isProfiling &&
406+ ! isUMDBundle &&
407+ ! sourcemapPackageExcludes . includes ( entry ) &&
408+ ! shouldStayReadable ;
409+
389410 return [
390411 // Keep dynamic imports as externals
391412 dynamicImports ( ) ,
@@ -395,7 +416,7 @@ function getPlugins(
395416 const transformed = flowRemoveTypes ( code ) ;
396417 return {
397418 code : transformed . toString ( ) ,
398- map : transformed . generateMap ( ) ,
419+ map : null ,
399420 } ;
400421 } ,
401422 } ,
@@ -424,6 +445,7 @@ function getPlugins(
424445 ) ,
425446 // Remove 'use strict' from individual source files.
426447 {
448+ name : "remove 'use strict'" ,
427449 transform ( source ) {
428450 return source . replace ( / [ ' " ] u s e s t r i c t [ " ' ] / g, '' ) ;
429451 } ,
@@ -443,47 +465,9 @@ function getPlugins(
443465 // I'm going to port "art" to ES modules to avoid this problem.
444466 // Please don't enable this for anything else!
445467 isUMDBundle && entry === 'react-art' && commonjs ( ) ,
446- // Apply dead code elimination and/or minification.
447- // closure doesn't yet support leaving ESM imports intact
448- isProduction &&
449- bundleType !== ESM_PROD &&
450- closure ( {
451- compilation_level : 'SIMPLE' ,
452- language_in : 'ECMASCRIPT_2020' ,
453- language_out :
454- bundleType === NODE_ES2015
455- ? 'ECMASCRIPT_2020'
456- : bundleType === BROWSER_SCRIPT
457- ? 'ECMASCRIPT5'
458- : 'ECMASCRIPT5_STRICT' ,
459- emit_use_strict :
460- bundleType !== BROWSER_SCRIPT &&
461- bundleType !== ESM_PROD &&
462- bundleType !== ESM_DEV ,
463- env : 'CUSTOM' ,
464- warning_level : 'QUIET' ,
465- apply_input_source_maps : false ,
466- use_types_for_optimization : false ,
467- process_common_js_modules : false ,
468- rewrite_polyfills : false ,
469- inject_libraries : false ,
470- allow_dynamic_import : true ,
471-
472- // Don't let it create global variables in the browser.
473- // https://github.com/facebook/react/issues/10909
474- assume_function_wrapper : ! isUMDBundle ,
475- renaming : ! shouldStayReadable ,
476- } ) ,
477- // Add the whitespace back if necessary.
478- shouldStayReadable &&
479- prettier ( {
480- parser : 'flow' ,
481- singleQuote : false ,
482- trailingComma : 'none' ,
483- bracketSpacing : true ,
484- } ) ,
485468 // License and haste headers, top-level `if` blocks.
486469 {
470+ name : 'license-and-headers' ,
487471 renderChunk ( source ) {
488472 return Wrappers . wrapBundle (
489473 source ,
@@ -495,6 +479,85 @@ function getPlugins(
495479 ) ;
496480 } ,
497481 } ,
482+ // Apply dead code elimination and/or minification.
483+ // closure doesn't yet support leaving ESM imports intact
484+ needsMinifiedByClosure &&
485+ closure (
486+ {
487+ compilation_level : 'SIMPLE' ,
488+ language_in : 'ECMASCRIPT_2020' ,
489+ language_out :
490+ bundleType === NODE_ES2015
491+ ? 'ECMASCRIPT_2020'
492+ : bundleType === BROWSER_SCRIPT
493+ ? 'ECMASCRIPT5'
494+ : 'ECMASCRIPT5_STRICT' ,
495+ emit_use_strict :
496+ bundleType !== BROWSER_SCRIPT &&
497+ bundleType !== ESM_PROD &&
498+ bundleType !== ESM_DEV ,
499+ env : 'CUSTOM' ,
500+ warning_level : 'QUIET' ,
501+ source_map_include_content : true ,
502+ use_types_for_optimization : false ,
503+ process_common_js_modules : false ,
504+ rewrite_polyfills : false ,
505+ inject_libraries : false ,
506+ allow_dynamic_import : true ,
507+
508+ // Don't let it create global variables in the browser.
509+ // https://github.com/facebook/react/issues/10909
510+ assume_function_wrapper : ! isUMDBundle ,
511+ renaming : ! shouldStayReadable ,
512+ } ,
513+ { needsSourcemaps}
514+ ) ,
515+ // Add the whitespace back if necessary.
516+ shouldStayReadable &&
517+ prettier ( {
518+ parser : 'flow' ,
519+ singleQuote : false ,
520+ trailingComma : 'none' ,
521+ bracketSpacing : true ,
522+ } ) ,
523+ needsSourcemaps && {
524+ name : 'generate-prod-bundle-sourcemaps' ,
525+ async renderChunk ( codeAfterLicense , chunk , options , meta ) {
526+ // We want to generate a sourcemap that shows the production bundle source
527+ // as it existed before Closure Compiler minified that chunk, rather than
528+ // showing the "original" individual source files. This better shows
529+ // what is actually running in the app.
530+
531+ // Use a path like `node_modules/react/cjs/react.production.min.js.map` for the sourcemap file
532+ const finalSourcemapPath = options . file . replace ( '.js' , '.js.map' ) ;
533+ const finalSourcemapFilename = path . basename ( finalSourcemapPath ) ;
534+
535+ // Read the sourcemap that Closure wrote to disk
536+ const sourcemapAfterClosure = JSON . parse (
537+ fs . readFileSync ( finalSourcemapPath , 'utf8' )
538+ ) ;
539+
540+ // CC generated a file list that only contains the tempfile name.
541+ // Replace that with a more meaningful "source" name for this bundle.
542+ sourcemapAfterClosure . sources = [ filename ] ;
543+ sourcemapAfterClosure . file = filename ;
544+
545+ // Overwrite the Closure-generated file with the final combined sourcemap
546+ fs . writeFileSync (
547+ finalSourcemapPath ,
548+ JSON . stringify ( sourcemapAfterClosure )
549+ ) ;
550+
551+ // Add the sourcemap URL to the actual bundle, so that tools pick it up
552+ const sourceWithMappingUrl =
553+ codeAfterLicense + `\n//# sourceMappingURL=${ finalSourcemapFilename } ` ;
554+
555+ return {
556+ code : sourceWithMappingUrl ,
557+ map : null ,
558+ } ;
559+ } ,
560+ } ,
498561 // Record bundle size.
499562 sizes ( {
500563 getSize : ( size , gzip ) => {
0 commit comments