mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add tools test for buildWeb compilation (#124179)
Add tools test for buildWeb compilation
This commit is contained in:
parent
6058e95919
commit
385728e7fd
@ -7,6 +7,7 @@ import '../base/file_system.dart';
|
|||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../build_system/targets/web.dart';
|
import '../build_system/targets/web.dart';
|
||||||
import '../features.dart';
|
import '../features.dart';
|
||||||
|
import '../globals.dart' as globals;
|
||||||
import '../html_utils.dart';
|
import '../html_utils.dart';
|
||||||
import '../project.dart';
|
import '../project.dart';
|
||||||
import '../runner/flutter_command.dart'
|
import '../runner/flutter_command.dart'
|
||||||
@ -168,7 +169,14 @@ class BuildWebCommand extends BuildSubCommand {
|
|||||||
final String? outputDirectoryPath = stringArg('output');
|
final String? outputDirectoryPath = stringArg('output');
|
||||||
|
|
||||||
displayNullSafetyMode(buildInfo);
|
displayNullSafetyMode(buildInfo);
|
||||||
await buildWeb(
|
final WebBuilder webBuilder = WebBuilder(
|
||||||
|
logger: globals.logger,
|
||||||
|
buildSystem: globals.buildSystem,
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
flutterVersion: globals.flutterVersion,
|
||||||
|
usage: globals.flutterUsage,
|
||||||
|
);
|
||||||
|
await webBuilder.buildWeb(
|
||||||
flutterProject,
|
flutterProject,
|
||||||
target,
|
target,
|
||||||
buildInfo,
|
buildInfo,
|
||||||
|
@ -314,7 +314,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
device!.generator!.accept();
|
device!.generator!.accept();
|
||||||
cacheInitialDillCompilation();
|
cacheInitialDillCompilation();
|
||||||
} else {
|
} else {
|
||||||
await buildWeb(
|
final WebBuilder webBuilder = WebBuilder(
|
||||||
|
logger: _logger,
|
||||||
|
buildSystem: globals.buildSystem,
|
||||||
|
fileSystem: _fileSystem,
|
||||||
|
flutterVersion: globals.flutterVersion,
|
||||||
|
usage: globals.flutterUsage,
|
||||||
|
);
|
||||||
|
await webBuilder.buildWeb(
|
||||||
flutterProject,
|
flutterProject,
|
||||||
target,
|
target,
|
||||||
debuggingOptions.buildInfo,
|
debuggingOptions.buildInfo,
|
||||||
@ -387,7 +394,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
await buildWeb(
|
final WebBuilder webBuilder = WebBuilder(
|
||||||
|
logger: _logger,
|
||||||
|
buildSystem: globals.buildSystem,
|
||||||
|
fileSystem: _fileSystem,
|
||||||
|
flutterVersion: globals.flutterVersion,
|
||||||
|
usage: globals.flutterUsage,
|
||||||
|
);
|
||||||
|
await webBuilder.buildWeb(
|
||||||
flutterProject,
|
flutterProject,
|
||||||
target,
|
target,
|
||||||
debuggingOptions.buildInfo,
|
debuggingOptions.buildInfo,
|
||||||
|
@ -16,10 +16,31 @@ import '../globals.dart' as globals;
|
|||||||
import '../platform_plugins.dart';
|
import '../platform_plugins.dart';
|
||||||
import '../plugins.dart';
|
import '../plugins.dart';
|
||||||
import '../project.dart';
|
import '../project.dart';
|
||||||
|
import '../reporting/reporting.dart';
|
||||||
|
import '../version.dart';
|
||||||
import 'migrations/scrub_generated_plugin_registrant.dart';
|
import 'migrations/scrub_generated_plugin_registrant.dart';
|
||||||
|
|
||||||
export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel;
|
export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel;
|
||||||
|
|
||||||
|
class WebBuilder {
|
||||||
|
WebBuilder({
|
||||||
|
required Logger logger,
|
||||||
|
required BuildSystem buildSystem,
|
||||||
|
required Usage usage,
|
||||||
|
required FlutterVersion flutterVersion,
|
||||||
|
required FileSystem fileSystem,
|
||||||
|
}) : _logger = logger,
|
||||||
|
_buildSystem = buildSystem,
|
||||||
|
_flutterUsage = usage,
|
||||||
|
_flutterVersion = flutterVersion,
|
||||||
|
_fileSystem = fileSystem;
|
||||||
|
|
||||||
|
final Logger _logger;
|
||||||
|
final BuildSystem _buildSystem;
|
||||||
|
final Usage _flutterUsage;
|
||||||
|
final FlutterVersion _flutterVersion;
|
||||||
|
final FileSystem _fileSystem;
|
||||||
|
|
||||||
Future<void> buildWeb(
|
Future<void> buildWeb(
|
||||||
FlutterProject flutterProject,
|
FlutterProject flutterProject,
|
||||||
String target,
|
String target,
|
||||||
@ -35,38 +56,35 @@ Future<void> buildWeb(
|
|||||||
bool noFrequencyBasedMinification = false,
|
bool noFrequencyBasedMinification = false,
|
||||||
String? outputDirectoryPath,
|
String? outputDirectoryPath,
|
||||||
}) async {
|
}) async {
|
||||||
final bool hasWebPlugins = (await findPlugins(flutterProject))
|
final bool hasWebPlugins =
|
||||||
.any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
|
(await findPlugins(flutterProject)).any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
|
||||||
final Directory outputDirectory = outputDirectoryPath == null
|
final Directory outputDirectory = outputDirectoryPath == null
|
||||||
? globals.fs.directory(getWebBuildDirectory(isWasm))
|
? _fileSystem.directory(getWebBuildDirectory(isWasm))
|
||||||
: globals.fs.directory(outputDirectoryPath);
|
: _fileSystem.directory(outputDirectoryPath);
|
||||||
outputDirectory.createSync(recursive: true);
|
outputDirectory.createSync(recursive: true);
|
||||||
|
|
||||||
// The migrators to apply to a Web project.
|
// The migrators to apply to a Web project.
|
||||||
final List<ProjectMigrator> migrators = <ProjectMigrator>[
|
final List<ProjectMigrator> migrators = <ProjectMigrator>[
|
||||||
ScrubGeneratedPluginRegistrant(flutterProject.web, globals.logger),
|
ScrubGeneratedPluginRegistrant(flutterProject.web, _logger),
|
||||||
];
|
];
|
||||||
|
|
||||||
final ProjectMigration migration = ProjectMigration(migrators);
|
final ProjectMigration migration = ProjectMigration(migrators);
|
||||||
migration.run();
|
migration.run();
|
||||||
|
|
||||||
final Status status = globals.logger.startProgress('Compiling $target for the Web...');
|
final Status status = _logger.startProgress('Compiling $target for the Web...');
|
||||||
final Stopwatch sw = Stopwatch()..start();
|
final Stopwatch sw = Stopwatch()..start();
|
||||||
try {
|
try {
|
||||||
final BuildResult result = await globals.buildSystem.build(
|
final BuildResult result = await _buildSystem.build(
|
||||||
WebServiceWorker(globals.fs, buildInfo.webRenderer, isWasm: isWasm),
|
WebServiceWorker(_fileSystem, buildInfo.webRenderer, isWasm: isWasm),
|
||||||
Environment(
|
Environment(
|
||||||
projectDir: globals.fs.currentDirectory,
|
projectDir: _fileSystem.currentDirectory,
|
||||||
outputDir: outputDirectory,
|
outputDir: outputDirectory,
|
||||||
buildDir: flutterProject.directory
|
buildDir: flutterProject.directory.childDirectory('.dart_tool').childDirectory('flutter_build'),
|
||||||
.childDirectory('.dart_tool')
|
|
||||||
.childDirectory('flutter_build'),
|
|
||||||
defines: <String, String>{
|
defines: <String, String>{
|
||||||
kTargetFile: target,
|
kTargetFile: target,
|
||||||
kHasWebPlugins: hasWebPlugins.toString(),
|
kHasWebPlugins: hasWebPlugins.toString(),
|
||||||
kCspMode: csp.toString(),
|
kCspMode: csp.toString(),
|
||||||
if (baseHref != null)
|
if (baseHref != null) kBaseHref: baseHref,
|
||||||
kBaseHref : baseHref,
|
|
||||||
kSourceMapsEnabled: sourceMaps.toString(),
|
kSourceMapsEnabled: sourceMaps.toString(),
|
||||||
kNativeNullAssertions: nativeNullAssertions.toString(),
|
kNativeNullAssertions: nativeNullAssertions.toString(),
|
||||||
kServiceWorkerStrategy: serviceWorkerStrategy,
|
kServiceWorkerStrategy: serviceWorkerStrategy,
|
||||||
@ -76,26 +94,23 @@ Future<void> buildWeb(
|
|||||||
...buildInfo.toBuildSystemEnvironment(),
|
...buildInfo.toBuildSystemEnvironment(),
|
||||||
},
|
},
|
||||||
artifacts: globals.artifacts!,
|
artifacts: globals.artifacts!,
|
||||||
fileSystem: globals.fs,
|
fileSystem: _fileSystem,
|
||||||
logger: globals.logger,
|
logger: _logger,
|
||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
usage: globals.flutterUsage,
|
usage: _flutterUsage,
|
||||||
cacheDir: globals.cache.getRoot(),
|
cacheDir: globals.cache.getRoot(),
|
||||||
engineVersion: globals.artifacts!.isLocalEngine
|
engineVersion: globals.artifacts!.isLocalEngine ? null : _flutterVersion.engineRevision,
|
||||||
? null
|
flutterRootDir: _fileSystem.directory(Cache.flutterRoot),
|
||||||
: globals.flutterVersion.engineRevision,
|
|
||||||
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
|
|
||||||
// Web uses a different Dart plugin registry.
|
// Web uses a different Dart plugin registry.
|
||||||
// https://github.com/flutter/flutter/issues/80406
|
// https://github.com/flutter/flutter/issues/80406
|
||||||
generateDartPluginRegistry: false,
|
generateDartPluginRegistry: false,
|
||||||
));
|
));
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
||||||
globals.printError('Target ${measurement.target} failed: ${measurement.exception}',
|
_logger.printError(
|
||||||
stackTrace: measurement.fatal
|
'Target ${measurement.target} failed: ${measurement.exception}',
|
||||||
? measurement.stackTrace
|
stackTrace: measurement.fatal ? measurement.stackTrace : null,
|
||||||
: null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throwToolExit('Failed to compile application for the Web.');
|
throwToolExit('Failed to compile application for the Web.');
|
||||||
@ -105,7 +120,8 @@ Future<void> buildWeb(
|
|||||||
} finally {
|
} finally {
|
||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
|
_flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Web rendering backend mode.
|
/// Web rendering backend mode.
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:file/memory.dart';
|
||||||
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
|
import 'package:flutter_tools/src/build_info.dart';
|
||||||
|
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||||
|
import 'package:flutter_tools/src/build_system/targets/web.dart';
|
||||||
|
import 'package:flutter_tools/src/project.dart';
|
||||||
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
|
import 'package:flutter_tools/src/version.dart';
|
||||||
|
import 'package:flutter_tools/src/web/compile.dart';
|
||||||
|
|
||||||
|
import '../../src/common.dart';
|
||||||
|
import '../../src/context.dart';
|
||||||
|
import '../../src/fakes.dart';
|
||||||
|
import '../../src/test_build_system.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
late MemoryFileSystem fileSystem;
|
||||||
|
late TestUsage testUsage;
|
||||||
|
late BufferLogger logger;
|
||||||
|
late FlutterVersion flutterVersion;
|
||||||
|
late FlutterProject flutterProject;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
fileSystem = MemoryFileSystem.test();
|
||||||
|
testUsage = TestUsage();
|
||||||
|
logger = BufferLogger.test();
|
||||||
|
flutterVersion = FakeFlutterVersion(frameworkVersion: '1.0.0', engineRevision: '9.8.7');
|
||||||
|
|
||||||
|
flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
|
||||||
|
fileSystem.file('.packages').createSync();
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('WebBuilder sets environment on success', () async {
|
||||||
|
final TestBuildSystem buildSystem =
|
||||||
|
TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||||
|
final WebServiceWorker webServiceWorker = target as WebServiceWorker;
|
||||||
|
expect(webServiceWorker.isWasm, isTrue);
|
||||||
|
expect(webServiceWorker.webRenderer, WebRendererMode.autoDetect);
|
||||||
|
|
||||||
|
expect(environment.defines, <String, String>{
|
||||||
|
'TargetFile': 'target',
|
||||||
|
'HasWebPlugins': 'false',
|
||||||
|
'cspMode': 'true',
|
||||||
|
'SourceMaps': 'true',
|
||||||
|
'NativeNullAssertions': 'true',
|
||||||
|
'ServiceWorkerStrategy': 'serviceWorkerStrategy',
|
||||||
|
'Dart2jsOptimization': 'O4',
|
||||||
|
'Dart2jsDumpInfo': 'false',
|
||||||
|
'Dart2jsNoFrequencyBasedMinification': 'false',
|
||||||
|
'BuildMode': 'debug',
|
||||||
|
'DartObfuscation': 'false',
|
||||||
|
'TrackWidgetCreation': 'true',
|
||||||
|
'TreeShakeIcons': 'false',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(environment.engineVersion, '9.8.7');
|
||||||
|
expect(environment.generateDartPluginRegistry, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
final WebBuilder webBuilder = WebBuilder(
|
||||||
|
logger: logger,
|
||||||
|
buildSystem: buildSystem,
|
||||||
|
usage: testUsage,
|
||||||
|
flutterVersion: flutterVersion,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
);
|
||||||
|
await webBuilder.buildWeb(
|
||||||
|
flutterProject,
|
||||||
|
'target',
|
||||||
|
BuildInfo.debug,
|
||||||
|
true,
|
||||||
|
'serviceWorkerStrategy',
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(logger.statusText, contains('Compiling target for the Web...'));
|
||||||
|
expect(logger.errorText, isEmpty);
|
||||||
|
// Runs ScrubGeneratedPluginRegistrant migrator.
|
||||||
|
expect(logger.traceText, contains('generated_plugin_registrant.dart not found. Skipping.'));
|
||||||
|
|
||||||
|
// Sends timing event.
|
||||||
|
final TestTimingEvent timingEvent = testUsage.timings.single;
|
||||||
|
expect(timingEvent.category, 'build');
|
||||||
|
expect(timingEvent.variableName, 'dart2js');
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('WebBuilder throws tool exit on failure', () async {
|
||||||
|
final TestBuildSystem buildSystem = TestBuildSystem.all(BuildResult(
|
||||||
|
success: false,
|
||||||
|
exceptions: <String, ExceptionMeasurement>{
|
||||||
|
'hello': ExceptionMeasurement(
|
||||||
|
'hello',
|
||||||
|
const FormatException('illegal character in input string'),
|
||||||
|
StackTrace.current,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
final WebBuilder webBuilder = WebBuilder(
|
||||||
|
logger: logger,
|
||||||
|
buildSystem: buildSystem,
|
||||||
|
usage: testUsage,
|
||||||
|
flutterVersion: flutterVersion,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
);
|
||||||
|
await expectLater(
|
||||||
|
() async => webBuilder.buildWeb(
|
||||||
|
flutterProject,
|
||||||
|
'target',
|
||||||
|
BuildInfo.debug,
|
||||||
|
true,
|
||||||
|
'serviceWorkerStrategy',
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
throwsToolExit(message: 'Failed to compile application for the Web.'));
|
||||||
|
|
||||||
|
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
|
||||||
|
expect(testUsage.timings, isEmpty);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user