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_system/targets/web.dart';
|
||||
import '../features.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../html_utils.dart';
|
||||
import '../project.dart';
|
||||
import '../runner/flutter_command.dart'
|
||||
@ -168,7 +169,14 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
final String? outputDirectoryPath = stringArg('output');
|
||||
|
||||
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,
|
||||
target,
|
||||
buildInfo,
|
||||
|
@ -314,7 +314,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
||||
device!.generator!.accept();
|
||||
cacheInitialDillCompilation();
|
||||
} else {
|
||||
await buildWeb(
|
||||
final WebBuilder webBuilder = WebBuilder(
|
||||
logger: _logger,
|
||||
buildSystem: globals.buildSystem,
|
||||
fileSystem: _fileSystem,
|
||||
flutterVersion: globals.flutterVersion,
|
||||
usage: globals.flutterUsage,
|
||||
);
|
||||
await webBuilder.buildWeb(
|
||||
flutterProject,
|
||||
target,
|
||||
debuggingOptions.buildInfo,
|
||||
@ -387,7 +394,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await buildWeb(
|
||||
final WebBuilder webBuilder = WebBuilder(
|
||||
logger: _logger,
|
||||
buildSystem: globals.buildSystem,
|
||||
fileSystem: _fileSystem,
|
||||
flutterVersion: globals.flutterVersion,
|
||||
usage: globals.flutterUsage,
|
||||
);
|
||||
await webBuilder.buildWeb(
|
||||
flutterProject,
|
||||
target,
|
||||
debuggingOptions.buildInfo,
|
||||
|
@ -16,96 +16,112 @@ import '../globals.dart' as globals;
|
||||
import '../platform_plugins.dart';
|
||||
import '../plugins.dart';
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
import '../version.dart';
|
||||
import 'migrations/scrub_generated_plugin_registrant.dart';
|
||||
|
||||
export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel;
|
||||
|
||||
Future<void> buildWeb(
|
||||
FlutterProject flutterProject,
|
||||
String target,
|
||||
BuildInfo buildInfo,
|
||||
bool csp,
|
||||
String serviceWorkerStrategy,
|
||||
bool sourceMaps,
|
||||
bool nativeNullAssertions,
|
||||
bool isWasm, {
|
||||
String dart2jsOptimization = kDart2jsDefaultOptimizationLevel,
|
||||
String? baseHref,
|
||||
bool dumpInfo = false,
|
||||
bool noFrequencyBasedMinification = false,
|
||||
String? outputDirectoryPath,
|
||||
}) async {
|
||||
final bool hasWebPlugins = (await findPlugins(flutterProject))
|
||||
.any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
|
||||
final Directory outputDirectory = outputDirectoryPath == null
|
||||
? globals.fs.directory(getWebBuildDirectory(isWasm))
|
||||
: globals.fs.directory(outputDirectoryPath);
|
||||
outputDirectory.createSync(recursive: true);
|
||||
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;
|
||||
|
||||
// The migrators to apply to a Web project.
|
||||
final List<ProjectMigrator> migrators = <ProjectMigrator>[
|
||||
ScrubGeneratedPluginRegistrant(flutterProject.web, globals.logger),
|
||||
];
|
||||
final Logger _logger;
|
||||
final BuildSystem _buildSystem;
|
||||
final Usage _flutterUsage;
|
||||
final FlutterVersion _flutterVersion;
|
||||
final FileSystem _fileSystem;
|
||||
|
||||
final ProjectMigration migration = ProjectMigration(migrators);
|
||||
migration.run();
|
||||
Future<void> buildWeb(
|
||||
FlutterProject flutterProject,
|
||||
String target,
|
||||
BuildInfo buildInfo,
|
||||
bool csp,
|
||||
String serviceWorkerStrategy,
|
||||
bool sourceMaps,
|
||||
bool nativeNullAssertions,
|
||||
bool isWasm, {
|
||||
String dart2jsOptimization = kDart2jsDefaultOptimizationLevel,
|
||||
String? baseHref,
|
||||
bool dumpInfo = false,
|
||||
bool noFrequencyBasedMinification = false,
|
||||
String? outputDirectoryPath,
|
||||
}) async {
|
||||
final bool hasWebPlugins =
|
||||
(await findPlugins(flutterProject)).any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
|
||||
final Directory outputDirectory = outputDirectoryPath == null
|
||||
? _fileSystem.directory(getWebBuildDirectory(isWasm))
|
||||
: _fileSystem.directory(outputDirectoryPath);
|
||||
outputDirectory.createSync(recursive: true);
|
||||
|
||||
final Status status = globals.logger.startProgress('Compiling $target for the Web...');
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
try {
|
||||
final BuildResult result = await globals.buildSystem.build(
|
||||
WebServiceWorker(globals.fs, buildInfo.webRenderer, isWasm: isWasm),
|
||||
Environment(
|
||||
projectDir: globals.fs.currentDirectory,
|
||||
outputDir: outputDirectory,
|
||||
buildDir: flutterProject.directory
|
||||
.childDirectory('.dart_tool')
|
||||
.childDirectory('flutter_build'),
|
||||
defines: <String, String>{
|
||||
kTargetFile: target,
|
||||
kHasWebPlugins: hasWebPlugins.toString(),
|
||||
kCspMode: csp.toString(),
|
||||
if (baseHref != null)
|
||||
kBaseHref : baseHref,
|
||||
kSourceMapsEnabled: sourceMaps.toString(),
|
||||
kNativeNullAssertions: nativeNullAssertions.toString(),
|
||||
kServiceWorkerStrategy: serviceWorkerStrategy,
|
||||
kDart2jsOptimization: dart2jsOptimization,
|
||||
kDart2jsDumpInfo: dumpInfo.toString(),
|
||||
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
|
||||
...buildInfo.toBuildSystemEnvironment(),
|
||||
},
|
||||
artifacts: globals.artifacts!,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
platform: globals.platform,
|
||||
usage: globals.flutterUsage,
|
||||
cacheDir: globals.cache.getRoot(),
|
||||
engineVersion: globals.artifacts!.isLocalEngine
|
||||
? null
|
||||
: globals.flutterVersion.engineRevision,
|
||||
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
|
||||
// Web uses a different Dart plugin registry.
|
||||
// https://github.com/flutter/flutter/issues/80406
|
||||
generateDartPluginRegistry: false,
|
||||
));
|
||||
if (!result.success) {
|
||||
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
||||
globals.printError('Target ${measurement.target} failed: ${measurement.exception}',
|
||||
stackTrace: measurement.fatal
|
||||
? measurement.stackTrace
|
||||
: null,
|
||||
);
|
||||
// The migrators to apply to a Web project.
|
||||
final List<ProjectMigrator> migrators = <ProjectMigrator>[
|
||||
ScrubGeneratedPluginRegistrant(flutterProject.web, _logger),
|
||||
];
|
||||
|
||||
final ProjectMigration migration = ProjectMigration(migrators);
|
||||
migration.run();
|
||||
|
||||
final Status status = _logger.startProgress('Compiling $target for the Web...');
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
try {
|
||||
final BuildResult result = await _buildSystem.build(
|
||||
WebServiceWorker(_fileSystem, buildInfo.webRenderer, isWasm: isWasm),
|
||||
Environment(
|
||||
projectDir: _fileSystem.currentDirectory,
|
||||
outputDir: outputDirectory,
|
||||
buildDir: flutterProject.directory.childDirectory('.dart_tool').childDirectory('flutter_build'),
|
||||
defines: <String, String>{
|
||||
kTargetFile: target,
|
||||
kHasWebPlugins: hasWebPlugins.toString(),
|
||||
kCspMode: csp.toString(),
|
||||
if (baseHref != null) kBaseHref: baseHref,
|
||||
kSourceMapsEnabled: sourceMaps.toString(),
|
||||
kNativeNullAssertions: nativeNullAssertions.toString(),
|
||||
kServiceWorkerStrategy: serviceWorkerStrategy,
|
||||
kDart2jsOptimization: dart2jsOptimization,
|
||||
kDart2jsDumpInfo: dumpInfo.toString(),
|
||||
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
|
||||
...buildInfo.toBuildSystemEnvironment(),
|
||||
},
|
||||
artifacts: globals.artifacts!,
|
||||
fileSystem: _fileSystem,
|
||||
logger: _logger,
|
||||
processManager: globals.processManager,
|
||||
platform: globals.platform,
|
||||
usage: _flutterUsage,
|
||||
cacheDir: globals.cache.getRoot(),
|
||||
engineVersion: globals.artifacts!.isLocalEngine ? null : _flutterVersion.engineRevision,
|
||||
flutterRootDir: _fileSystem.directory(Cache.flutterRoot),
|
||||
// Web uses a different Dart plugin registry.
|
||||
// https://github.com/flutter/flutter/issues/80406
|
||||
generateDartPluginRegistry: false,
|
||||
));
|
||||
if (!result.success) {
|
||||
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
||||
_logger.printError(
|
||||
'Target ${measurement.target} failed: ${measurement.exception}',
|
||||
stackTrace: measurement.fatal ? measurement.stackTrace : null,
|
||||
);
|
||||
}
|
||||
throwToolExit('Failed to compile application for the Web.');
|
||||
}
|
||||
throwToolExit('Failed to compile application for the Web.');
|
||||
} on Exception catch (err) {
|
||||
throwToolExit(err.toString());
|
||||
} finally {
|
||||
status.stop();
|
||||
}
|
||||
} on Exception catch (err) {
|
||||
throwToolExit(err.toString());
|
||||
} finally {
|
||||
status.stop();
|
||||
_flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
|
||||
}
|
||||
globals.flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
|
||||
}
|
||||
|
||||
/// 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