@@ -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,25 @@ 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` in this file breaks `ReactDevToolsHooksIntegration-test.js`,
396
+ // and this is an internal
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
+
389
410
return [
390
411
// Keep dynamic imports as externals
391
412
dynamicImports ( ) ,
@@ -395,7 +416,7 @@ function getPlugins(
395
416
const transformed = flowRemoveTypes ( code ) ;
396
417
return {
397
418
code : transformed . toString ( ) ,
398
- map : transformed . generateMap ( ) ,
419
+ map : null ,
399
420
} ;
400
421
} ,
401
422
} ,
@@ -424,6 +445,7 @@ function getPlugins(
424
445
) ,
425
446
// Remove 'use strict' from individual source files.
426
447
{
448
+ name : "remove 'use strict'" ,
427
449
transform ( source ) {
428
450
return source . replace ( / [ ' " ] u s e s t r i c t [ " ' ] / g, '' ) ;
429
451
} ,
@@ -443,47 +465,9 @@ function getPlugins(
443
465
// I'm going to port "art" to ES modules to avoid this problem.
444
466
// Please don't enable this for anything else!
445
467
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
468
// License and haste headers, top-level `if` blocks.
486
469
{
470
+ name : 'license-and-headers' ,
487
471
renderChunk ( source ) {
488
472
return Wrappers . wrapBundle (
489
473
source ,
@@ -495,6 +479,85 @@ function getPlugins(
495
479
) ;
496
480
} ,
497
481
} ,
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
+ } ,
498
561
// Record bundle size.
499
562
sizes ( {
500
563
getSize : ( size , gzip ) => {
0 commit comments