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

docs: add kcl wasm lib browser target user guide documents #467

Merged
merged 1 commit into from
Sep 10, 2024
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
128 changes: 127 additions & 1 deletion docs/reference/xlang-api/wasm-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,132 @@ sidebar_position: 12

# WASM API

The KCL core is written by Rust and can be compiled to the `wasm-wasi` target using toolchains such as cargo. With the help of WASM, we can also easily achieve multilingual and browser integration. Here is how we can use the KCL WASM module in Node.js, Go and Rust.
The KCL core is written by Rust and can be compiled to the `wasm-wasi` target using toolchains such as cargo. With the help of WASM, we can also easily achieve multilingual and browser integration. Here is how we can use the KCL WASM module in Browser, Node.js, Go and Rust.

## Quick Start

We can find and download KCL WASM module from [here](https://github.com/kcl-lang/lib/tree/main/wasm)

## Browser

Install the dependency

```shell
npm install buffer @wasmer/wasi @kcl-lang/wasm-lib
```

> Note: buffer is required by @wasmer/wasi.

Write the code

```typescript
import { load, invokeKCLRun } from "@kcl-lang/wasm-lib";

async function main() {
const inst = await load();
const result = invokeKCLRun(inst, {
filename: "test.k",
source: `
schema Person:
name: str

p = Person {name = "Alice"}`,
});
console.log(result);
}

main();
```

Here, we use `webpack` to bundle the website, the `webpack.config.js` config as follows.

> Note: This configuration includes necessary settings for @wasmer/wasi and other required plugins.

```js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const webpack = require("webpack");

const dist = path.resolve("./dist");
const isProduction = process.argv.some((x) => x === "--mode=production");
const hash = isProduction ? ".[contenthash]" : "";

module.exports = {
mode: "development",
entry: {
main: "./src/main.ts",
},
target: "web",
output: {
path: dist,
filename: `[name]${hash}.js`,
clean: true,
},
devServer: {
hot: true,
port: 9000,
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.m?js$/,
resourceQuery: { not: [/(raw|wasm)/] },
},
{
resourceQuery: /raw/,
type: "asset/source",
},
{
resourceQuery: /wasm/,
type: "asset/resource",
generator: {
filename: "wasm/[name][ext]",
},
},
],
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./src/index.html"),
}),
new webpack.IgnorePlugin({
resourceRegExp: /^(path|ws|crypto|fs|os|util|node-fetch)$/,
}),
// needed by @wasmer/wasi
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
}),
],
externals: {
// needed by @wasmer/wasi
"wasmer_wasi_js_bg.wasm": true,
},
resolve: {
fallback: {
// needed by @wasmer/wasi
buffer: require.resolve("buffer/"),
},
},
};
```

For a complete working example, refer to [here](https://github.com/kcl-lang/lib/tree/main/wasm/examples/browser).

### Troubleshooting

If you encounter any issues, make sure:

- All dependencies are correctly installed.
- Your `webpack.config.js` is properly set up.
- You're using a modern browser that supports WebAssembly.
- The KCL WASM module is correctly loaded and accessible.

## Node.js

Install the dependency
Expand Down Expand Up @@ -46,6 +166,8 @@ p:
name: Alice
```

The code example can be found [here](https://github.com/kcl-lang/lib/tree/main/wasm/examples/node).

## Rust

In Rust, we use `wasmtime` as an example, and of course, you can also use other runtime that supports WASI to accomplish this.
Expand Down Expand Up @@ -82,6 +204,8 @@ The output is
a: 1
```

The code example can be found [here](https://github.com/kcl-lang/lib/tree/main/wasm/examples/rust).

## Go

In Go, we use `wasmtime` as an example, and of course, you can also use other runtime that supports WASI to accomplish this.
Expand Down Expand Up @@ -118,3 +242,5 @@ The output is
```yaml
a: 1
```

The code example can be found [here](https://github.com/kcl-lang/lib/tree/main/wasm/examples/go).
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,131 @@ sidebar_position: 12

# WASM API

KCL 核心用 Rust 编写,可以使用 cargo 等工具链编译到 `wasm-wasi` 目标。在 WASM 的帮助下,也可以轻松实现多语言和浏览器集成。以下是在 Node.js 环境, Go 和 Rust 中使用 KCL WASM 模块的方法。
KCL 核心用 Rust 编写,可以使用 cargo 等工具链编译到 `wasm-wasi` 目标。在 WASM 的帮助下,也可以轻松实现多语言和浏览器集成。以下是在浏览器, Node.js 环境, Go 和 Rust 中使用 KCL WASM 模块的方法。

## 快速开始

可以从[这里](https://github.com/kcl-lang/lib/tree/main/wasm)找到 KCL WASM 模块。

## 浏览器环境

安装依赖

```shell
npm install buffer @wasmer/wasi @kcl-lang/wasm-lib
```

> 注意:buffer 是 @wasmer/wasi 所需的依赖。

编写代码

```ts
import { load, invokeKCLRun } from "@kcl-lang/wasm-lib";

async function main() {
const inst = await load();
const result = invokeKCLRun(inst, {
filename: "test.k",
source: `
schema Person:
name: str
p = Person {name = "Alice"}`,
});
console.log(result);
}

main();
```

在这里,我们使用 `webpack` 来打包网站, `webpack.config.js` 的配置如下。

> 注意:此配置包含了 @wasmer/wasi 所需的必要设置和其他必需的插件。

```js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const webpack = require("webpack");

const dist = path.resolve("./dist");
const isProduction = process.argv.some((x) => x === "--mode=production");
const hash = isProduction ? ".[contenthash]" : "";

module.exports = {
mode: "development",
entry: {
main: "./src/main.ts",
},
target: "web",
output: {
path: dist,
filename: `[name]${hash}.js`,
clean: true,
},
devServer: {
hot: true,
port: 9000,
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.m?js$/,
resourceQuery: { not: [/(raw|wasm)/] },
},
{
resourceQuery: /raw/,
type: "asset/source",
},
{
resourceQuery: /wasm/,
type: "asset/resource",
generator: {
filename: "wasm/[name][ext]",
},
},
],
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./src/index.html"),
}),
new webpack.IgnorePlugin({
resourceRegExp: /^(path|ws|crypto|fs|os|util|node-fetch)$/,
}),
// needed by @wasmer/wasi
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
}),
],
externals: {
// needed by @wasmer/wasi
"wasmer_wasi_js_bg.wasm": true,
},
resolve: {
fallback: {
// needed by @wasmer/wasi
buffer: require.resolve("buffer/"),
},
},
};
```

完整的代码示例可以在[这里](https://github.com/kcl-lang/lib/tree/main/wasm/examples/browser)找到。

## 错误排查

如果遇到任何问题,请确保:

- 所有依赖都正确安装。
- webpack.config.js 配置正确。
- 使用的是支持 WebAssembly 的现代浏览器。
- KCL WASM 模块正确加载并可访问。

## Node.js

安装依赖:
Expand Down Expand Up @@ -46,6 +165,8 @@ p:
name: Alice
```

完整的代码示例可以在[这里](https://github.com/kcl-lang/lib/tree/main/wasm/examples/node)找到。

## Rust

在 Rust 中,我们以 `wasmtime` 为例,当然你也可以使用其他支持 WASI 的运行时来完成这一任务。
Expand Down Expand Up @@ -82,6 +203,8 @@ fn main() -> Result<()> {
a: 1
```

完整的代码示例可以在[这里](https://github.com/kcl-lang/lib/tree/main/wasm/examples/rust)找到。

## Go

在 Go 中,我们以 `wasmtime` 为例,当然你也可以使用其他支持 WASI 的运行时来完成这一任务。
Expand Down Expand Up @@ -118,3 +241,5 @@ func main() {
```yaml
a: 1
```

完整的代码示例可以在[这里](https://github.com/kcl-lang/lib/tree/main/wasm/examples/go)找到。
Loading
Loading