3 votes

Échec du chargement de l'application wasm

Je suis en train d'essayer d'héberger un site web et j'utilise un fichier .wasm avec des scripts .js créés par l'outil wasm-pack.

J'ai testé le projet en local avec npm et node.js et tout fonctionnait bien.

Mais lorsque je l'ai hébergé sur un raspberry (apache2), j'ai obtenu l'erreur suivante :

Failed to load module script: The server responded with a non-JavaScript MIME type of "application/wasm". Strict MIME type checking is enforced for module scripts per HTML spec.

détails

Il y a plusieurs fichiers, mais voici l'idée :

Mon index.html charge le module bootstrap.js

// contenu de bootstrap.js
import("./index.js").catch(e => console.error("Erreur lors de l'import de `index.js` :", e));

Mon code principal se trouve dans index.js, qui appelle test_wasm_bg.js

Et enfin, test_wasm_bg.js charge le fichier wasm avec cette ligne :

// première ligne de test_wasm_bg.js
import * as wasm from './test_wasm_bg.wasm';

Où est le problème ?

Quelle est la bonne manière de charger un fichier assembly web ?

6voto

rambi Points 548

J'ai enfin trouvé quelle est la bonne façon de charger une application wasm dans un projet wasm-bindgen !

En fait, tout était sur cette page

Lorsque vous compilez le projet sans vouloir l'exécuter avec un bundler, vous devez exécuter wasm-pack build avec un drapeau --target.

wasm-pack build --release --target web.

Cela crée un fichier .js (pkg/test_wasm.js dans mon exemple) avec tout ce dont vous avez besoin pour charger l'application wasm.

Et voici comment vous utilisez les fonctions créées par wasm-bindgen (index.js):

import init from './pkg/test_wasm.js';
import {ex_function, ex_Struct ...} from '../pkg/test_wasm.js';

function run {
    // use the function ex_function1 here

}

init().then(run)

Vous incluez votre index.js dans votre fichier HTML

Et là ça marche !

Edit:

Maintenant que je comprends un peu mieux l'écosystème JavaScript, je peux essayer d'expliquer ce que je comprends : Il existe de nombreuses façons d'importer en js, voici une liste : https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm

Vous n'avez pas besoin d'en savoir beaucoup sur cela, sauf que la cible par défaut de wasm-pack est un module ecmascript de style node. Cet import fonctionnera dans node.js, mais pas directement dans le navigateur. Donc dans node, vous pouvez importer une fonction à partir d'un fichier wasm directement, comme ceci : import {ex_function} from "./test.wasm"

Mais ces styles d'import ne fonctionnent pas dans le navigateur en ce moment. Peut-être que ce sera possible à l'avenir Mais pour l'instant, votre navigateur ne connaît que les modules js. Donc si vous essayez d'importer directement un fichier .wasm dans le navigateur, il lancera une erreur de type mime car il ne sait pas comment traiter les fichiers webassembly.

L'outil que vous utilisez pour passer des modules ecmascript (avec beaucoup de packages npm par exemple) à un seul fichier js s'appelle un web-bundler (webpack, rollup, snowpack ...). Si vous travaillez sur un gros projet avec npm, vous en avez probablement besoin. Sinon, le "--target web" indiquera à wasm-bindgen d'instancier le module wasm de la bonne manière (regardez le pkg/test_wasm.js)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X