1// Copyright 2019 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'package:meta/meta.dart'; 6 7import '../asset.dart'; 8import '../base/common.dart'; 9import '../base/context.dart'; 10import '../base/file_system.dart'; 11import '../base/logger.dart'; 12import '../build_info.dart'; 13import '../bundle.dart'; 14import '../globals.dart'; 15import '../project.dart'; 16import '../reporting/reporting.dart'; 17 18/// The [WebCompilationProxy] instance. 19WebCompilationProxy get webCompilationProxy => context.get<WebCompilationProxy>(); 20 21Future<void> buildWeb(FlutterProject flutterProject, String target, BuildInfo buildInfo) async { 22 if (!flutterProject.web.existsSync()) { 23 throwToolExit('Missing index.html.'); 24 } 25 final Status status = logger.startProgress('Compiling $target for the Web...', timeout: null); 26 final Stopwatch sw = Stopwatch()..start(); 27 final Directory outputDir = fs.directory(getWebBuildDirectory()) 28 ..createSync(recursive: true); 29 bool result; 30 try { 31 result = await webCompilationProxy.initialize( 32 projectDirectory: FlutterProject.current().directory, 33 release: buildInfo.isRelease, 34 ); 35 if (result) { 36 // Places assets adjacent to the web stuff. 37 final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); 38 await assetBundle.build(); 39 await writeBundle(fs.directory(fs.path.join(outputDir.path, 'assets')), assetBundle.entries); 40 41 // Copy results to output directory. 42 final String outputPath = fs.path.join( 43 flutterProject.dartTool.path, 44 'build', 45 'flutter_web', 46 flutterProject.manifest.appName, 47 '${fs.path.withoutExtension(target)}_web_entrypoint.dart.js' 48 ); 49 fs.file(outputPath).copySync(fs.path.join(outputDir.path, 'main.dart.js')); 50 fs.file('$outputPath.map').copySync(fs.path.join(outputDir.path, 'main.dart.js.map')); 51 flutterProject.web.indexFile.copySync(fs.path.join(outputDir.path, 'index.html')); 52 } 53 } catch (err) { 54 printError(err.toString()); 55 result = false; 56 } finally { 57 status.stop(); 58 } 59 if (result == false) { 60 throwToolExit('Failed to compile $target for the Web.'); 61 } 62 String buildName = 'ddc'; 63 if (buildInfo.isRelease) { 64 buildName = 'dart2js'; 65 } 66 flutterUsage.sendTiming('build', buildName, Duration(milliseconds: sw.elapsedMilliseconds)); 67} 68 69/// An indirection on web compilation. 70/// 71/// Avoids issues with syncing build_runner_core to other repos. 72class WebCompilationProxy { 73 const WebCompilationProxy(); 74 75 /// Initialize the web compiler from the `projectDirectory`. 76 /// 77 /// Returns whether or not the build was successful. 78 /// 79 /// `release` controls whether we build the bundle for dartdevc or only 80 /// the entrypoints for dart2js to later take over. 81 Future<bool> initialize({ 82 @required Directory projectDirectory, 83 String testOutputDir, 84 bool release, 85 }) async { 86 throw UnimplementedError(); 87 } 88 89 /// Invalidate the source files in `inputs` and recompile them to JavaScript. 90 Future<void> invalidate({@required List<Uri> inputs}) async { 91 throw UnimplementedError(); 92 } 93} 94