Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ environment:
dev_dependencies:
build_runner: '>=1.3.0 <2.0.0'
build_web_compilers: '>=1.0.0 <3.0.0'
build_daemon: ^0.5.0
4 changes: 4 additions & 0 deletions webdev/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.3

- Fix an issue with reusing an existing Chrome instance.

## 2.0.2

- Support `package:dwds` version `0.3.0`.
Expand Down
44 changes: 32 additions & 12 deletions webdev/lib/src/serve/chrome.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:async/async.dart';
import 'package:path/path.dart' as p;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

import 'utils.dart';

const _chromeEnvironment = 'CHROME_EXECUTABLE';
const _linuxExecutable = 'google-chrome';
const _macOSExecutable =
Expand Down Expand Up @@ -73,9 +72,18 @@ class Chrome {
/// Each url in [urls] will be loaded in a separate tab.
static Future<Chrome> start(List<String> urls, {int port}) async {
var dataDir = Directory(p.joinAll(
[Directory.current.path, '.dart_tool', 'webdev', 'chrome_profile']))
..createSync(recursive: true);
port = port == null || port == 0 ? await findUnusedPort() : port;
[Directory.current.path, '.dart_tool', 'webdev', 'chrome_profile']));
var activePortFile = File(p.join(dataDir.path, 'DevToolsActivePort'));
// If we are reusing the Chrome profile we'll need to be able to read the
// DevToolsActivePort to connect the debugger.
// When a non-zero debugging port is provided Chrome will not write the
// DevToolsActivePort file and therefore we can not reuse the profile.
if (dataDir.existsSync() && !activePortFile.existsSync()) {
dataDir.deleteSync(recursive: true);
}
if (activePortFile.existsSync()) activePortFile.deleteSync();
dataDir.createSync(recursive: true);
port = port == null ? 0 : port;
var args = [
// Using a tmp directory ensures that a new instance of chrome launches
// allowing for the remote debug port to be enabled.
Expand All @@ -95,15 +103,27 @@ class Chrome {
]..addAll(urls);

var process = await Process.start(_executable, args);
var output = StreamGroup.merge([
process.stderr.transform(utf8.decoder).transform(const LineSplitter()),
process.stdout.transform(utf8.decoder).transform(const LineSplitter())
]);

// Wait until the DevTools are listening before trying to connect.
await process.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
.firstWhere((line) => line.startsWith('DevTools listening'))
.timeout(Duration(seconds: 60),
onTimeout: () =>
throw Exception('Unable to connect to Chrome DevTools.'));
await output.firstWhere((line) {
print(line);
return line.startsWith('DevTools listening') ||
line.startsWith('Opening in existing');
}).timeout(Duration(seconds: 60),
onTimeout: () =>
throw Exception('Unable to connect to Chrome DevTools.'));

// The DevToolsActivePort file is only written if 0 is provided.
if (port == 0) {
if (!activePortFile.existsSync()) {
throw ChromeError("Can't read DevToolsActivePort file.");
}
port = int.parse(activePortFile.readAsLinesSync().first);
}

return _connect(Chrome._(
port,
Expand Down
Loading