@@ -11,6 +11,7 @@ const stripBanner = require('rollup-plugin-strip-banner');
11
11
const chalk = require ( 'chalk' ) ;
12
12
const resolve = require ( '@rollup/plugin-node-resolve' ) . nodeResolve ;
13
13
const fs = require ( 'fs' ) ;
14
+ const path = require ( 'path' ) ;
14
15
const argv = require ( 'minimist' ) ( process . argv . slice ( 2 ) ) ;
15
16
const Modules = require ( './modules' ) ;
16
17
const Bundles = require ( './bundles' ) ;
@@ -148,6 +149,7 @@ function getBabelConfig(
148
149
presets : [ ] ,
149
150
plugins : [ ...babelPlugins ] ,
150
151
babelHelpers : 'bundled' ,
152
+ sourcemap : false ,
151
153
} ;
152
154
if ( isDevelopment ) {
153
155
options . plugins . push (
@@ -386,6 +388,27 @@ function getPlugins(
386
388
387
389
const { isUMDBundle, shouldStayReadable} = getBundleTypeFlags ( bundleType ) ;
388
390
391
+ const needsMinifiedByClosure = isProduction && bundleType !== ESM_PROD ;
392
+
393
+ // Any other packages that should specifically _not_ have sourcemaps
394
+ const sourcemapPackageExcludes = [
395
+ // Having `//#sourceMappingUrl` for the `react-debug-tools` prod bundle
396
+ // breaks `ReactDevToolsHooksIntegration-test.js`,because it changes
397
+ // Node's generated stack traces and thus alters the hook name parsing behavior.
398
+ // Also, this is an internal-only package that doesn't need sourcemaps anyway
399
+ 'react-debug-tools' ,
400
+ ] ;
401
+
402
+ // Only generate sourcemaps for true "production" build artifacts
403
+ // that will be used by bundlers, such as `react-dom.production.min.js`.
404
+ // UMD and "profiling" builds are rarely used and not worth having sourcemaps.
405
+ const needsSourcemaps =
406
+ needsMinifiedByClosure &&
407
+ ! isProfiling &&
408
+ ! isUMDBundle &&
409
+ ! sourcemapPackageExcludes . includes ( entry ) &&
410
+ ! shouldStayReadable ;
411
+
389
412
return [
390
413
// Keep dynamic imports as externals
391
414
dynamicImports ( ) ,
@@ -395,7 +418,7 @@ function getPlugins(
395
418
const transformed = flowRemoveTypes ( code ) ;
396
419
return {
397
420
code : transformed . toString ( ) ,
398
- map : transformed . generateMap ( ) ,
421
+ map : null ,
399
422
} ;
400
423
} ,
401
424
} ,
@@ -424,6 +447,7 @@ function getPlugins(
424
447
) ,
425
448
// Remove 'use strict' from individual source files.
426
449
{
450
+ name : "remove 'use strict'" ,
427
451
transform ( source ) {
428
452
return source . replace ( / [ ' " ] u s e s t r i c t [ " ' ] / g, '' ) ;
429
453
} ,
@@ -443,47 +467,9 @@ function getPlugins(
443
467
// I'm going to port "art" to ES modules to avoid this problem.
444
468
// Please don't enable this for anything else!
445
469
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
- } ) ,
485
470
// License and haste headers, top-level `if` blocks.
486
471
{
472
+ name : 'license-and-headers' ,
487
473
renderChunk ( source ) {
488
474
return Wrappers . wrapBundle (
489
475
source ,
@@ -495,6 +481,85 @@ function getPlugins(
495
481
) ;
496
482
} ,
497
483
} ,
484
+ // Apply dead code elimination and/or minification.
485
+ // closure doesn't yet support leaving ESM imports intact
486
+ needsMinifiedByClosure &&
487
+ closure (
488
+ {
489
+ compilation_level : 'SIMPLE' ,
490
+ language_in : 'ECMASCRIPT_2020' ,
491
+ language_out :
492
+ bundleType === NODE_ES2015
493
+ ? 'ECMASCRIPT_2020'
494
+ : bundleType === BROWSER_SCRIPT
495
+ ? 'ECMASCRIPT5'
496
+ : 'ECMASCRIPT5_STRICT' ,
497
+ emit_use_strict :
498
+ bundleType !== BROWSER_SCRIPT &&
499
+ bundleType !== ESM_PROD &&
500
+ bundleType !== ESM_DEV ,
501
+ env : 'CUSTOM' ,
502
+ warning_level : 'QUIET' ,
503
+ source_map_include_content : true ,
504
+ use_types_for_optimization : false ,
505
+ process_common_js_modules : false ,
506
+ rewrite_polyfills : false ,
507
+ inject_libraries : false ,
508
+ allow_dynamic_import : true ,
509
+
510
+ // Don't let it create global variables in the browser.
511
+ // https://github.com/facebook/react/issues/10909
512
+ assume_function_wrapper : ! isUMDBundle ,
513
+ renaming : ! shouldStayReadable ,
514
+ } ,
515
+ { needsSourcemaps}
516
+ ) ,
517
+ // Add the whitespace back if necessary.
518
+ shouldStayReadable &&
519
+ prettier ( {
520
+ parser : 'flow' ,
521
+ singleQuote : false ,
522
+ trailingComma : 'none' ,
523
+ bracketSpacing : true ,
524
+ } ) ,
525
+ needsSourcemaps && {
526
+ name : 'generate-prod-bundle-sourcemaps' ,
527
+ async renderChunk ( codeAfterLicense , chunk , options , meta ) {
528
+ // We want to generate a sourcemap that shows the production bundle source
529
+ // as it existed before Closure Compiler minified that chunk, rather than
530
+ // showing the "original" individual source files. This better shows
531
+ // what is actually running in the app.
532
+
533
+ // Use a path like `node_modules/react/cjs/react.production.min.js.map` for the sourcemap file
534
+ const finalSourcemapPath = options . file . replace ( '.js' , '.js.map' ) ;
535
+ const finalSourcemapFilename = path . basename ( finalSourcemapPath ) ;
536
+
537
+ // Read the sourcemap that Closure wrote to disk
538
+ const sourcemapAfterClosure = JSON . parse (
539
+ fs . readFileSync ( finalSourcemapPath , 'utf8' )
540
+ ) ;
541
+
542
+ // CC generated a file list that only contains the tempfile name.
543
+ // Replace that with a more meaningful "source" name for this bundle.
544
+ sourcemapAfterClosure . sources = [ filename ] ;
545
+ sourcemapAfterClosure . file = filename ;
546
+
547
+ // Overwrite the Closure-generated file with the final combined sourcemap
548
+ fs . writeFileSync (
549
+ finalSourcemapPath ,
550
+ JSON . stringify ( sourcemapAfterClosure )
551
+ ) ;
552
+
553
+ // Add the sourcemap URL to the actual bundle, so that tools pick it up
554
+ const sourceWithMappingUrl =
555
+ codeAfterLicense + `\n//# sourceMappingURL=${ finalSourcemapFilename } ` ;
556
+
557
+ return {
558
+ code : sourceWithMappingUrl ,
559
+ map : null ,
560
+ } ;
561
+ } ,
562
+ } ,
498
563
// Record bundle size.
499
564
sizes ( {
500
565
getSize : ( size , gzip ) => {
0 commit comments