emscripten-core / emscripten-core/emscripten

Allow esm in JS libraries?

Open
#22,997 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Ref:
- https://github.com/toyobayashi/emnapi/blob/3cb78fbc014e545409b72ef05dc71bd7dbe1c2ee/packages/ts-transform-emscripten-esm-library/README.md
- https://github.com/toyobayashi/emnapi/tree/3cb78fbc014e545409b72ef05dc71bd7dbe1c2ee/packages/rollup-plugin-emscripten-esm-library

With this TypeScript custom transformer and rollup plugin, the JS library can be written in ES Module:

inputoutput

```js
export function x () {
return 42
}
```

```js
function _x() {
return 42
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
x: _x
})
```

```js
export function $x () {
return 42
}
```

```js
function x() {
return 42
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
$x: x
})
```

```js
export const x = getX()

function getX() {
return 42
}
```

```js
const _x = getX()
function getX() {
return 42;
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
$getX: getX,
x: "getX()",
x__deps: ["$getX"]
});
```

```js
const localVar = 10

function f () {
console.log(localVar)
}

function localFunc() {
f()
console.log(localVar)
}

export {
localVar as exportedVar,
localFunc as exportedFunc
}
```

```js
const _exportedVar = 10
function f() {
console.log(_exportedVar)
}
function _exportedFunc() {
f()
console.log(_exportedVar)
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
exportedVar: "10",
$f: f,
$f__deps: ["exportedVar"],
exportedFunc: _exportedFunc,
exportedFunc__deps: ["$f", "exportedVar"]
})
```

```js
/** @__deps $external */
export function x() {}

/**
* @__deps emscripten_resize_heap
* @__deps $runtimeKeepalivePush
* @__deps $runtimeKeepalivePop
* @__sig v
* @__postset
* ```
* console.log(42);
* console.log(_y);
* ```
*
* @returns {void}
*/
export function y() {
runtimeKeepalivePush()
runtimeKeepalivePop()
_emscripten_resize_heap()
return x()
}
```

```js
/** @__deps $external */
function _x() { }
/**
* @__deps emscripten_resize_heap
* @__deps $runtimeKeepalivePush
* @__deps $runtimeKeepalivePop
* @__sig v
* @__postset
* ```
* console.log(42);
* console.log(_y);
* ```
*
* @returns {void}
*/
function _y() {
runtimeKeepalivePush()
runtimeKeepalivePop()
_emscripten_resize_heap()
return _x()
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
x: _x,
x__deps: ["$external"],
y: _y,
y__deps: [
"x",
"emscripten_resize_heap",
"$runtimeKeepalivePush",
"$runtimeKeepalivePop"
],
y__sig: "v",
y__postset: "console.log(42);\nconsole.log(_y);"
})
```

```js
export function getPointerSize () {
let result
// #if MEMORY64
result = 8
// #else
result = 4
// #endif
return result
}
```

```js
function _getPointerSize() {
let result
#if MEMORY64
result = 8
#else
result = 4
#endif
return result
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
getPointerSize: _getPointerSize
})
```

```js
import {
from64,
makeSetValue,
SIZE_TYPE,
POINTER_SIZE
} from 'emscripten:parse-tools'
import {
wasmMemory,
HEAPU8
} from 'emscripten:runtime'

export function getPointerSize (ret) {
from64('ret')
makeSetValue('ret', 0, POINTER_SIZE, SIZE_TYPE)
console.log(HEAPU8.buffer === wasmMemory.buffer)
return POINTER_SIZE
}
```

```js
function _getPointerSize(ret) {
{{{ from64('ret') }}}
{{{ makeSetValue('ret', 0, POINTER_SIZE, SIZE_TYPE) }}}
console.log(HEAPU8.buffer === wasmMemory.buffer)
return {{{ POINTER_SIZE }}}
}
(typeof addToLibrary === "function"
? addToLibrary :
(...args) => mergeInto(
LibraryManager.library, ...args)
)({
getPointerSize: _getPointerSize
});
```

Does emscripten can officially support things like this?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.