Unverified Commit fa0a4c04 authored by flutteractionsbot's avatar flutteractionsbot Committed by GitHub

[CP-beta]Copy part files and sourcemaps when building with dart2js. (#146361)

This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process#automatically-creates-a-cherry-pick-request)

### Issue Link:
https://github.com/flutter/flutter/issues/145653

### Changelog Description:
Fixes and issue where dart2js deferred part files were not being properly emitted by a web build.

### Impact Description:
Users who use deferred loading in dart2js will not have any of the deferred JS files copied to their build directory.

### Workaround:
Users can manually copy the part files out of the `.dart_tool/flutter_build` directory into their `build/web` folder.

### Risk:
What is the risk level of this cherry-pick?

### Test Coverage:
Are you confident that your fix is well-tested by automated tests?

### Validation Steps:
Follow the repro steps listed in https://github.com/flutter/flutter/issues/145653.
Ensure that the `build/web` folder contains the `main.dart.js_1.part.js` and `main.dart.js_1.part.js.map` files.
parent 20078535
...@@ -93,7 +93,6 @@ class WebEntrypointTarget extends Target { ...@@ -93,7 +93,6 @@ class WebEntrypointTarget extends Target {
} }
} }
/// Compiles a web entry point with dart2js.
abstract class Dart2WebTarget extends Target { abstract class Dart2WebTarget extends Target {
const Dart2WebTarget(); const Dart2WebTarget();
...@@ -102,7 +101,8 @@ abstract class Dart2WebTarget extends Target { ...@@ -102,7 +101,8 @@ abstract class Dart2WebTarget extends Target {
WebCompilerConfig get compilerConfig; WebCompilerConfig get compilerConfig;
Map<String, Object?> get buildConfig; Map<String, Object?> get buildConfig;
List<String> get buildFiles; Iterable<File> buildFiles(Environment environment);
Iterable<String> get buildPatternStems;
@override @override
List<Target> get dependencies => const <Target>[ List<Target> get dependencies => const <Target>[
...@@ -120,14 +120,15 @@ abstract class Dart2WebTarget extends Target { ...@@ -120,14 +120,15 @@ abstract class Dart2WebTarget extends Target {
]; ];
@override @override
List<Source> get outputs => buildFiles.map( List<Source> get outputs => <Source>[
(String file) => Source.pattern('{BUILD_DIR}/$file') for (final String stem in buildPatternStems) Source.pattern('{BUILD_DIR}/$stem'),
).toList(); ];
@override @override
String get buildKey => compilerConfig.buildKey; String get buildKey => compilerConfig.buildKey;
} }
/// Compiles a web entry point with dart2js.
class Dart2JSTarget extends Dart2WebTarget { class Dart2JSTarget extends Dart2WebTarget {
Dart2JSTarget(this.compilerConfig); Dart2JSTarget(this.compilerConfig);
...@@ -230,12 +231,43 @@ class Dart2JSTarget extends Dart2WebTarget { ...@@ -230,12 +231,43 @@ class Dart2JSTarget extends Dart2WebTarget {
}; };
@override @override
List<String> get buildFiles => <String>[ Iterable<File> buildFiles(Environment environment)
=> environment.buildDir
.listSync(recursive: true)
.whereType<File>()
.where((File file) {
if (file.basename == 'main.dart.js') {
return true;
}
if (file.basename == 'main.dart.js.map') {
return compilerConfig.sourceMaps;
}
final RegExp partFileRegex = RegExp(r'main\.dart\.js_[0-9].*\.part\.js');
if (partFileRegex.hasMatch(file.basename)) {
return true;
}
if (compilerConfig.sourceMaps) {
final RegExp partFileSourceMapRegex = RegExp(r'main\.dart\.js_[0-9].*.part\.js\.map');
if (partFileSourceMapRegex.hasMatch(file.basename)) {
return true;
}
}
return false;
});
@override
Iterable<String> get buildPatternStems => <String>[
'main.dart.js', 'main.dart.js',
if (compilerConfig.sourceMaps) 'main.dart.js.map', 'main.dart.js_*.part.js',
if (compilerConfig.sourceMaps) ...<String>[
'main.dart.js.map',
'main.dart.js_*.part.js.map',
],
]; ];
} }
/// Compiles a web entry point with dart2wasm.
class Dart2WasmTarget extends Dart2WebTarget { class Dart2WasmTarget extends Dart2WebTarget {
Dart2WasmTarget(this.compilerConfig); Dart2WasmTarget(this.compilerConfig);
...@@ -273,7 +305,7 @@ class Dart2WasmTarget extends Dart2WebTarget { ...@@ -273,7 +305,7 @@ class Dart2WasmTarget extends Dart2WebTarget {
if (compilerConfig.renderer == WebRendererMode.skwasm) ...<String>[ if (compilerConfig.renderer == WebRendererMode.skwasm) ...<String>[
'--extra-compiler-option=--import-shared-memory', '--extra-compiler-option=--import-shared-memory',
'--extra-compiler-option=--shared-memory-max-pages=32768', '--extra-compiler-option=--shared-memory-max-pages=32768',
], ],
if (buildMode == BuildMode.profile) if (buildMode == BuildMode.profile)
'-Ddart.vm.profile=true' '-Ddart.vm.profile=true'
else else
...@@ -320,7 +352,17 @@ class Dart2WasmTarget extends Dart2WebTarget { ...@@ -320,7 +352,17 @@ class Dart2WasmTarget extends Dart2WebTarget {
}; };
@override @override
List<String> get buildFiles => <String>[ Iterable<File> buildFiles(Environment environment)
=> environment.buildDir
.listSync(recursive: true)
.whereType<File>()
.where((File file) => switch (file.basename) {
'main.dart.wasm' || 'main.dart.mjs' => true,
_ => false,
});
@override
Iterable<String> get buildPatternStems => const <String>[
'main.dart.wasm', 'main.dart.wasm',
'main.dart.mjs', 'main.dart.mjs',
]; ];
...@@ -361,11 +403,6 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)}; ...@@ -361,11 +403,6 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)};
final List<Dart2WebTarget> compileTargets; final List<Dart2WebTarget> compileTargets;
final WebTemplatedFiles templatedFilesTarget; final WebTemplatedFiles templatedFilesTarget;
List<String> get buildFiles => compileTargets.fold(
const Iterable<String>.empty(),
(Iterable<String> current, Dart2WebTarget target) => current.followedBy(target.buildFiles)
).toList();
@override @override
String get name => 'web_release_bundle'; String get name => 'web_release_bundle';
...@@ -375,15 +412,19 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)}; ...@@ -375,15 +412,19 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)};
templatedFilesTarget, templatedFilesTarget,
]; ];
Iterable<String> get buildPatternStems => compileTargets.expand(
(Dart2WebTarget target) => target.buildPatternStems,
);
@override @override
List<Source> get inputs => <Source>[ List<Source> get inputs => <Source>[
const Source.pattern('{PROJECT_DIR}/pubspec.yaml'), const Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
...buildFiles.map((String file) => Source.pattern('{BUILD_DIR}/$file')) ...buildPatternStems.map((String file) => Source.pattern('{BUILD_DIR}/$file'))
]; ];
@override @override
List<Source> get outputs => <Source>[ List<Source> get outputs => <Source>[
...buildFiles.map((String file) => Source.pattern('{OUTPUT_DIR}/$file')) ...buildPatternStems.map((String file) => Source.pattern('{OUTPUT_DIR}/$file'))
]; ];
@override @override
...@@ -395,9 +436,8 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)}; ...@@ -395,9 +436,8 @@ _flutter.buildConfig = ${jsonEncode(buildConfig)};
@override @override
Future<void> build(Environment environment) async { Future<void> build(Environment environment) async {
final FileSystem fileSystem = environment.fileSystem; final FileSystem fileSystem = environment.fileSystem;
for (final File outputFile in environment.buildDir.listSync(recursive: true).whereType<File>()) { for (final Dart2WebTarget target in compileTargets) {
final String basename = fileSystem.path.basename(outputFile.path); for (final File outputFile in target.buildFiles(environment)) {
if (buildFiles.contains(basename)) {
outputFile.copySync( outputFile.copySync(
environment.outputDir.childFile(fileSystem.path.basename(outputFile.path)).path environment.outputDir.childFile(fileSystem.path.basename(outputFile.path)).path
); );
......
...@@ -170,6 +170,8 @@ void main() { ...@@ -170,6 +170,8 @@ void main() {
..writeAsStringSync('A'); ..writeAsStringSync('A');
environment.buildDir.childFile('main.dart.js').createSync(); environment.buildDir.childFile('main.dart.js').createSync();
environment.buildDir.childFile('main.dart.js.map').createSync(); environment.buildDir.childFile('main.dart.js.map').createSync();
environment.buildDir.childFile('main.dart.js_1.part.js').createSync();
environment.buildDir.childFile('main.dart.js_1.part.js.map').createSync();
await WebReleaseBundle(<WebCompilerConfig>[ await WebReleaseBundle(<WebCompilerConfig>[
const JsCompilerConfig() const JsCompilerConfig()
...@@ -181,6 +183,10 @@ void main() { ...@@ -181,6 +183,10 @@ void main() {
.existsSync(), true); .existsSync(), true);
expect(environment.outputDir.childFile('main.dart.js.map') expect(environment.outputDir.childFile('main.dart.js.map')
.existsSync(), true); .existsSync(), true);
expect(environment.outputDir.childFile('main.dart.js_1.part.js')
.existsSync(), true);
expect(environment.outputDir.childFile('main.dart.js_1.part.js.map')
.existsSync(), true);
expect(environment.outputDir.childDirectory('assets') expect(environment.outputDir.childDirectory('assets')
.childFile('AssetManifest.bin.json').existsSync(), true); .childFile('AssetManifest.bin.json').existsSync(), true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment