Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser] introduce sourcemaps #86152

Merged
merged 2 commits into from
Jun 28, 2023
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: 2 additions & 0 deletions eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,10 @@
<LibrariesRuntimeFiles Condition="'$(TargetOS)' == 'browser'"
Include="
$(LibrariesNativeArtifactsPath)dotnet.js;
$(LibrariesNativeArtifactsPath)dotnet.js.map;
$(LibrariesNativeArtifactsPath)dotnet.native.js;
$(LibrariesNativeArtifactsPath)dotnet.runtime.js;
$(LibrariesNativeArtifactsPath)dotnet.runtime.js.map;
$(LibrariesNativeArtifactsPath)dotnet.d.ts;
$(LibrariesNativeArtifactsPath)dotnet-legacy.d.ts;
$(LibrariesNativeArtifactsPath)package.json;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@
<PlatformManifestFileEntry Include="libmono-wasm-eh-wasm.a" IsNative="true" />
<PlatformManifestFileEntry Include="wasm-bundled-timezones.a" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.js.map" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.runtime.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.runtime.js.map" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.worker.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.js.symbols" IsNative="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ Copyright (c) .NET Foundation. All rights reserved.
Condition="@(WasmNativeAsset->Count()) > 0 and ( '%(FileName)' == 'dotnet' or '%(FileName)' == 'dotnet.native' ) and ('%(Extension)' == '.wasm' or '%(Extension)' == '.js')" />
</ItemGroup>

<PropertyGroup>
<_WasmEmitSourceMapBuild>$(WasmEmitSourceMap)</_WasmEmitSourceMapBuild>
<_WasmEmitSourceMapBuild Condition="'$(_WasmEmitSourceMapBuild)' == ''">true</_WasmEmitSourceMapBuild>
</PropertyGroup>

<ComputeWasmBuildAssets
Candidates="@(ReferenceCopyLocalPaths->Distinct());@(WasmNativeAsset)"
CustomIcuCandidate="$(_BlazorIcuDataFileName)"
Expand All @@ -222,6 +227,7 @@ Copyright (c) .NET Foundation. All rights reserved.
OutputPath="$(OutputPath)"
FingerprintDotNetJs="$(WasmFingerprintDotnetJs)"
EnableThreads="$(_WasmEnableThreads)"
EmitSourceMap="$(_WasmEmitSourceMapBuild)"
>
<Output TaskParameter="AssetCandidates" ItemName="_BuildAssetsCandidates" />
<Output TaskParameter="FilesToRemove" ItemName="_WasmBuildFilesToRemove" />
Expand Down Expand Up @@ -376,6 +382,11 @@ Copyright (c) .NET Foundation. All rights reserved.
Condition="'%(StaticWebAsset.AssetTraitName)' == 'WasmResource' or '%(StaticWebAsset.AssetTraitName)' == 'Culture' or '%(AssetRole)' == 'Alternative'" />
</ItemGroup>

<PropertyGroup>
<_WasmEmitSourceMapPublish>$(WasmEmitSourceMap)</_WasmEmitSourceMapPublish>
<_WasmEmitSourceMapPublish Condition="'$(_WasmEmitSourceMapPublish)' == ''">false</_WasmEmitSourceMapPublish>
</PropertyGroup>

<ComputeWasmPublishAssets
ResolvedFilesToPublish="@(ResolvedFileToPublish)"
CustomIcuCandidate="$(_BlazorIcuDataFileName)"
Expand All @@ -388,6 +399,7 @@ Copyright (c) .NET Foundation. All rights reserved.
DotNetJsVersion="$(_WasmRuntimePackVersion)"
FingerprintDotNetJs="$(WasmFingerprintDotnetJs)"
EnableThreads="$(_WasmEnableThreads)"
EmitSourceMap="$(_WasmEmitSourceMapPublish)"
IsWebCilEnabled="$(_WasmEnableWebcil)"
>
<Output TaskParameter="NewCandidates" ItemName="_NewWasmPublishStaticWebAssets" />
Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,10 @@ protected static void AssertBasicAppBundle(string bundleDir,
"_framework/dotnet.native.wasm",
"_framework/blazor.boot.json",
"_framework/dotnet.js",
"_framework/dotnet.js.map",
"_framework/dotnet.native.js",
"_framework/dotnet.runtime.js"
"_framework/dotnet.runtime.js",
"_framework/dotnet.runtime.js.map",
};

