Skip to content
Merged
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
2 changes: 1 addition & 1 deletion dwds_test_common/fixtures/_webdev_smoke/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A test fixture for webdev testing.
publish_to: none

environment:
sdk: ^3.10.0-0.0.dev
sdk: ^3.14.0-286.0.dev

dev_dependencies:
build_daemon: ^4.1.4
Expand Down
9 changes: 9 additions & 0 deletions webdev/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 4.1.0-wip

- Add a `--[no-]deprecated-js-interop` flag to `serve`, `build` and `daemon`.
When set, it allows or disallows the deprecated JS interop libraries, such
as `dart:html` and `package:js`, in dartdevc, dart2js and expression
evaluation. When not set, the Dart SDK default is used. Requires a Dart SDK
that supports the flag and `build_web_compilers` 4.9.0 or later.
- Require `package:dwds` `^27.2.0`.

## 4.0.3

- Fix failing debugger expression evaluation.
Expand Down
18 changes: 18 additions & 0 deletions webdev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ Common:
(defaults to on)
-v, --verbose Enables verbose logging.
--offline Disable fetching from pub.dev.
--[no-]deprecated-js-interop Whether to allow the deprecated JS
interop libraries, such as
"dart:html", "dart:js",
"dart:js_util" and "package:js", when
compiling with ddc and dart2js.
If not set, the Dart SDK default is
used. Requires a Dart SDK and
"build_web_compilers" version that
support this option.

Run "webdev help" to see global options.

Expand Down Expand Up @@ -149,6 +158,15 @@ Usage: webdev build [arguments]
(defaults to on)
-v, --verbose Enables verbose logging.
--offline Disable fetching from pub.dev.
--[no-]deprecated-js-interop Whether to allow the deprecated JS
interop libraries, such as
"dart:html", "dart:js",
"dart:js_util" and "package:js", when
compiling with ddc and dart2js.
If not set, the Dart SDK default is
used. Requires a Dart SDK and
"build_web_compilers" version that
support this option.

Run "webdev help" to see global options.

Expand Down
82 changes: 39 additions & 43 deletions webdev/lib/src/command/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const canaryFeaturesFlag = 'canary';
const moduleFormatFlag = 'module-format';
const offlineFlag = 'offline';
const webHotReloadFlag = 'web-hot-reload';
const deprecatedJsInteropFlag = 'deprecated-js-interop';

ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) {
var auto = argResults.options.contains(autoOption)
Expand Down Expand Up @@ -111,61 +112,42 @@ class Configuration {
final String? _moduleFormat;
final bool? _offline;
final bool? _webHotReload;
final bool? _deprecatedJsInterop;

Configuration({
bool? autoRun,
int? chromeDebugPort,
bool? debugExtension,
bool? debug,
bool? enableInjectedClient,
String? hostname,
String? tlsCertChain,
String? tlsCertKey,
List<String>? launchApps,
bool? launchInChrome,
String? userDataDir,
bool? logRequests,
String? output,
this._autoRun,
this._chromeDebugPort,
this._debugExtension,
this._debug,
this._enableInjectedClient,
this._hostname,
this._tlsCertChain,
this._tlsCertKey,
this._launchApps,
this._launchInChrome,
this._userDataDir,
this._logRequests,
this._output,
this.outputInput,
this.outputPath,
ReloadConfiguration? reload,
bool? release,
bool? requireBuildWebCompilers,
bool? enableExpressionEvaluation,
bool? verbose,
bool? disableDds,
List<String>? experiments,
this._reload,
this._release,
this._requireBuildWebCompilers,
this._enableExpressionEvaluation,
this._verbose,
this._disableDds,
this._experiments,
bool? canaryFeatures,
String? moduleFormat,
bool? offline,
this._offline,
bool? webHotReload,
}) : _autoRun = autoRun,
_chromeDebugPort = chromeDebugPort,
_debugExtension = debugExtension,
_debug = debug,
_enableInjectedClient = enableInjectedClient,
_hostname = hostname,
_tlsCertChain = tlsCertChain,
_tlsCertKey = tlsCertKey,
_launchApps = launchApps,
_launchInChrome = launchInChrome,
_userDataDir = userDataDir,
_logRequests = logRequests,
_output = output,
_release = release,
_reload = reload,
_requireBuildWebCompilers = requireBuildWebCompilers,
_disableDds = disableDds,
_enableExpressionEvaluation = enableExpressionEvaluation,
_verbose = verbose,
_experiments = experiments,
_canaryFeatures = (webHotReload == true && canaryFeatures == null)
this._deprecatedJsInterop,
}) : _canaryFeatures = (webHotReload == true && canaryFeatures == null)
? true
: canaryFeatures,
_moduleFormat = (webHotReload == true && moduleFormat == null)
? 'ddc'
: moduleFormat,
_offline = offline,
_webHotReload = webHotReload {
_validateConfiguration();
}
Expand Down Expand Up @@ -265,6 +247,7 @@ class Configuration {
moduleFormat: other._moduleFormat ?? _moduleFormat,
offline: other._offline ?? _offline,
webHotReload: other._webHotReload ?? _webHotReload,
deprecatedJsInterop: other._deprecatedJsInterop ?? _deprecatedJsInterop,
);

