5
5
6
6
<h1 >as-loader</h1 >
7
7
<p >AssemblyScript loader for webpack</p >
8
- <p >⚠️ In development ⚠️</p >
9
8
10
9
[ ![ npm version] ( https://img.shields.io/npm/v/as-loader.svg )] ( https://www.npmjs.com/package/as-loader )
11
10
[ ![ build status] ( https://github.com/piotr-oles/as-loader/workflows/CI/CD/badge.svg?branch=main&event=push )] ( https://github.com/piotr-oles/as-loader/actions?query=branch%3Amain+event%3Apush )
@@ -55,15 +54,16 @@ module.exports = {
55
54
56
55
## Usage
57
56
58
- By default, the loader emits ` .wasm ` file (+ ` .wasm.map ` if source maps are enabled) and
57
+ By default, the loader emits a ` .wasm ` file (+ ` .wasm.map ` if source maps are enabled) and
59
58
creates CommonJS module that exports URL to the emitted ` .wasm ` file.
60
59
61
60
If you enable ` fallback ` option, the loader will emit additional ` .js ` file (+ ` .js.map ` if source maps are enabled)
62
61
and will expose async ` fallback() ` function which dynamically imports fallback module.
63
62
64
- To simplify loading logic, you can use ` as-loader/runtime ` loader which uses
65
- ` @assemblyscript/loader ` under the hood.
66
- The loader provides correct types, checks for WebAssembly support, and uses fallback if available.
63
+ To simplify loading logic, you can use ` as-loader/runtime ` loader which uses
64
+ [ @assemblyscript/loader ] ( https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader ) , or
65
+ ` as-loader/runtime/bind ` loader which uses [ as-bind] ( https://github.com/torch2424/as-bind ) .
66
+ These loaders provide correct types, checks for WebAssembly support, and uses fallback if available.
67
67
68
68
``` typescript
69
69
import * as myModule from " ./assembly/myModule" ;
@@ -97,11 +97,13 @@ loadAndRun();
97
97
98
98
```
99
99
100
+ </details >
101
+
100
102
### API
101
103
> For more details, check [ src/runtime] ( src/runtime ) directory
102
104
103
105
#### ` as-loader/runtime `
104
- This runtime loader uses ` @assemblyscript/loader ` under the hood.
106
+ This runtime loader uses [ @assemblyscript/loader ] ( https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader ) under the hood.
105
107
``` typescript
106
108
export interface WasmModuleInstance <TModule > {
107
109
type: " wasm" ;
@@ -123,15 +125,51 @@ export function instantiate<TModule>(
123
125
module : TModule ,
124
126
load : (url : string ) => Promise <unknown >,
125
127
imports ? : object ,
126
- fallback ? : boolean ,
128
+ fallback : boolean = false ,
127
129
supports ? : () => boolean
128
130
): Promise <ModuleInstance <TModule >>
129
131
```
130
132
133
+ <details >
134
+ <summary ><code >as - loader / runtime < / code > binding code example :</summary >
135
+
136
+ ` ` ` typescript
137
+ // ./src/assembly/sayHello.ts
138
+ export function sayHello(firstName: string, lastName: string): string {
139
+ return ` Hello $ {firstName } $ {lastName }! ` ;
140
+ }
141
+
142
+ // ./src/sayHello.ts
143
+ import * as sayHelloModule from "./assembly/sayHello";
144
+ import { instantiate } from "as-loader/runtime";
145
+
146
+ export async function loadModule(): Promise<typeof sayHelloModule> {
147
+ const { exports } = await instantiate(sayHelloModule, fetch);
148
+ const { __pin, __unpin, __newString, __getString } = exports;
149
+
150
+ function sayHello(firstName: string, lastName: string): string {
151
+ const firstNamePtr = __pin(__newString(firstName));
152
+ const lastNamePtr = __pin(__newString(lastName));
153
+ const result = __getString(
154
+ exports.sayHello(firstNamePtr, lastNamePtr)
155
+ );
156
+
157
+ __unpin(firstNamePtr);
158
+ __unpin(lastNamePtr);
159
+
160
+ return result;
161
+ }
162
+
163
+ return { sayHello };
164
+ }
165
+ ` ` `
166
+
167
+ < / details >
168
+
169
+
131
170
#### ` as-loader/runtime/bind `
132
- This runtime loader uses ` as-bind ` under the hood , so you don ' t have to resolve pointers for
133
- types like ` string ` , ` number[] ` , ` Int8Array ` , etc . You still have to resolve pointers to objects .
134
- Requires ` bind: true ` option in the webpack loader configuration .
171
+ This runtime loader uses [as - bind ](https :// github.com/torch2424/as-bind) under the hood.
172
+ Requires ` bind ` option enabled in the webpack loader configuration .
135
173
> Keep in mind that currently [it ' s recommended to manually set `Function.returnType`](https://github.com/torch2424/as-bind#production)
136
174
` ` ` typescript
137
175
export interface BoundWasmModuleInstance<TModule, TImports> {
@@ -162,30 +200,15 @@ export function instantiate<TModule, TImports>(
162
200
module: TModule,
163
201
load: (url: string) => Promise<unknown>,
164
202
imports?: TImports,
165
- fallback? : boolean,
203
+ fallback: boolean = false ,
166
204
supports?: () => boolean
167
205
): Promise<BoundModuleInstance<TModule, TImports>>
168
206
169
207
export const RETURN_TYPES: AsBindReturnTypes;
170
208
` ` `
171
209
172
- < / details >
173
-
174
- ## Binding
175
- There are 2 aspects that you have to consider when interacting with WebAssembly module :
176
- 1. WebAssembly doesn ' t support function arguments and returns others than `number` and `boolean` yet.
177
- Because of that , you have to [manually translate between WebAssembly pointers and JavaScript objects ](https :// www.assemblyscript.org/loader.html#usage).
178
- The alternative solution is to use [` as-bind ` ](https :// github.com/torch2424/as-bind#readme) library which
179
- does this automatically for ` string ` and ` array ` types (doesn ' t support objects yet).
180
- 2. WebAssembly doesn ' t provide GC yet ([proposal](https://github.com/WebAssembly/gc)) - to manage memory,
181
- AssemblyScript offers very lightweight GC implementation . If you use it (see ` runtime ` option - it ' s `"incremental"` by default),
182
- you have to manually ` __pin ` and ` __unpin ` pointers to instruct GC if given data can be collected or not .
183
-
184
- The ` as-loader/runtime ` uses ` @assemblyscript/loader ` under the hood -
185
- [see the docs ](https :// www.assemblyscript.org/loader.html) for more information.
186
-
187
210
<details >
188
- <summary >` as-loader/runtime ` binding code example :</summary >
211
+ <summary >< code > as - loader / runtime / bind < / code > binding code example :</summary >
189
212
190
213
` ` ` typescript
191
214
// ./src/assembly/sayHello.ts
@@ -195,40 +218,66 @@ export function sayHello(firstName: string, lastName: string): string {
195
218
196
219
// ./src/sayHello.ts
197
220
import * as sayHelloModule from "./assembly/sayHello";
198
- import { instantiate } from "as-loader/runtime";
221
+ import { instantiate, RETURN_TYPES } from "as-loader/runtime/bind ";
199
222
200
223
export async function loadModule(): Promise<typeof sayHelloModule> {
201
- // this example doesn't use fallback so TypeScript knows that it's only WASM module
202
- const { exports } = await instantiate(sayHelloModule, fetch, undefined, false);
203
- const { __pin, __unpin, __newString, __getString } = exports;
204
-
205
- function sayHello(firstName: string, lastName: string): string {
206
- const firstNamePtr = __pin(__newString(firstName));
207
- const lastNamePtr = __pin(__newString(lastName));
208
- const result = __getString(
209
- exports.sayHello(firstNamePtr, lastNamePtr)
210
- );
211
-
212
- __unpin(firstNamePtr);
213
- __unpin(lastNamePtr);
214
-
215
- return result;
216
- }
224
+ const { exports } = await instantiate(sayHelloModule, fetch);
225
+ const { sayHello } = exports;
226
+ sayHello.returnType = RETURN_TYPES.STRING;
217
227
218
228
return { sayHello };
219
229
}
220
230
` ` `
221
231
222
232
< / details >
223
233
224
- You can consider using ` bind: true ` option and ` as-loader/runtime/bind ` runtime loader which uses
225
- [` as-bind ` ](https :// github.com/torch2424/as-bind) under the hood - this makes passing types like `string` and `array`
226
- much easier .
234
+ ## Binding
235
+ There are 2 aspects that you have to consider when interacting with a WebAssembly module :
236
+ 1. WebAssembly doesn ' t support function arguments and returns others than `number | boolean | bigint` yet.
237
+ Because of that , you have to [manually translate between WebAssembly pointers and JavaScript objects ](https :// www.assemblyscript.org/loader.html#usage).
238
+
239
+ The alternative is to enable the ` bind ` option and use ` as-loader/runtime/bind ` loader which uses an [as - bind ](https :// github.com/torch2424/as-bind) library.
240
+ This simplifies passing types like strings and arrays .
241
+
242
+ 2. WebAssembly doesn ' t provide Garbage Collector yet ([proposal](https://github.com/WebAssembly/gc)) - to manage memory,
243
+ AssemblyScript offers very lightweight GC implementation . If you use it (see ` runtime ` option ),
244
+ you have to [manually ` __pin ` and ` __unpin ` pointers ](https :// www.assemblyscript.org/garbage-collection.html#incremental-runtime)
245
+ to instruct GC if given data can be collected or not .
246
+
247
+ ## Fallback
248
+ If you need to support [older browsers ](https :// caniuse.com/wasm) like *Internet Explorer* or *Edge* < 16,
249
+ you can use the ` fallback ` option . A fallback module is different from WebAssembly one because you don ' t have to bind it.
227
250
228
251
229
252
<details >
230
- <summary >` as-loader/runtime/bind ` binding code example :</summary >
253
+ <summary >Fallback example :</summary >
231
254
255
+ ` ` ` js
256
+ // webpack.config.js
257
+ module.exports = {
258
+ entry: "src/index.ts",
259
+ resolve: {
260
+ extensions: [".ts", ".js"],
261
+ },
262
+ module: {
263
+ rules: [
264
+ {
265
+ test: /\. ts$/,
266
+ include: path.resolve(__dirname, "src/assembly"),
267
+ loader: "as-loader",
268
+ options: {
269
+ fallback: true
270
+ }
271
+ },
272
+ {
273
+ test: /\. ts$/,
274
+ exclude: path.resolve(__dirname, "src/assembly"),
275
+ loader: "ts-loader",
276
+ },
277
+ ],
278
+ },
279
+ };
280
+ ` ` `
232
281
` ` ` typescript
233
282
// ./src/assembly/sayHello.ts
234
283
export function sayHello(firstName: string, lastName: string): string {
@@ -237,15 +286,32 @@ export function sayHello(firstName: string, lastName: string): string {
237
286
238
287
// ./src/sayHello.ts
239
288
import * as sayHelloModule from "./assembly/sayHello";
240
- import { instantiate, RETURN_TYPES } from "as-loader/runtime/bind ";
289
+ import { instantiate } from "as-loader/runtime";
241
290
242
291
export async function loadModule(): Promise<typeof sayHelloModule> {
243
- // this example doesn't use fallback so TypeScript knows that it's only WASM module
244
- const { exports } = await instantiate(sayHelloModule, fetch, undefined, false);
245
- const { sayHello } = exports;
246
- sayHello.returnType = RETURN_TYPES.STRING;
247
-
248
- return { sayHello };
292
+ // set fallback option to true (opt-in)
293
+ const module = await instantiate(sayHelloModule, fetch, undefined, true);
294
+
295
+ if (module.type === 'wasm') {
296
+ const { __pin, __unpin, __newString, __getString } = exports;
297
+
298
+ function sayHello(firstName: string, lastName: string): string {
299
+ const firstNamePtr = __pin(__newString(firstName));
300
+ const lastNamePtr = __pin(__newString(lastName));
301
+ const result = __getString(
302
+ exports.sayHello(firstNamePtr, lastNamePtr)
303
+ );
304
+
305
+ __unpin(firstNamePtr);
306
+ __unpin(lastNamePtr);
307
+
308
+ return result;
309
+ }
310
+
311
+ return { sayHello };
312
+ } else {
313
+ return { sayHello: module.exports.sayHello }
314
+ }
249
315
}
250
316
` ` `
251
317
@@ -257,9 +323,9 @@ export async function loadModule(): Promise<typeof sayHelloModule> {
257
323
| Name | Type | Description |
258
324
| ------------ | -------- - | ---------- - |
259
325
| ` name ` | string | Output asset name template , ` [name].[contenthash].wasm ` by default . |
260
- | ` raw ` | boolean | If true , returns binary instead of emitting file . Use for chaining with other loaders . |
326
+ | ` bind ` | boolean | If true , adds [ as - bind ]( https : // github.com/torch2424/as-bind) library files to the compilation (required if you want to use `as-loader/runtime/bind`) . |
261
327
| ` fallback ` | boolean | If true , creates additional JavaScript file which can be used if WebAssembly is not supported . |
262
- | ` bind ` | boolean | If true , adds ` as-bind ` library files to the compilation ( required if you want to use ` as-loader/runtime/bind ` ) . |
328
+ | ` raw ` | boolean | If true , returns binary instead of emitting file . Use for chaining with other loaders . |
263
329
264
330
#### Compiler Options
265
331
@@ -279,7 +345,7 @@ Options passed to the [AssemblyScript compiler](https://www.assemblyscript.org/c
279
345
| ` sharedMemory ` | boolean | Declare memory as shared . Requires maximumMemory . |
280
346
| ` importTable ` | boolean | Imports the function table provided as 'env.table'. |
281
347
| `exportTable` | boolean | Exports the function table as 'table'. |
282
- | `runtime` | string | Specifies the runtime variant to include in the program. Available runtimes are: "incremental" (default ), "minimal", "stub" |
348
+ | `runtime` | string | Specifies the runtime variant to include in the program. Available runtime are: "incremental" (default ), "minimal", "stub" |
283
349
| `exportRuntime` | boolean | Exports the runtime helpers (__new , __collect etc.). Enabled by default. |
284
350
| `explicitStart` | boolean | Exports an explicit '_start' function to call. |
285
351
| `enable` | string[] | Enables WebAssembly features being disabled by default. Available features are: "sign-extension", "bulk-memory", "simd", "threads", "reference-types", "gc" |
0 commit comments