if (isBrowserProject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ internal void CompareStat(IDictionary<string, FileStat> oldStat, IDictionary<str

// those files do not change on re-link
dict["dotnet.js"]=(Path.Combine(paths.BundleDir, "_framework", "dotnet.js"), true);
dict["dotnet.js.map"]=(Path.Combine(paths.BundleDir, "_framework", "dotnet.js.map"), true);
dict["dotnet.runtime.js"]=(Path.Combine(paths.BundleDir, "_framework", "dotnet.runtime.js"), true);
dict["dotnet.runtime.js.map"]=(Path.Combine(paths.BundleDir, "_framework", "dotnet.runtime.js.map"), true);

return dict;
}
Expand Down
5 changes: 5 additions & 0 deletions src/mono/wasm/build/WasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- $(WasmNativeDebugSymbols) - Build with native debug symbols, useful only with `$(RunAOTCompilation)`, or `$(WasmBuildNative)`
Defaults to true.
- $(WasmEmitSymbolMap) - Generates a `dotnet.native.js.symbols` file with a map of wasm function number to name.
- $(WasmEmitSourceMap) - Generates `dotnet.runtime.js.map` and `dotnet.js.map` files with a TypeScript source map.
- $(WasmDedup) - Whenever to dedup generic instances when using AOT. Defaults to true.

- $(WasmProfilers) - Profilers to use
Expand Down Expand Up @@ -356,6 +357,10 @@
Condition="'$(WasmEmitSymbolMap)' == 'true' and
'$(_HasDotnetJsSymbols)' != 'true' and
Exists('$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.native.js.symbols')" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.js.map"
Condition="'$(WasmEmitSourceMap)' != 'false'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.runtime.js.map"
Condition="'$(WasmEmitSourceMap)' != 'false'" />
</ItemGroup>

<ItemGroup Condition="'$(InvariantGlobalization)' != 'true'">
Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ interface BootJsonData {
readonly resources: ResourceGroups;
/** Gets a value that determines if this boot config was produced from a non-published build (i.e. dotnet build or dotnet run) */
readonly debugBuild: boolean;
readonly debugLevel: number;
readonly linkerEnabled: boolean;
readonly cacheBootResources: boolean;
readonly config: string[];
Expand Down
3 changes: 2 additions & 1 deletion src/mono/wasm/runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
"author": "Microsoft",
"license": "MIT",
"devDependencies": {
"@rollup/plugin-terser": "0.4.1",
"@rollup/plugin-typescript": "11.1.0",
"@rollup/plugin-virtual": "3.0.1",
"@rollup/plugin-terser": "0.4.1",
"@typescript-eslint/eslint-plugin": "5.59.1",
"@typescript-eslint/parser": "5.59.1",
"magic-string": "0.30.0",
"eslint": "8.39.0",
"fast-glob": "3.2.12",
"git-commit-info": "2.0.1",
Expand Down
103 changes: 73 additions & 30 deletions src/mono/wasm/runtime/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import dts from "rollup-plugin-dts";
import { createFilter } from "@rollup/pluginutils";
import fast_glob from "fast-glob";
import gitCommitInfo from "git-commit-info";
import MagicString from "magic-string";

const configuration = process.env.Configuration;
const isDebug = configuration !== "Release";
const isContinuousIntegrationBuild = process.env.ContinuousIntegrationBuild === "true" ? true : false;
const productVersion = process.env.ProductVersion || "8.0.0-dev";
const nativeBinDir = process.env.NativeBinDir ? process.env.NativeBinDir.replace(/"/g, "") : "bin";
const monoWasmThreads = process.env.MonoWasmThreads === "true" ? true : false;
Expand All @@ -38,13 +40,15 @@ const banner_dts = banner + "//!\n//! This is generated file, see src/mono/wasm/
// emcc doesn't know how to load ES6 module, that's why we need the whole rollup.js
const inlineAssert = [
{
pattern: /mono_assert\(([^,]*), *"([^"]*)"\);/gm,
// eslint-disable-next-line quotes
replacement: 'if (!($1)) throw new Error("Assert failed: $2"); // inlined mono_assert'
pattern: 'mono_assert\\(([^,]*), *"([^"]*)"\\);',
// eslint-disable-next-line quotes
replacement: (match) => `if (!(${match[1]})) throw new Error("Assert failed: ${match[2]}"); // inlined mono_assert`
},
{
pattern: /mono_assert\(([^,]*), \(\) => *`([^`]*)`\);/gm,
replacement: "if (!($1)) throw new Error(`Assert failed: $2`); // inlined mono_assert"
// eslint-disable-next-line quotes
pattern: 'mono_assert\\(([^,]*), \\(\\) => *`([^`]*)`\\);',
replacement: (match) => `if (!(${match[1]})) throw new Error(\`Assert failed: ${match[2]}\`); // inlined mono_assert`
}
];
const checkAssert =
Expand Down Expand Up @@ -78,8 +82,28 @@ const envConstants = {
monoDiagnosticsMock,
gitHash,
wasmEnableLegacyJsInterop,
isContinuousIntegrationBuild,
};

const locationCache = {};
function sourcemapPathTransform(relativeSourcePath, sourcemapPath) {
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
let res = locationCache[relativeSourcePath];
if (res === undefined) {
if (!isContinuousIntegrationBuild) {
const sourcePath = path.resolve(
path.dirname(sourcemapPath),
relativeSourcePath
);
res = `file:///${sourcePath.replace(/\\/g, "/")}`;
} else {
relativeSourcePath = relativeSourcePath.substring(12);
res = `https://raw.githubusercontent.com/dotnet/runtime/${gitHash}/${relativeSourcePath}`;
}
locationCache[relativeSourcePath] = res;
}
return res;
}

function consts(dict) {
// implement rollup-plugin-const in terms of @rollup/plugin-virtual
// It's basically the same thing except "consts" names all its modules with a "consts:" prefix,
Expand All @@ -103,7 +127,7 @@ const typescriptConfigOptions = {
};

const outputCodePlugins = [consts(envConstants), typescript(typescriptConfigOptions)];
const externalDependencies = ["module"];
const externalDependencies = ["module", "process"];

const loaderConfig = {
treeshake: !isDebug,
Expand All @@ -114,25 +138,14 @@ const loaderConfig = {
file: nativeBinDir + "/dotnet.js",
banner,
plugins,
sourcemap: true,
sourcemapPathTransform,
}
],
external: externalDependencies,
plugins: [regexReplace(inlineAssert), regexCheck([checkAssert, checkNoRuntime]), ...outputCodePlugins],
onwarn: onwarn
};
const typesConfig = {
input: "./types/export-types.ts",
output: [
{
format: "es",
file: nativeBinDir + "/dotnet.d.ts",
banner: banner_dts,
plugins: [writeOnChangePlugin()],
}
],
external: externalDependencies,
plugins: [dts()],
};
const runtimeConfig = {
treeshake: !isDebug,
input: "exports.ts",
Expand All @@ -142,13 +155,28 @@ const runtimeConfig = {
file: nativeBinDir + "/dotnet.runtime.js",
banner,
plugins,
sourcemap: true,
sourcemapPathTransform,
}
],
external: externalDependencies,
plugins: [regexReplace(inlineAssert), regexCheck([checkAssert, checkNoLoader]), ...outputCodePlugins],
onwarn: onwarn
};
const legacyConfig = {
const typesConfig = {
input: "./types/export-types.ts",
output: [
{
format: "es",
file: nativeBinDir + "/dotnet.d.ts",
banner: banner_dts,
plugins: [writeOnChangePlugin()],
}
],
external: externalDependencies,
plugins: [dts()],
};
const legacyTypesConfig = {
input: "./net6-legacy/export-types.ts",
output: [
{
Expand All @@ -174,7 +202,7 @@ if (isDebug) {
banner: banner_dts,
plugins: [alwaysLF(), writeOnChangePlugin()],
});
legacyConfig.output.push({
legacyTypesConfig.output.push({
format: "es",
file: "./dotnet-legacy.d.ts",
banner: banner_dts,
Expand Down Expand Up @@ -221,7 +249,7 @@ const allConfigs = [
loaderConfig,
runtimeConfig,
typesConfig,
legacyConfig,
legacyTypesConfig,
].concat(workerConfigs)
.concat(diagnosticMockTypesConfig ? [diagnosticMockTypesConfig] : []);
export default defineConfig(allConfigs);
Expand Down Expand Up @@ -336,19 +364,34 @@ function regexReplace(replacements = []) {
}
};

function executeReplacement(_, code) {
// TODO use MagicString for sourcemap support
let fixed = code;
for (const rep of replacements) {
const { pattern, replacement } = rep;
fixed = fixed.replace(pattern, replacement);
function executeReplacement(_, code, id) {
const magicString = new MagicString(code);
if (!codeHasReplacements(code, id, magicString)) {
return null;
}

if (fixed == code) {
return null;
const result = { code: magicString.toString() };
result.map = magicString.generateMap({ hires: true });
return result;
}

function codeHasReplacements(code, id, magicString) {
let result = false;
let match;
for (const rep of replacements) {
const { pattern, replacement } = rep;
const rx = new RegExp(pattern, "gm");
while ((match = rx.exec(code))) {
result = true;
const updated = replacement(match);
const start = match.index;
const end = start + match[0].length;
magicString.overwrite(start, end, updated);
}
}

return { code: fixed };
// eslint-disable-next-line no-cond-assign
return result;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/mono/wasm/runtime/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"esnext",
"dom"
],
"sourceMap": true,
}
}
}
4 changes: 3 additions & 1 deletion src/mono/wasm/wasm.proj
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,9 @@
</ItemGroup>

<Copy SourceFiles="$(NativeBinDir)dotnet.js;
$(NativeBinDir)dotnet.js.map;
$(NativeBinDir)dotnet.runtime.js;
$(NativeBinDir)dotnet.runtime.js.map;
$(NativeBinDir)dotnet.native.js;
$(NativeBinDir)dotnet.d.ts;
$(NativeBinDir)dotnet-legacy.d.ts;
Expand Down Expand Up @@ -514,7 +516,7 @@

<Target Name="SetMonoRollupEnvironment" DependsOnTargets="GetProductVersions">
<PropertyGroup>
<MonoRollupEnvironment>Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),DISABLE_LEGACY_JS_INTEROP:$(_DisableLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock)</MonoRollupEnvironment>
<MonoRollupEnvironment>Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),DISABLE_LEGACY_JS_INTEROP:$(_DisableLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock),ContinuousIntegrationBuild:$(ContinuousIntegrationBuild)</MonoRollupEnvironment>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static bool ShouldFilterCandidate(
bool copySymbols,
string customIcuCandidateFilename,
bool enableThreads,
bool emitSourceMap,
out string reason)
{
var extension = candidate.GetMetadata("Extension");
Expand All @@ -55,6 +56,7 @@ public static bool ShouldFilterCandidate(
".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file will be used instead of icu from the runtime pack",
".json" when fromMonoPackage && (fileName == "emcc-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor",
".ts" when fromMonoPackage && fileName == "dotnet.d" => "dotnet type definition is not used by Blazor",
".map" when !emitSourceMap && fromMonoPackage && (fileName == "dotnet.js" || fileName == "dotnet.runtime.js") => "source map file is not published",
".ts" when fromMonoPackage && fileName == "dotnet-legacy.d" => "dotnet type definition is not used by Blazor",
".js" when assetType == "native" && !(dotnetJsSingleThreadNames.Contains(fileName) || (enableThreads && fileName == "dotnet.native.worker")) => $"{fileName}{extension} is not used by Blazor",
".pdb" when !copySymbols => "copying symbols is disabled",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class ComputeWasmBuildAssets : Task

public bool EnableThreads { get; set; }

public bool EmitSourceMap { get; set; }

[Output]
public ITaskItem[] AssetCandidates { get; set; }

Expand Down Expand Up @@ -84,7 +86,7 @@ public override bool Execute()
for (int i = 0; i < Candidates.Length; i++)
{
var candidate = Candidates[i];
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, out var reason))
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
{
Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason);
filesToRemove.Add(candidate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public class ComputeWasmPublishAssets : Task

public bool EnableThreads { get; set; }

public bool EmitSourceMap { get; set; }

public bool IsWebCilEnabled { get; set; }

[Output]
Expand Down Expand Up @@ -575,7 +577,7 @@ private void GroupResolvedFilesToPublish(

foreach (var candidate in resolvedFilesToPublish)
{
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, out var reason))
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
{
Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason);
if (!resolvedFilesToPublishToRemove.ContainsKey(candidate.ItemSpec))
Expand Down
Loading
Loading