How to Overcome Three WASM Integration Hurdles in WeChat Mini Programs

This article walks through the step‑by‑step process of integrating the @jsquash/jpeg WebAssembly JPEG codec into a WeChat mini program, detailing three major challenges—module import, import.meta usage, and WebAssembly initialization—and the practical fixes that enable local image compression.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
How to Overcome Three WASM Integration Hurdles in WeChat Mini Programs

Preface

This is another story of being tormented by mini programs. After a previous experience with a WeChat avatar‑flag mini program, I attempted a second mini program that required integrating a third‑party npm package @jsquash/jpeg, a WebAssembly‑based JPEG encoder/decoder that runs in the browser.

Business & Background

The mini program I built is an image‑compression tool called Image Compression Darkroom. It can compress images, reduce dimensions, and convert formats, and all functionality must run locally because I have no server budget.

First Challenge: Importing @jsquash/jpeg

Install the package: npm install @jsquash/jpeg After building the npm package in the mini program there is no problem, but importing the module with the example code triggers a “module not defined” error, indicating that the WeChat build process failed to compile certain files.

Comparing node_modules and miniprogram_npm reveals that encode.js and decode.js were not compiled and therefore are missing in miniprogram_npm:

The compiled index.js contains a comment marking these files as external dependencies, so they are excluded from compilation.

//miniprogram-npm-outsideDeps=["./codec/enc/mozjpeg_enc.js","./codec/dec/mozjpeg_dec.js"]
//# sourceMappingURL=index.js.map

To fix this, manually copy the codec directory from the source into miniprogram_npm:

cp -r node_modules/@jsquash/jpeg/codec miniprogram_npm/@jsquash/jpeg/
Note: You will need to either manually include the wasm files from the codec directory or use a bundler like WebPack or Rollup to include them in your app/server.

Second Challenge: Disabling import.meta

After clearing the mini‑program cache and rebuilding, a new error appears: import.meta cannot be used outside a module. The offending code resides in miniprogram_npm/@jsquash/jpeg/codec/enc/mozjpeg_enc.js.

Replace every occurrence of import.meta.url with the actual script path and comment out unused lines:

// var _scriptDir = import.meta.url;
var _scriptDir = '/miniprogram_npm/@jsquash/jpeg/codec/enc/mozjpeg_enc.js';

Also adjust the wasm file reference to point to a wasm folder at the project root because the mini program cannot access files inside miniprogram_npm:

// wasmBinaryFile = new URL("mozjpeg_enc.wasm", import.meta.url).href
wasmBinaryFile = "/wasm/mozjpeg_enc.wasm";

Third Challenge: WebAssembly Not Defined

Initializing @jsquash/jpeg now fails with a “WebAssembly is not defined” error. The root cause is that WeChat provides its own WXWebAssembly implementation, which replaces the standard WebAssembly object.

Modify the initEmscriptenModule function to use WXWebAssembly.instantiate instead of the native constructor:

export function initEmscriptenModule(moduleFactory, wasmModule, moduleOptionOverrides = {}) {
  let instantiateWasm;
  if (wasmModule) {
    instantiateWasm = async (imports, callback) => {
      const result = await WXWebAssembly.instantiate(wasmModule, imports);
      const instance = result.instance;
      callback(instance);
      return instance.exports;
    };
  }
  return moduleFactory({
    noInitialRun: true,
    instantiateWasm,
    ...moduleOptionOverrides,
  });
}

Replace all remaining references to the native WebAssembly object with the WeChat version:

var WebAssembly = WXWebAssembly;
var _scriptDir = '/miniprogram_npm/@jsquash/jpeg/codec/enc/mozjpeg_enc.js';

Finally, pass the correct wasm path when calling the encoder:

initJpegEncode('/wasm/mozjpeg_enc.wasm');

Afterwards

After overcoming the three hurdles, @jsquash/jpeg works, but its compression speed is very low (tens of seconds per image). I switched to using Canvas for JPEG processing and kept separate wasm scripts for GIF and PNG handling.

Future Work

Next article: “Is there really no case online? Integrating gifsicle wasm into a mini program”.

Mini Program Demo

Below is a screenshot of the final “Image Compression Darkroom” mini program.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

WebAssemblyWeChat mini-programJPEG CompressionWASM Integration
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.