in build_web_compilers/lib/src/dev_compiler_bootstrap.dart [30:159]
Future<void> bootstrapDdc(
BuildStep buildStep, {
DartPlatform? platform,
Iterable<AssetId> requiredAssets = const [],
required bool soundNullSafety,
required bool nativeNullAssertions,
required bool nullAssertions,
}) async {
platform = ddcPlatform;
// Ensures that the sdk resources are built and available.
await _ensureResources(buildStep, requiredAssets);
var dartEntrypointId = buildStep.inputId;
var moduleId = buildStep.inputId.changeExtension(moduleExtension(platform));
var module = Module.fromJson(json
.decode(await buildStep.readAsString(moduleId)) as Map<String, dynamic>);
// First, ensure all transitive modules are built.
List<AssetId> transitiveJsModules;
try {
transitiveJsModules = await _ensureTransitiveJsModules(module, buildStep,
soundNullSafety: soundNullSafety);
} on UnsupportedModules catch (e) {
var librariesString = (await e.exactLibraries(buildStep).toList())
.map((lib) => AssetId(lib.id.package,
lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
.join('\n');
log.warning('''
Skipping compiling ${buildStep.inputId} with ddc because some of its
transitive libraries have sdk dependencies that not supported on this platform:
$librariesString
https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
''');
return;
}
var jsId =
module.primarySource.changeExtension(jsModuleExtension(soundNullSafety));
var appModuleName = ddcModuleName(jsId, soundNullSafety);
var appDigestsOutput =
dartEntrypointId.changeExtension(digestsEntrypointExtension);
var mergedMetadataOutput =
dartEntrypointId.changeExtension(mergedMetadataExtension);
// The name of the entrypoint dart library within the entrypoint JS module.
//
// This is used to invoke `main()` from within the bootstrap script.
//
// TODO(jakemac53): Sane module name creation, this only works in the most
// basic of cases.
//
// See https://github.com/dart-lang/sdk/issues/27262 for the root issue
// which will allow us to not rely on the naming schemes that dartdevc uses
// internally, but instead specify our own.
var oldAppModuleScope = toJSIdentifier(
_context.withoutExtension(_context.basename(buildStep.inputId.path)));
// Like above but with a package-relative entrypoint.
var appModuleScope =
pathToJSIdentifier(_context.withoutExtension(buildStep.inputId.path));
// Map from module name to module path for custom modules.
var modulePaths = SplayTreeMap.of({
'dart_sdk': r'packages/build_web_compilers/src/dev_compiler/dart_sdk'
'${soundNullSafety ? '.sound' : ''}'
});
for (var jsId in transitiveJsModules) {
// Strip out the top level dir from the path for any module, and set it to
// `packages/` for lib modules. We set baseUrl to `/` to simplify things,
// and we only allow you to serve top level directories.
var moduleName = ddcModuleName(jsId, soundNullSafety);
modulePaths[moduleName] = _context.withoutExtension(
jsId.path.startsWith('lib')
? '$moduleName${jsModuleExtension(soundNullSafety)}'
: _context.joinAll(_context.split(jsId.path).skip(1)));
}
var bootstrapId = dartEntrypointId.changeExtension(ddcBootstrapExtension);
var bootstrapModuleName = _context.withoutExtension(_context.relative(
bootstrapId.path,
from: _context.dirname(dartEntrypointId.path)));
var dartEntrypointParts = _context.split(dartEntrypointId.path);
var entrypointLibraryName = _context.joinAll([
// Convert to a package: uri for files under lib.
if (dartEntrypointParts.first == 'lib')
'package:${module.primarySource.package}',
// Strip top-level directory from the path.
...dartEntrypointParts.skip(1),
]);
var bootstrapContent =
StringBuffer('$_entrypointExtensionMarker\n(function() {\n')
..write(_dartLoaderSetup(
modulePaths,
_p.url.relative(appDigestsOutput.path,
from: _p.url.dirname(bootstrapId.path)),
soundNullSafety))
..write(_requireJsConfig(soundNullSafety))
..write(_appBootstrap(
bootstrapModuleName: bootstrapModuleName,
entrypointLibraryName: entrypointLibraryName,
moduleName: appModuleName,
moduleScope: appModuleScope,
nativeNullAssertions: nativeNullAssertions,
nullAssertions: nullAssertions,
oldModuleScope: oldAppModuleScope));
await buildStep.writeAsString(bootstrapId, bootstrapContent.toString());
var entrypointJsContent = _entryPointJs(bootstrapModuleName);
await buildStep.writeAsString(
dartEntrypointId.changeExtension(jsEntrypointExtension),
entrypointJsContent);
// Output the digests and merged_metadata for transitive modules.
// These can be consumed for hot reloads and debugging.
var mergedMetadataContent = StringBuffer();
var moduleDigests = <String, String>{};
for (var jsId in transitiveJsModules) {
mergedMetadataContent.writeln(
await buildStep.readAsString(jsId.changeExtension('.js.metadata')));
moduleDigests[_moduleDigestKey(jsId, soundNullSafety)] =
'${await buildStep.digest(jsId)}';
}
await buildStep.writeAsString(appDigestsOutput, jsonEncode(moduleDigests));
await buildStep.writeAsString(
mergedMetadataOutput, mergedMetadataContent.toString());
}