factory Configuration.noInjectedClientDefaults() =>
Expand Down Expand Up @@ -321,6 +304,12 @@ class Configuration {

bool get offline => _offline ?? false;

/// Whether the compilers allow the deprecated JS interop libraries, such as
/// `dart:html`.
///
/// If `null`, nothing is passed to the compilers and the SDK default is used.
bool? get deprecatedJsInterop => _deprecatedJsInterop;

/// Returns a new configuration with values updated from the parsed args.
static Configuration fromArgs(
ArgResults? argResults, {
Expand Down Expand Up @@ -520,6 +509,12 @@ class Configuration {
? argResults[offlineFlag] as bool?
: defaultConfiguration.offline;

final deprecatedJsInterop =
argResults.options.contains(deprecatedJsInteropFlag) &&
argResults.wasParsed(deprecatedJsInteropFlag)
? argResults[deprecatedJsInteropFlag] as bool?
: defaultConfiguration.deprecatedJsInterop;

return Configuration(
autoRun: defaultConfiguration.autoRun,
chromeDebugPort: chromeDebugPort,
Expand Down Expand Up @@ -547,6 +542,7 @@ class Configuration {
canaryFeatures: coercedCanaryFeatures ?? canaryFeatures,
moduleFormat: coercedModuleFormat ?? moduleFormat,
offline: offline,
deprecatedJsInterop: deprecatedJsInterop,
);
}
}
Expand Down
48 changes: 48 additions & 0 deletions webdev/lib/src/command/shared.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,43 @@ void addSharedArgs(
defaultsTo: false,
negatable: false,
help: 'Disable fetching from pub.dev.',
)
..addFlag(
deprecatedJsInteropFlag,
defaultsTo: null,
negatable: true,
help:
'Whether to allow the deprecated JS interop libraries, such as '
'"dart:html", "dart:js", "dart:js_util" and "package:js", when '
'compiling with ddc and dart2js.\n'
'If not set, the Dart SDK default is used. Requires a Dart SDK and '
'"build_web_compilers" version that support this option.',
);
}

/// The `build_web_compilers` builders that must be configured with the same
/// `deprecated-js-interop` option.
const _deprecatedJsInteropBuilders = [
'ddc',
'ddc_modules',
'dart2js_modules',
'entrypoint',
];

/// Returns the `build_runner` arguments that configure
/// `deprecated-js-interop` for every builder that compiles user code to JS.
///
/// Returns an empty list when [deprecatedJsInterop] is `null` so that the
/// SDK default is used.
List<String> _deprecatedJsInteropArgs(bool? deprecatedJsInterop) => [
if (deprecatedJsInterop != null)
for (final builder in _deprecatedJsInteropBuilders) ...[
'--define',
'build_web_compilers|$builder='
'$deprecatedJsInteropFlag=$deprecatedJsInterop',
],
];

/// Parses the provided [Configuration] to return a list of
/// `package:build_runner` appropriate arguments.
List<String> buildRunnerArgs(Configuration configuration) {
Expand Down Expand Up @@ -158,6 +192,8 @@ List<String> buildRunnerArgs(Configuration configuration) {
..add('build_web_compilers|entrypoint_marker=ddc-library-bundle=true');
}

arguments.addAll(_deprecatedJsInteropArgs(configuration.deprecatedJsInterop));

return arguments;
}

Expand All @@ -166,9 +202,21 @@ Future<void> validatePubspecLock(Configuration configuration) async {
await checkPubspecLock(
pubspecLock,
requireBuildWebCompilers: configuration.requireBuildWebCompilers,
deprecatedJsInteropArgument: _deprecatedJsInteropFlagName(
configuration.deprecatedJsInterop,
),
);
}

/// The `--[no-]deprecated-js-interop` flag name (without `--`) the user
/// passed, or `null` if they did not pass it.
String? _deprecatedJsInteropFlagName(bool? deprecatedJsInterop) =>
switch (deprecatedJsInterop) {
null => null,
true => deprecatedJsInteropFlag,
false => 'no-$deprecatedJsInteropFlag',
};

/// Checks that the normalized form of [path] is a top level directory under
/// such as `web` or `test`.
///
Expand Down
15 changes: 7 additions & 8 deletions webdev/lib/src/logging.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import 'dart:io';
import 'package:io/ansi.dart';
import 'package:logging/logging.dart';

typedef LogWriter =
void Function(
Level level,
String message, {
String? error,
String? loggerName,
String? stackTrace,
});
typedef LogWriter = void Function(
Level level,
String message, {
String? error,
String? loggerName,
String? stackTrace,
});

var _verbose = false;
StreamSubscription<LogRecord>? _subscription;
Expand Down
44 changes: 35 additions & 9 deletions webdev/lib/src/pubspec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class PackageExceptionDetails {
const PackageExceptionDetails._(
this.error, {
this.description,
bool missingDependency = false,
}) : _missingDependency = missingDependency;
this._missingDependency = false,
});

static PackageExceptionDetails missingDep(
String pkgName,
Expand Down Expand Up @@ -91,13 +91,9 @@ class PubspecLock {
dir = next;
}

final pubspecLock =
loadYaml(
await File(
p.relative(p.join(dir, 'pubspec.lock')),
).readAsString(),
)
as YamlMap;
final pubspecLock = loadYaml(
await File(p.relative(p.join(dir, 'pubspec.lock'))).readAsString(),
) as YamlMap;

final packages = pubspecLock['packages'] as YamlMap?;
return PubspecLock(packages);
Expand Down Expand Up @@ -190,11 +186,22 @@ Future<List<PackageExceptionDetails>> _validateBuildDaemonVersion(
final buildRunnerConstraint = VersionConstraint.parse('^2.4.0');
final buildWebCompilersConstraint = VersionConstraint.parse('^4.4.12');

/// The `build_web_compilers` versions that support the `deprecated-js-interop`
/// option.
final buildWebCompilersDeprecatedJsInteropConstraint = VersionConstraint.parse(
'^4.9.0',
);

// Note the minimum versions should never be dev versions as users will not
// get them by default.
//
// If [deprecatedJsInteropArgument] is set, it is the `--[no-]` form of the
// `deprecated-js-interop` flag passed by the user, which requires a newer
// `build_web_compilers`.
Future<void> checkPubspecLock(
PubspecLock pubspecLock, {
required bool requireBuildWebCompilers,
String? deprecatedJsInteropArgument,
Comment thread
Markzipan marked this conversation as resolved.
}) async {
final issues = <PackageExceptionDetails>[];
final buildRunnerIssues = pubspecLock.checkPackage(
Expand All @@ -220,6 +227,25 @@ Future<void> checkPubspecLock(
if (issues.isNotEmpty) {
throw PackageException(issues);
}

if (requireBuildWebCompilers && deprecatedJsInteropArgument != null) {
_checkDeprecatedJsInteropSupport(pubspecLock, deprecatedJsInteropArgument);
}
}

/// Throws a [PackageException] if `build_web_compilers` does not support the
/// `deprecated-js-interop` option used by [argument].
void _checkDeprecatedJsInteropSupport(
PubspecLock pubspecLock,
String argument,
) {
final issues = pubspecLock.checkPackage(
'build_web_compilers',
buildWebCompilersDeprecatedJsInteropConstraint,
);
if (issues.isNotEmpty) {
throw PackageException(issues, unsupportedArgument: argument);
}
}

class _PackageInfo {
Expand Down
1 change: 1 addition & 0 deletions webdev/lib/src/serve/webdev_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class WebDevServer {
canaryFeatures: options.configuration.canaryFeatures,
isFlutterApp: false,
experiments: options.configuration.experiments,
deprecatedJsInterop: options.configuration.deprecatedJsInterop,
);

final LoadStrategy loadStrategy;
Expand Down
2 changes: 1 addition & 1 deletion webdev/lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading