Skip to content

Commit 2781837

Browse files
authored
Adding support for DDC's Library Bundle module system. (#4303)
This module system - in conjunction with the Frontend Server - supports web hot reload. This is part of an effort to deprecate DDC's older module systems.
1 parent 00ceed3 commit 2781837

12 files changed

+807
-59
lines changed

build_modules/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 5.1.5
2+
3+
- Add support for DDC's Library Bundle module system, which is compatible with web hot reload. This is not yet enabled by default.
4+
15
## 5.1.4
26

37
- Fix module_builder reading DDC modules for non-primary dart libraries.

build_modules/lib/src/module_builder.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ String moduleExtension(DartPlatform platform) => '.${platform.name}.module';
2424
class ModuleBuilder implements Builder {
2525
final DartPlatform _platform;
2626

27-
/// Emits DDC code with the Library Bundle module system, which supports hot
28-
/// reload.
29-
///
3027
/// If set, this builder will consume raw meta modules (instead of clean).
31-
/// Clean meta modules are only used for DDC's AMD module system due its
32-
/// requirement that self-referential libraries be bundled.
28+
///
29+
/// Clean meta modules cannot be used when compiling with the Frontend Server
30+
/// due to potentially divergent bundling strategies between it and
31+
/// build_runner. Additionally, bundling isn't required in DDC's Library
32+
/// Bundle module system.
3333
final bool usesWebHotReload;
3434

3535
ModuleBuilder(this._platform, {this.usesWebHotReload = false})

build_modules/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: build_modules
2-
version: 5.1.4
2+
version: 5.1.5
33
description: >-
44
Builders to analyze and split Dart code into individually compilable modules
55
based on imports.

build_web_compilers/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## 4.4.6
1+
## 4.4.7
2+
- Add support for DDC's Library Bundle module system, which is compatible with web hot reload. This is not yet enabled by default.
23

4+
## 4.4.6
35
- Add build options to customize the SDK used for compiling to js and wasm.
46

57
## 4.4.5

build_web_compilers/lib/builders.dart

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ Builder ddcBuilder(BuilderOptions options) {
6464
useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
6565
generateFullDill: _readGenerateFullDillOption(options),
6666
emitDebugSymbols: _readEmitDebugSymbolsOption(options),
67-
canaryFeatures: _readCanaryOption(options),
68-
ddcModules: _readWebHotReloadOption(options),
67+
canaryFeatures:
68+
_readCanaryOption(options) || _readWebHotReloadOption(options),
69+
ddcLibraryBundle:
70+
_readDdcLibraryBundleOption(options) ||
71+
_readWebHotReloadOption(options),
6972
trackUnusedInputs: _readTrackInputsCompilerOption(options),
7073
platform: ddcPlatform,
7174
sdkKernelPath: _readDdcKernelPathOption(options),
@@ -102,8 +105,10 @@ Builder sdkJsCompile(BuilderOptions options) {
102105
sdkKernelPath: 'lib/_internal/ddc_platform.dill',
103106
outputPath: 'lib/src/dev_compiler/dart_sdk.js',
104107
canaryFeatures:
105-
_readWebHotReloadOption(options) || _readCanaryOption(options),
106-
usesWebHotReload: _readWebHotReloadOption(options),
108+
_readCanaryOption(options) || _readWebHotReloadOption(options),
109+
ddcLibraryBundle:
110+
_readDdcLibraryBundleOption(options) ||
111+
_readWebHotReloadOption(options),
107112
usePrebuiltSdkFromPath: _readUsePrebuiltSdkFromPathOption(options),
108113
);
109114
}
@@ -244,6 +249,10 @@ bool _readWebHotReloadOption(BuilderOptions options) {
244249
return options.config[_webHotReloadOption] as bool? ?? false;
245250
}
246251

252+
bool _readDdcLibraryBundleOption(BuilderOptions options) {
253+
return options.config[_ddcLibraryBundleOption] as bool? ?? false;
254+
}
255+
247256
bool _readUseUiLibrariesOption(BuilderOptions options) {
248257
return options.config[_useUiLibrariesOption] as bool? ?? false;
249258
}
@@ -279,6 +288,7 @@ const _canaryOption = 'canary';
279288
const _trackUnusedInputsCompilerOption = 'track-unused-inputs';
280289
const _environmentOption = 'environment';
281290
const _webHotReloadOption = 'web-hot-reload';
291+
const _ddcLibraryBundleOption = 'ddc-library-bundle';
282292
const _useUiLibrariesOption = 'use-ui-libraries';
283293
const _ddcKernelPathOption = 'ddc-kernel-path';
284294
const _librariesPathOption = 'libraries-path';
@@ -293,8 +303,10 @@ const _supportedOptions = [
293303
_canaryOption,
294304
_trackUnusedInputsCompilerOption,
295305
_webHotReloadOption,
306+
_ddcLibraryBundleOption,
296307
_useUiLibrariesOption,
297308
_ddcKernelPathOption,
298309
_librariesPathOption,
299310
_platformSdkOption,
311+
_usePrebuiltSdkFromPathOption,
300312
];

build_web_compilers/lib/src/dev_compiler_bootstrap.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Future<void> bootstrapDdc(
3737
String entrypointExtension = jsEntrypointExtension,
3838
required bool? nativeNullAssertions,
3939
bool usesWebHotReload = false,
40+
bool ddcLibraryBundle = false,
4041
bool unsafeAllowUnsupportedModules = false,
4142
}) async {
4243
// Ensures that the sdk resources are built and available.
@@ -112,7 +113,7 @@ $librariesString
112113
final dartEntrypointParts = _context.split(dartEntrypointId.path);
113114
final packageName = module.primarySource.package;
114115
final entrypointLibraryName =
115-
usesWebHotReload
116+
ddcLibraryBundle
116117
? _context.joinAll([
117118
// Convert to a package: uri for files under lib.
118119
if (dartEntrypointParts.first == 'lib') 'package:$packageName',
@@ -132,7 +133,7 @@ $librariesString
132133
String entrypointJsContent;
133134
String bootstrapContent;
134135
String bootstrapEndContent;
135-
if (usesWebHotReload) {
136+
if (ddcLibraryBundle) {
136137
final ddcSdkUrl =
137138
r'packages/build_web_compilers/src/dev_compiler/dart_sdk.js';
138139
modulePaths['dart_sdk'] = ddcSdkUrl;
@@ -148,8 +149,8 @@ $librariesString
148149
: _context.joinAll(_context.split(jsId.path).skip(1));
149150
}
150151
final bootstrapEndModuleName = _context.relative(
151-
bootstrapId.path,
152-
from: _context.dirname(bootstrapEndId.path),
152+
bootstrapEndId.path,
153+
from: _context.dirname(bootstrapId.path),
153154
);
154155
bootstrapContent = generateDDCLibraryBundleMainModule(
155156
entrypoint: entrypointLibraryName,

build_web_compilers/lib/src/dev_compiler_builder.dart

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class DevCompilerBuilder implements Builder {
4242
/// Enables canary features in DDC.
4343
final bool canaryFeatures;
4444

45-
/// Emits code with the DDC module system.
46-
final bool ddcModules;
45+
/// Emits code with the DDC Library Bundle module system.
46+
final bool ddcLibraryBundle;
4747

4848
final bool trackUnusedInputs;
4949

@@ -74,7 +74,7 @@ class DevCompilerBuilder implements Builder {
7474
this.generateFullDill = false,
7575
this.emitDebugSymbols = false,
7676
this.canaryFeatures = false,
77-
this.ddcModules = false,
77+
this.ddcLibraryBundle = false,
7878
this.trackUnusedInputs = false,
7979
required this.platform,
8080
String? sdkKernelPath,
@@ -125,16 +125,16 @@ class DevCompilerBuilder implements Builder {
125125
await _createDevCompilerModule(
126126
module,
127127
buildStep,
128-
useIncrementalCompiler,
129-
generateFullDill,
130-
emitDebugSymbols,
131-
canaryFeatures,
132-
ddcModules,
133-
trackUnusedInputs,
134-
platformSdk,
135-
sdkKernelPath,
136-
librariesPath,
137128
environment,
129+
useIncrementalCompiler: useIncrementalCompiler,
130+
generateFullDill: generateFullDill,
131+
emitDebugSymbols: emitDebugSymbols,
132+
canaryFeatures: canaryFeatures,
133+
ddcLibraryBundle: ddcLibraryBundle,
134+
trackUnusedInputs: trackUnusedInputs,
135+
dartSdk: platformSdk,
136+
sdkKernelPath: sdkKernelPath,
137+
librariesPath: librariesPath,
138138
);
139139
} on DartDevcCompilationException catch (e) {
140140
await handleError(e);
@@ -148,16 +148,16 @@ class DevCompilerBuilder implements Builder {
148148
Future<void> _createDevCompilerModule(
149149
Module module,
150150
BuildStep buildStep,
151-
bool useIncrementalCompiler,
152-
bool generateFullDill,
153-
bool emitDebugSymbols,
154-
bool canaryFeatures,
155-
bool ddcModules,
156-
bool trackUnusedInputs,
157-
String dartSdk,
158-
String sdkKernelPath,
159-
String librariesPath,
160151
Map<String, String> environment, {
152+
required bool useIncrementalCompiler,
153+
required bool generateFullDill,
154+
required bool emitDebugSymbols,
155+
required bool canaryFeatures,
156+
required bool ddcLibraryBundle,
157+
required bool trackUnusedInputs,
158+
required String dartSdk,
159+
required String sdkKernelPath,
160+
required String librariesPath,
161161
bool debugMode = true,
162162
}) async {
163163
final transitiveDeps = await buildStep.trackStage(
@@ -202,11 +202,11 @@ Future<void> _createDevCompilerModule(
202202
WorkRequest()
203203
..arguments.addAll([
204204
'--dart-sdk-summary=$sdkSummary',
205-
'--modules=${ddcModules ? 'ddc' : 'amd'}',
205+
'--modules=${ddcLibraryBundle ? 'ddc' : 'amd'}',
206206
'--no-summarize',
207207
if (generateFullDill) '--experimental-output-compiled-kernel',
208208
if (emitDebugSymbols) '--emit-debug-symbols',
209-
if (canaryFeatures) '--canary',
209+
if (canaryFeatures || ddcLibraryBundle) '--canary',
210210
'-o',
211211
jsOutputFile.path,
212212
debugMode ? '--source-map' : '--no-source-map',

build_web_compilers/lib/src/sdk_js_compile_builder.dart

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ class SdkJsCompileBuilder implements Builder {
4242
/// Enables canary features in DDC.
4343
final bool canaryFeatures;
4444

45-
/// Emits DDC code with the Library Bundle module system, which supports hot
46-
/// reload.
47-
final bool usesWebHotReload;
45+
/// Emits DDC code using its Library Bundle module system.
46+
final bool ddcLibraryBundle;
4847

4948
/// An optional directory path that contains prebuilt sdk files.
5049
///
@@ -58,7 +57,7 @@ class SdkJsCompileBuilder implements Builder {
5857
String? librariesPath,
5958
String? platformSdk,
6059
required this.canaryFeatures,
61-
required this.usesWebHotReload,
60+
required this.ddcLibraryBundle,
6261
this.usePrebuiltSdkFromPath,
6362
}) : platformSdk = platformSdk ?? sdkDir,
6463
librariesPath =
@@ -82,12 +81,12 @@ class SdkJsCompileBuilder implements Builder {
8281
} else {
8382
await _createDevCompilerModule(
8483
buildStep,
85-
platformSdk,
86-
sdkKernelPath,
87-
librariesPath,
8884
jsOutputId,
89-
canaryFeatures,
90-
usesWebHotReload,
85+
dartSdk: platformSdk,
86+
sdkKernelPath: sdkKernelPath,
87+
librariesPath: librariesPath,
88+
canaryFeatures: canaryFeatures,
89+
ddcLibraryBundle: ddcLibraryBundle,
9190
);
9291
}
9392
}
@@ -96,13 +95,13 @@ class SdkJsCompileBuilder implements Builder {
9695
/// Compile the sdk module with the dev compiler.
9796
Future<void> _createDevCompilerModule(
9897
BuildStep buildStep,
99-
String dartSdk,
100-
String sdkKernelPath,
101-
String librariesPath,
102-
AssetId jsOutputId,
103-
bool canaryFeatures,
104-
bool usesWebHotReload,
105-
) async {
98+
AssetId jsOutputId, {
99+
required String dartSdk,
100+
required String sdkKernelPath,
101+
required String librariesPath,
102+
required bool canaryFeatures,
103+
required bool ddcLibraryBundle,
104+
}) async {
106105
final scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
107106
final jsOutputFile = scratchSpace.fileFor(jsOutputId);
108107

@@ -130,8 +129,8 @@ Future<void> _createDevCompilerModule(
130129
result = await Process.run(dartPath, [
131130
snapshotPath,
132131
'--multi-root-scheme=org-dartlang-sdk',
133-
'--modules=${usesWebHotReload ? 'ddc' : 'amd'}',
134-
if (canaryFeatures || usesWebHotReload) '--canary',
132+
'--modules=${ddcLibraryBundle ? 'ddc' : 'amd'}',
133+
if (canaryFeatures || ddcLibraryBundle) '--canary',
135134
'--module-name=dart_sdk',
136135
'-o',
137136
jsOutputFile.path,

build_web_compilers/lib/src/web_entrypoint_builder.dart

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,13 @@ final class EntrypointBuilderOptions {
126126

127127
/// Whether or not to emit DDC entrypoints that support web hot reload.
128128
///
129-
/// Web hot reload is only supported for DDC's Library Bundle module system.
129+
/// Only supported for DDC's Library Bundle module system.
130130
final bool usesWebHotReload;
131131

132+
/// Whether or not to emit DDC entrypoints that target the DDC Library Bundle
133+
/// module system.
134+
final bool ddcLibraryBundle;
135+
132136
/// The absolute path to the libraries file for the current platform.
133137
///
134138
/// If not provided, defaults to "lib/libraries.json" in the sdk directory.
@@ -145,6 +149,7 @@ final class EntrypointBuilderOptions {
145149
this.nativeNullAssertions,
146150
this.loaderExtension,
147151
this.usesWebHotReload = false,
152+
this.ddcLibraryBundle = false,
148153
this.librariesPath,
149154
this.unsafeAllowUnsupportedModules = false,
150155
});
@@ -159,9 +164,11 @@ final class EntrypointBuilderOptions {
159164
const nativeNullAssertionsOption = 'native_null_assertions';
160165
const loaderOption = 'loader';
161166
const webHotReloadOption = 'web-hot-reload';
167+
const ddcLibraryBundleOption = 'ddc-library-bundle';
162168
const librariesPathOption = 'libraries-path';
163169
const unsafeAllowUnsupportedModulesOption =
164170
'unsafe-allow-unsupported-modules';
171+
165172
String? defaultLoaderOption;
166173

167174
const supportedOptions = [
@@ -172,6 +179,7 @@ final class EntrypointBuilderOptions {
172179
dart2wasmArgsOption,
173180
loaderOption,
174181
webHotReloadOption,
182+
ddcLibraryBundleOption,
175183
librariesPathOption,
176184
unsafeAllowUnsupportedModulesOption,
177185
'use-ui-libraries',
@@ -181,9 +189,12 @@ final class EntrypointBuilderOptions {
181189
final nativeNullAssertions =
182190
options.config[nativeNullAssertionsOption] as bool?;
183191
final usesWebHotReload = options.config[webHotReloadOption] as bool?;
192+
final usesDdcLibraryBundle =
193+
usesWebHotReload ?? options.config[ddcLibraryBundleOption] as bool?;
184194
final librariesPath = options.config[librariesPathOption] as String?;
185195
final unsafeAllowUnsupportedModules =
186196
options.config[unsafeAllowUnsupportedModulesOption] as bool?;
197+
187198
final compilers = <EnabledEntrypointCompiler>[];
188199

189200
validateOptions(
@@ -271,6 +282,7 @@ final class EntrypointBuilderOptions {
271282
? config[loaderOption] as String?
272283
: defaultLoaderOption,
273284
usesWebHotReload: usesWebHotReload ?? false,
285+
ddcLibraryBundle: usesDdcLibraryBundle ?? false,
274286
librariesPath: librariesPath,
275287
unsafeAllowUnsupportedModules: unsafeAllowUnsupportedModules ?? false,
276288
);
@@ -354,14 +366,17 @@ class WebEntrypointBuilder implements Builder {
354366
Future(() async {
355367
try {
356368
final usesWebHotReload = options.usesWebHotReload;
369+
final usesDdcLibraryBundle =
370+
options.ddcLibraryBundle || usesWebHotReload;
357371
await bootstrapDdc(
358372
buildStep,
359373
nativeNullAssertions: options.nativeNullAssertions,
360374
requiredAssets:
361-
usesWebHotReload
375+
usesDdcLibraryBundle
362376
? _ddcLibraryBundleSdkResources
363377
: _ddcSdkResources,
364378
usesWebHotReload: usesWebHotReload,
379+
ddcLibraryBundle: usesDdcLibraryBundle,
365380
unsafeAllowUnsupportedModules:
366381
options.unsafeAllowUnsupportedModules,
367382
);

build_web_compilers/lib/src/web_entrypoint_marker_builder.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import 'package:glob/glob.dart';
1111
/// A builder that gathers information about a web target's 'main' entrypoint.
1212
class WebEntrypointMarkerBuilder implements Builder {
1313
/// Records state (such as the web entrypoint) required when compiling DDC
14-
/// with the Library Bundle module system.
14+
/// with the Frontend Server, which supports hot reload.
1515
///
1616
/// A no-op if [usesWebHotReload] is not set.
1717
final bool usesWebHotReload;

0 commit comments

Comments
 (0)