{"id":16812021,"url":"https://github.com/piotr-oles/as-loader","last_synced_at":"2025-08-09T10:05:12.486Z","repository":{"id":42072230,"uuid":"330239855","full_name":"piotr-oles/as-loader","owner":"piotr-oles","description":"AssemblyScript loader for webpack","archived":false,"fork":false,"pushed_at":"2024-12-30T07:22:31.000Z","size":284,"stargazers_count":19,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-01T12:06:11.648Z","etag":null,"topics":["assemblyscript","loader","wasm","webassembly","webpack"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piotr-oles.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-16T19:26:15.000Z","updated_at":"2024-12-30T07:22:35.000Z","dependencies_parsed_at":"2023-01-20T02:32:27.192Z","dependency_job_id":null,"html_url":"https://github.com/piotr-oles/as-loader","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotr-oles%2Fas-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotr-oles%2Fas-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotr-oles%2Fas-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotr-oles%2Fas-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piotr-oles","download_url":"https://codeload.github.com/piotr-oles/as-loader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243902291,"owners_count":20366259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assemblyscript","loader","wasm","webassembly","webpack"],"created_at":"2024-10-13T10:20:25.496Z","updated_at":"2025-03-22T03:31:07.039Z","avatar_url":"https://github.com/piotr-oles.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg width=\"100\" height=\"100\" src=\"media/assemblyscript-logo.svg\" alt=\"AssemblyScript logo\"\u003e\n\u003cimg width=\"100\" height=\"100\" src=\"media/webpack-logo.svg\" alt=\"webpack logo\"\u003e\n\n\u003ch1\u003eas-loader\u003c/h1\u003e\n\u003cp\u003eAssemblyScript loader for webpack\u003c/p\u003e\n\n[![npm version](https://img.shields.io/npm/v/as-loader.svg)](https://www.npmjs.com/package/as-loader)\n[![build status](https://github.com/piotr-oles/as-loader/workflows/CI/CD/badge.svg?branch=main\u0026event=push)](https://github.com/piotr-oles/as-loader/actions?query=branch%3Amain+event%3Apush)\n\n\u003c/div\u003e\n\n## Installation\n\nThis loader requires [AssemblyScript ~0.18](https://github.com/AssemblyScript/assemblyscript), \nNode.js \u003e= 12 and [webpack 5](https://github.com/webpack/webpack)\n\n```sh\n# with npm\nnpm install as-loader\nnpm install --save-dev assemblyscript\n\n# with yarn\nyarn add as-loader\nyarn add --dev assemblyscript\n```\n\nThe minimal `webpack.config.js`:\n\n```js\nmodule.exports = {\n  entry: \"src/index.ts\",\n  resolve: {\n    extensions: [\".ts\", \".js\"],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.ts$/,\n        include: path.resolve(__dirname, \"src/assembly\"),\n        loader: \"as-loader\",\n        options: {\n          // optional loader and compiler options\n        }\n      },\n      {\n        test: /\\.ts$/,\n        exclude: path.resolve(__dirname, \"src/assembly\"),\n        loader: \"ts-loader\",\n      },\n    ],\n  },\n};\n```\n\n## Example repository\n\nhttps://stackblitz.com/edit/webpack-webpack-js-org-zl6ung?file=webpack.config.js\n\n## Usage\n\nBy default, the loader emits a `.wasm` file (+ `.wasm.map` if source maps are enabled) and \ncreates CommonJS module that exports URL to the emitted `.wasm` file.\n\nIf you enable `fallback` option, the loader will emit additional `.js` file (+ `.js.map` if source maps are enabled)\nand will expose async `fallback()` function which dynamically imports fallback module.\n\nTo simplify loading logic, you can use `as-loader/runtime` loader which uses \n[@assemblyscript/loader](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader), or\n`as-loader/runtime/bind` loader which uses [as-bind](https://github.com/torch2424/as-bind).\nThese loaders provide correct types, checks for WebAssembly support, and uses fallback if available.\n\n```typescript\nimport * as myModule from \"./assembly/myModule\";\nimport { instantiate } from \"as-loader/runtime\";\n\nasync function loadAndRun() {\n  const { exports } = await instantiate(myModule);\n\n  exports.myFunction(100);\n}\n\nloadAndRun();\n```\n\u003cdetails\u003e\n\u003csummary\u003eAlternatively, you can use exported URL directly:\u003c/summary\u003e\n\n```typescript\nimport * as myModule from \"./assembly/myModule\";\nimport { instantiate } from \"@assemblyscript/loader\";\n\nasync function loadAndRun() {\n  const { exports } = await instantiate\u003ctypeof myModule\u003e(\n    // workaround for TypeScript\n    fetch((myModule as unknown) as string)\n  );\n\n  exports.myFunction(100);\n}\n\nloadAndRun();\n\n```\n\n\u003c/details\u003e\n\n### API\n\u003e For more details, check [src/runtime](src/runtime) directory\n\n#### `as-loader/runtime`\nThis runtime loader uses [@assemblyscript/loader](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader) under the hood.\n```typescript\nexport interface WasmModuleInstance\u003cTModule\u003e {\n  type: \"wasm\";\n  exports: AsLoaderRuntime \u0026 PointerCastObject\u003cTModule\u003e;\n  module: WebAssembly.Module;\n  instance: WebAssembly.Instance;\n}\n\nexport interface JsModuleInstance\u003cTModule\u003e {\n  type: \"js\";\n  exports: TModule;\n}\n\nexport type ModuleInstance\u003cTModule\u003e =\n  | WasmModuleInstance\u003cTModule\u003e\n  | JsModuleInstance\u003cTModule\u003e;\n\nexport function instantiate\u003cTModule\u003e(\n  module: TModule,\n  load: (url: string) =\u003e Promise\u003cunknown\u003e,\n  imports?: object,\n  fallback: boolean = false,\n  supports?: () =\u003e boolean\n): Promise\u003cModuleInstance\u003cTModule\u003e\u003e\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eas-loader/runtime\u003c/code\u003e binding code example:\u003c/summary\u003e\n\n```typescript\n// ./src/assembly/sayHello.ts\nexport function sayHello(firstName: string, lastName: string): string {\n  return `Hello ${firstName} ${lastName}!`;\n}\n\n// ./src/sayHello.ts\nimport * as sayHelloModule from \"./assembly/sayHello\";\nimport { instantiate } from \"as-loader/runtime\";\n\nexport async function loadModule(): Promise\u003ctypeof sayHelloModule\u003e {\n  const { exports } = await instantiate(sayHelloModule, fetch);\n  const { __pin, __unpin, __newString, __getString } = exports;\n\n  function sayHello(firstName: string, lastName: string): string {\n    const firstNamePtr = __pin(__newString(firstName));\n    const lastNamePtr = __pin(__newString(lastName));\n    const result = __getString(\n      exports.sayHello(firstNamePtr, lastNamePtr)\n    );\n\n    __unpin(firstNamePtr);\n    __unpin(lastNamePtr);\n\n    return result;\n  }\n\n  return { sayHello };\n}\n```\n\n\u003c/details\u003e\n\n\n#### `as-loader/runtime/bind`\nThis runtime loader uses [as-bind](https://github.com/torch2424/as-bind) under the hood. \nRequires `bind` option enabled in the webpack loader configuration.\n\u003e Keep in mind that currently [it's recommended to manually set `Function.returnType`](https://github.com/torch2424/as-bind#production)\n```typescript\nexport interface BoundWasmModuleInstance\u003cTModule, TImports\u003e {\n  type: \"wasm-bound\";\n  exports: AsLoaderRuntime \u0026 BoundExports\u003cTModule\u003e;\n  unboundExports: AsLoaderRuntime \u0026 PointerCastObject\u003cTModule\u003e;\n  importObject: TImports;\n  module: WebAssembly.Module;\n  instance: WebAssembly.Instance;\n}\n\nexport interface JsModuleInstance\u003cTModule\u003e {\n  type: \"js\";\n  exports: TModule;\n}\n\ntype BoundModuleInstance\u003cTModule, TImports\u003e =\n  | BoundWasmModuleInstance\u003cTModule, TImports\u003e\n  | JsModuleInstance\u003cTModule\u003e;\n\nexport function instantiate\u003cTModule, TImports\u003e(\n  module: TModule,\n  load: (url: string) =\u003e Promise\u003cunknown\u003e,\n  imports?: TImports,\n  fallback: boolean = false,\n  supports?: () =\u003e boolean\n): Promise\u003cBoundModuleInstance\u003cTModule, TImports\u003e\u003e\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eas-loader/runtime/bind\u003c/code\u003e binding code example:\u003c/summary\u003e\n\n```typescript\n// ./src/assembly/sayHello.ts\nexport function sayHello(firstName: string, lastName: string): string {\n  return `Hello ${firstName} ${lastName}!`;\n}\n\n// ./src/sayHello.ts\nimport * as sayHelloModule from \"./assembly/sayHello\";\nimport { instantiate } from \"as-loader/runtime/bind\";\n\nexport async function loadModule(): Promise\u003ctypeof sayHelloModule\u003e {\n  const module = await instantiate(sayHelloModule, fetch);\n\n  return { sayHello: module.exports.sayHello };\n}\n```\n\n\u003c/details\u003e\n\n## Binding\nThere are 2 aspects that you have to consider when interacting with a WebAssembly module:\n  1. WebAssembly doesn't support function arguments and returns others than `number | boolean | bigint` yet.\n     Because of that, you have to [manually translate between WebAssembly pointers and JavaScript objects](https://www.assemblyscript.org/loader.html#usage).\n     \n     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. \n     This simplifies passing types like strings and arrays. \n       \n  2. WebAssembly doesn't provide Garbage Collector yet ([proposal](https://github.com/WebAssembly/gc)) - to manage memory, \n     AssemblyScript offers very lightweight GC implementation. If you use it (see `runtime` option), \n     you have to [manually `__pin` and `__unpin` pointers](https://www.assemblyscript.org/garbage-collection.html#incremental-runtime)\n     to instruct GC if given data can be collected or not.\n   \n## Fallback\nIf you need to support [older browsers](https://caniuse.com/wasm) like *Internet Explorer* or *Edge* \u003c 16, \nyou can use the `fallback` option. A fallback module is different from WebAssembly one because you don't have to bind it.\n\n\n\u003cdetails\u003e\n\u003csummary\u003eFallback example:\u003c/summary\u003e\n\n```js\n// webpack.config.js\nmodule.exports = {\n  entry: \"src/index.ts\",\n  resolve: {\n    extensions: [\".ts\", \".js\"],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.ts$/,\n        include: path.resolve(__dirname, \"src/assembly\"),\n        use: [\n          // fallback loader (must be before as-loader)\n          {\n            loader: \"ts-loader\",\n            options: {\n              transpileOnly: true\n            }   \n          },   \n          // as-loader, apart from building .wasm file,\n          // will forward assembly script files to the fallback loader above\n          // to build a .js file\n          {\n            loader: \"as-loader\",\n            options: {\n              fallback: true\n           }\n          }\n        ]\n      },\n      {\n        test: /\\.ts$/,\n        exclude: path.resolve(__dirname, \"src/assembly\"),\n        loader: \"ts-loader\",\n      },\n    ],\n  },\n};\n```\n```typescript\n// ./src/assembly/sayHello.ts\nexport function sayHello(firstName: string, lastName: string): string {\n  return `Hello ${firstName} ${lastName}!`;\n}\n\n// ./src/sayHello.ts\nimport * as sayHelloModule from \"./assembly/sayHello\";\nimport { instantiate } from \"as-loader/runtime\";\n\nexport async function loadModule(): Promise\u003ctypeof sayHelloModule\u003e {\n  // set fallback option to true (opt-in)\n  const module = await instantiate(sayHelloModule, fetch, undefined, true);\n\n  if (module.type === 'wasm') {\n    const { __pin, __unpin, __newString, __getString } = exports;\n  \n    function sayHello(firstName: string, lastName: string): string {\n      const firstNamePtr = __pin(__newString(firstName));\n      const lastNamePtr = __pin(__newString(lastName));\n      const result = __getString(\n        exports.sayHello(firstNamePtr, lastNamePtr)\n      );\n  \n      __unpin(firstNamePtr);\n      __unpin(lastNamePtr);\n  \n      return result;\n    }\n  \n    return { sayHello };\n  } else {\n    return { sayHello: module.exports.sayHello }\n  }\n}\n```\n\n\u003c/details\u003e\n   \n## Options\n#### Loader Options\n\n| Name       | Type    | Description |\n|------------|---------| ----------- |\n| `name`     | string  | Output asset name template, `[name].[contenthash].wasm` by default. |\n| `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`). |\n| `fallback` | boolean | If true, creates additional JavaScript file which can be used if WebAssembly is not supported. |\n| `raw`      | boolean | If true, returns binary instead of emitting file. Use for chaining with other loaders. |\n\n#### Compiler Options\n\nOptions passed to the [AssemblyScript compiler](https://www.assemblyscript.org/compiler.html#command-line-options).\n\n| Name             | Type     | Description |\n|------------------|----------| ----------- |\n| `debug`          | boolean  | Enables debug information in emitted binaries, enabled by default in webpack development mode. |\n| `optimizeLevel`  | number   | How much to focus on optimizing code, 3 by default. [0-3] |\n| `shrinkLevel`    | number   | How much to focus on shrinking code size, 1 by default. [0-2] |\n| `coverage`       | boolean  | Re-optimizes until no further improvements can be made. |\n| `noAssert`       | boolean  | Replaces assertions with just their value without trapping, enabled by default in webpack production mode. |\n| `importMemory`   | boolean  | Imports the memory provided as 'env.memory'. |\n| `noExportMemory` | boolean  | Does not export the memory as 'memory'. |\n| `initialMemory`  | number   | Sets the initial memory size in pages. |\n| `maximumMemory`  | number   | Sets the maximum memory size in pages. |\n| `sharedMemory`   | boolean  | Declare memory as shared. Requires maximumMemory. |\n| `importTable`    | boolean  | Imports the function table provided as 'env.table'. |\n| `exportTable`    | boolean  | Exports the function table as 'table'. |\n| `runtime`        | string   | Specifies the runtime variant to include in the program. Available runtime are: \"incremental\" (default), \"minimal\", \"stub\" |\n| `exportRuntime`  | boolean  | Exports the runtime helpers (__new, __collect etc.). Enabled by default. |\n| `explicitStart`  | boolean  | Exports an explicit '_start' function to call. |\n| `enable`         | string[] | Enables WebAssembly features being disabled by default. Available features are: \"sign-extension\", \"bulk-memory\", \"simd\", \"threads\", \"reference-types\", \"gc\" |\n| `disable`        | string[] | Disables WebAssembly features being enabled by default. Available features are: \"mutable-globals\" |\n| `lowMemoryLimit` | boolean  | Enforces very low (\u003c64k) memory constraints. |\n| `memoryBase`     | number   | Sets the start offset of emitted memory segments. |\n| `tableBase`      | number   | Sets the start offset of emitted table elements. |\n| `trapMode`       | string   | Sets the trap mode to use. Available modes are: \"allow\", \"clamp\", \"js\" |\n| `noValidate`     | boolean  | Skips validating the module using Binaryen. |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotr-oles%2Fas-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiotr-oles%2Fas-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotr-oles%2Fas-loader/lists"}