Skip to content

Commit 10bf161

Browse files
committed
build
1 parent 1ec48e5 commit 10bf161

File tree

6 files changed

+320
-18
lines changed

6 files changed

+320
-18
lines changed

src/native/corehost/browserhost/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ set(SAMPLE_ASSETS
8888
# ${CLR_ARTIFACTS_OBJ_DIR}/sfx-finish/${CMAKE_BUILD_TYPE}/net10.0-browser/illink-wasm/System.Threading.dll
8989
# ${CLR_ARTIFACTS_BIN_DIR}/artifacts/bin/HelloWorld/${CMAKE_BUILD_TYPE}/net10.0/win-x64/HelloWorld.dll
9090
${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.js
91-
# WASM-TODO ${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.js.map
91+
${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.js.map
9292
${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.d.ts
9393
${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.js
94-
# WASM-TODO ${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.js.map
94+
${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.js.map
9595
)
9696
install(FILES ${SAMPLE_ASSETS} DESTINATION corehost COMPONENT runtime)

src/native/libs/System.Native.Browser/CMakeLists.txt

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,33 @@ add_library(System.Native.Browser-Static
1313
set_target_properties(System.Native.Browser-Static PROPERTIES OUTPUT_NAME System.Native.Browser CLEAN_DIRECT_OUTPUT 1)
1414
install(TARGETS System.Native.Browser-Static DESTINATION ${STATIC_LIB_DESTINATION} COMPONENT libs)
1515

16-
# WASM-TODO *.ts files instead
17-
set(ROLLUP_TS_SOURCES
18-
"${CMAKE_CURRENT_SOURCE_DIR}/../../corehost/browserhost/loader/dotnet.js"
19-
"${CMAKE_CURRENT_SOURCE_DIR}/../../corehost/browserhost/loader/dotnet.d.ts"
20-
"${CMAKE_CURRENT_SOURCE_DIR}/../../corehost/browserhost/libBrowserHost.js"
21-
"${CMAKE_CURRENT_SOURCE_DIR}/libSystem.Native.Browser.js"
22-
"${CMAKE_CURRENT_SOURCE_DIR}/libSystem.Native.Browser.extpost.js"
23-
"${CMAKE_CURRENT_SOURCE_DIR}/../System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.js"
24-
"${CMAKE_CURRENT_SOURCE_DIR}/../System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.js"
25-
"${CMAKE_CURRENT_SOURCE_DIR}/./libSystem.Native.Browser.extpost.js"
26-
"${CMAKE_CURRENT_SOURCE_DIR}/./libSystem.Native.Browser.js"
27-
"${CMAKE_CURRENT_SOURCE_DIR}/../../package.json"
28-
"${CMAKE_CURRENT_SOURCE_DIR}/../../tsconfig.json"
16+
17+
file(GLOB_RECURSE ROLLUP_TS_SOURCES
18+
"${CMAKE_CURRENT_SOURCE_DIR}/*.ts"
19+
"${CMAKE_CURRENT_SOURCE_DIR}/*.js"
20+
"${CMAKE_CURRENT_SOURCE_DIR}/../System.Runtime.InteropServices.JavaScript.Native/*.ts"
21+
"${CMAKE_CURRENT_SOURCE_DIR}/../System.Runtime.InteropServices.JavaScript.Native/*.js"
22+
"${CMAKE_CURRENT_SOURCE_DIR}/../Common/JavaScript/*.ts"
23+
"${CMAKE_CURRENT_SOURCE_DIR}/../Common/JavaScript/*.js"
24+
"${CMAKE_CURRENT_SOURCE_DIR}/../../corehost/browserhost/*.ts"
25+
"${CMAKE_CURRENT_SOURCE_DIR}/../../corehost/browserhost/*.js"
26+
"${CMAKE_CURRENT_SOURCE_DIR}../../package.json"
27+
"${CMAKE_CURRENT_SOURCE_DIR}../../tsconfig.json"
28+
"${CMAKE_CURRENT_SOURCE_DIR}/../../node_modules/.npm-stamp"
2929
)
3030

31-
# WASM-TODO *.js.map files
3231
set(ROLLUP_OUTPUTS
3332
"${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.js"
33+
"${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.js.map"
3434
"${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/dotnet.d.ts"
3535
"${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/libBrowserHost.js"
36+
"${CLR_ARTIFACTS_OBJ_DIR}/coreclr/browser.wasm.${CMAKE_BUILD_TYPE}/corehost/libBrowserHost.js.map"
3637
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Native.Browser.js"
38+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/libSystem.Native.Browser.js.map"
3739
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/dotnet.runtime.js"
40+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Native.Browser/dotnet.runtime.js.map"
3841
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.js"
42+
"${CLR_ARTIFACTS_OBJ_DIR}/native/browser-${CMAKE_BUILD_TYPE}-wasm/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.js.map"
3943
)
4044

4145
set(ROLLUP_STAMP
@@ -54,7 +58,7 @@ endif()
5458
add_custom_command(
5559
OUTPUT ${ROLLUP_STAMP}
5660
BYPRODUCTS ${ROLLUP_OUTPUTS}
57-
COMMAND npm run rollup:stub -- ${CMAKE_BUILD_TYPE} ${PRODUCT_VERSION_JS} ${CI_BUILD_JS}
61+
COMMAND npm run rollup:cmake -- "Configuration:${CMAKE_BUILD_TYPE},ProductVersion:${PRODUCT_VERSION_JS},ContinuousIntegrationBuild:${CI_BUILD_JS}"
5862
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../.."
5963
COMMENT "Running 'npm run rollup' to generate JavaScript bundles"
6064
DEPENDS ${ROLLUP_TS_SOURCES}

src/native/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"type": "module",
1111
"types": "dotnet.d.ts",
1212
"scripts": {
13-
"rollup:stub": "node rollup.stub.js",
1413
"rollup:cmake": "rollup -c --environment ",
1514
"rollup:release": "rollup -c --environment Configuration:Release,ProductVersion:10.0.0-dev,ContinuousIntegrationBuild:false",
1615
"rollup:debug": "rollup -c --environment Configuration:Debug,ProductVersion:10.0.0-dev,ContinuousIntegrationBuild:false",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//! Licensed to the .NET Foundation under one or more agreements.
2+
//! The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import gitCommitInfo from "git-commit-info";
5+
6+
export const configuration = process.env.Configuration || "Debug";
7+
export const productVersion = process.env.ProductVersion || "10.0.0-dev";
8+
export const isContinuousIntegrationBuild = process.env.ContinuousIntegrationBuild === "true" ? true : false;
9+
10+
console.log(`Rollup configuration: Configuration=${configuration}, ProductVersion=${productVersion}, ContinuousIntegrationBuild=${isContinuousIntegrationBuild}`);
11+
12+
export const banner = "//! Licensed to the .NET Foundation under one or more agreements.\n//! The .NET Foundation licenses this file to you under the MIT license.\n//! This is generated file, see src/native/libs/Browser/rollup.config.defines.js\n\n";
13+
export const banner_dts = banner + "//! This is not considered public API with backward compatibility guarantees. \n";
14+
export const keep_classnames = /(ManagedObject|ManagedError|Span|ArraySegment)/;
15+
export const reserved = ["Assert", "JSEngine", "Logger", "Module", "dotnetInternals", "interopExports", "loaderExports", "nativeExports", "runtimeApi", "runtimeExports"];
16+
export const externalDependencies = ["module", "process", "perf_hooks", "node:crypto"];
17+
export const artifactsObjDir = "../../artifacts/obj";
18+
export const isDebug = configuration !== "Release";
19+
20+
let gitHash;
21+
try {
22+
const gitInfo = gitCommitInfo();
23+
gitHash = gitInfo.hash;
24+
} catch (e) {
25+
gitHash = "unknown";
26+
}
27+
28+
export const envConstants = {
29+
productVersion,
30+
configuration,
31+
gitHash,
32+
isContinuousIntegrationBuild,
33+
};

src/native/rollup.config.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! Licensed to the .NET Foundation under one or more agreements.
2+
//! The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import { defineConfig } from "rollup";
5+
import typescript from "@rollup/plugin-typescript";
6+
import { nodeResolve } from "@rollup/plugin-node-resolve";
7+
import dts from "rollup-plugin-dts";
8+
import { terserPlugin, writeOnChangePlugin, consts, onwarn, alwaysLF, iife2fe, sourcemapPathTransform } from "./rollup.config.plugins.js"
9+
import { externalDependencies, isDebug, artifactsObjDir, envConstants, banner, banner_dts, configuration } from "./rollup.config.defines.js"
10+
import { promises as fs } from "fs";
11+
12+
const dotnetDTS = {
13+
input: "./libs/Common/JavaScript/types/export-api.ts",
14+
output: [
15+
{
16+
format: "es",
17+
file: artifactsObjDir + `/coreclr/browser.wasm.${configuration}/corehost/dotnet.d.ts`,
18+
banner: banner_dts,
19+
plugins: [writeOnChangePlugin()],
20+
},
21+
...(isDebug ? [{
22+
format: "es",
23+
file: "./corehost/browserhost/loader/dotnet.d.ts",
24+
banner: banner_dts,
25+
plugins: [alwaysLF(), writeOnChangePlugin()],
26+
}] : [])
27+
],
28+
external: externalDependencies,
29+
plugins: [dts()],
30+
onwarn
31+
};
32+
33+
const dotnetJS = configure({
34+
input: "./corehost/browserhost/loader/dotnet.ts",
35+
output: [{
36+
file: artifactsObjDir + `/coreclr/browser.wasm.${configuration}/corehost/dotnet.js`,
37+
intro: "/*! bundlerFriendlyImports */",
38+
}],
39+
});
40+
41+
const libNativeBrowser = configure({
42+
input: "./libs/System.Native.Browser/native/index.ts",
43+
output: [{
44+
name: "libNativeBrowser",
45+
format: "iife",
46+
file: artifactsObjDir + `/native/browser-${configuration}-wasm/System.Native.Browser/libSystem.Native.Browser.js`,
47+
footer: await fs.readFile("./libs/System.Native.Browser/libSystem.Native.Browser.footer.js"),
48+
}],
49+
});
50+
51+
const dotnetRuntimeJS = configure({
52+
input: "./libs/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.ts",
53+
output: [{
54+
file: artifactsObjDir + `/native/browser-${configuration}-wasm/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.js`,
55+
}],
56+
});
57+
58+
const libInteropJavaScriptNative = configure({
59+
input: "./libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts",
60+
output: [{
61+
name: "libInteropJavaScriptNative",
62+
format: "iife",
63+
file: artifactsObjDir + `/native/browser-${configuration}-wasm/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.js`,
64+
footer: await fs.readFile("./libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js"),
65+
}],
66+
});
67+
68+
const libBrowserHost = configure({
69+
input: "./corehost/browserhost/host/index.ts",
70+
output: [{
71+
name: "libBrowserHost",
72+
format: "iife",
73+
file: artifactsObjDir + `/coreclr/browser.wasm.${configuration}/corehost/libBrowserHost.js`,
74+
footer: await fs.readFile("./corehost/browserhost/libBrowserHost.footer.js"),
75+
}],
76+
});
77+
78+
export default defineConfig([
79+
dotnetJS,
80+
dotnetDTS,
81+
libNativeBrowser,
82+
dotnetRuntimeJS,
83+
libInteropJavaScriptNative,
84+
libBrowserHost,
85+
]);
86+
87+
function configure({ input, output }) {
88+
return {
89+
treeshake: !isDebug,
90+
input,
91+
output: output.map(o => {
92+
return {
93+
banner,
94+
format: "es",
95+
plugins: isDebug
96+
? [iife2fe(), writeOnChangePlugin()]
97+
: [terserPlugin(), iife2fe(), writeOnChangePlugin()],
98+
sourcemap: true, //isDebug ? true : "hidden",
99+
sourcemapPathTransform,
100+
...o
101+
}
102+
}),
103+
external: externalDependencies,
104+
plugins: [
105+
nodeResolve(),
106+
consts(envConstants),
107+
typescript({
108+
tsconfig: "./tsconfig.json",
109+
})
110+
],
111+
onwarn,
112+
}
113+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
//! Licensed to the .NET Foundation under one or more agreements.
2+
//! The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import { createHash } from "crypto";
5+
import { readFile, writeFile, mkdir } from "fs/promises";
6+
import virtual from "@rollup/plugin-virtual";
7+
import * as fs from "fs";
8+
import * as path from "path";
9+
import terser from "@rollup/plugin-terser";
10+
11+
import { isContinuousIntegrationBuild, keep_classnames, reserved } from "./rollup.config.defines.js"
12+
13+
export const terserPlugin = () => terser({
14+
compress: {
15+
defaults: true,
16+
passes: 2,
17+
drop_debugger: false, // we invoke debugger
18+
drop_console: false, // we log to console
19+
keep_classnames,
20+
ecma: "2015",
21+
toplevel: true,
22+
},
23+
format: {
24+
beautify: true,
25+
},
26+
mangle: {
27+
keep_classnames,
28+
reserved,
29+
toplevel: true,
30+
},
31+
});
32+
33+
// this would create .sha256 file next to the output file, so that we do not touch datetime of the file if it's same -> faster incremental build.
34+
export const writeOnChangePlugin = () => ({
35+
name: "writeOnChange",
36+
generateBundle: writeWhenChanged
37+
});
38+
39+
// Drop invocation from IIFE
40+
export function iife2fe() {
41+
return {
42+
name: "iife2fe",
43+
generateBundle: (options, bundle) => {
44+
const name = Object.keys(bundle)[0];
45+
if (name.endsWith(".map")) return;
46+
const asset = bundle[name];
47+
const code = asset.code;
48+
//throw new Error("iife2fe " + code);
49+
asset.code = code
50+
.replace(/}\({}\);/, "};") // }({}); ->};
51+
.replace(/}\)\({}\);/, "});") // })({}); ->});
52+
;
53+
}
54+
};
55+
}
56+
57+
// force always unix line ending
58+
export const alwaysLF = () => ({
59+
name: "writeOnChange",
60+
generateBundle: (options, bundle) => {
61+
const name = Object.keys(bundle)[0];
62+
const asset = bundle[name];
63+
const code = asset.code;
64+
asset.code = code.replace(/\r/g, "");
65+
}
66+
});
67+
68+
async function writeWhenChanged(options, bundle) {
69+
try {
70+
const name = Object.keys(bundle)[0];
71+
const asset = bundle[name];
72+
const code = asset.code;
73+
const hashFileName = options.file + ".sha256";
74+
const oldHashExists = await checkFileExists(hashFileName);
75+
const oldFileExists = await checkFileExists(options.file);
76+
77+
const newHash = createHash("sha256").update(code).digest("hex");
78+
79+
let isOutputChanged = true;
80+
if (oldHashExists && oldFileExists) {
81+
const oldHash = await readFile(hashFileName, { encoding: "ascii" });
82+
isOutputChanged = oldHash !== newHash;
83+
}
84+
if (isOutputChanged) {
85+
const dir = path.dirname(options.file);
86+
if (!await checkFileExists(dir)) {
87+
await mkdir(dir, { recursive: true });
88+
}
89+
await writeFile(hashFileName, newHash);
90+
} else {
91+
// this.warn('No change in ' + options.file)
92+
delete bundle[name];
93+
}
94+
} catch (ex) {
95+
this.warn(ex.toString());
96+
}
97+
}
98+
99+
function checkFileExists(file) {
100+
return fs.promises.access(file, fs.constants.F_OK)
101+
.then(() => true)
102+
.catch(() => false);
103+
}
104+
105+
export function onwarn(warning) {
106+
if (warning.code === "CIRCULAR_DEPENDENCY") {
107+
return;
108+
}
109+
110+
if (warning.code === "UNRESOLVED_IMPORT" && warning.exporter === "process") {
111+
return;
112+
}
113+
114+
if (warning.code === "PLUGIN_WARNING" && warning.message.indexOf("sourcemap") !== -1) {
115+
return;
116+
}
117+
118+
// eslint-disable-next-line no-console
119+
console.warn(`(!) ${warning.toString()} ${warning.code}`);
120+
}
121+
122+
export function consts(dict) {
123+
// implement rollup-plugin-const in terms of @rollup/plugin-virtual
124+
// It's basically the same thing except "consts" names all its modules with a "consts:" prefix,
125+
// and the virtual module always exports a single default binding (the const value).
126+
127+
let newDict = {};
128+
for (const k in dict) {
129+
const newKey = "consts:" + k;
130+
const newVal = JSON.stringify(dict[k]);
131+
newDict[newKey] = `export default ${newVal}`;
132+
}
133+
return virtual(newDict);
134+
}
135+
136+
const locationCache = {};
137+
export function sourcemapPathTransform(relativeSourcePath, sourcemapPath) {
138+
let res = locationCache[relativeSourcePath];
139+
if (res === undefined) {
140+
if (!isContinuousIntegrationBuild) {
141+
const sourcePath = path.resolve(
142+
path.dirname(sourcemapPath),
143+
relativeSourcePath
144+
);
145+
res = `file:///${sourcePath.replace(/\\/g, "/")}`;
146+
} else {
147+
relativeSourcePath = relativeSourcePath.substring(12);
148+
res = `https://raw.githubusercontent.com/dotnet/runtime/${gitHash}/${relativeSourcePath}`;
149+
}
150+
locationCache[relativeSourcePath] = res;
151+
}
152+
return res;
153+
}

0 commit comments

Comments
 (0)