Open sombor-shuffle opened 1 year ago
Hi. Did you already have a look at the demo https://github.com/ianfab/fairy-stockfish-nnue-wasm-demo? I hope that should help to get started.
Hi @ianfab, thank you for writing back to me!
I spent some time with the demo yesterday and today.
By reusing the code found there, it's possible for me to create a new html file (foo.html
) inside of the public folder which...
Stockfish
<html>
<body>
<script src="./lib/stockfish.js"></script>
<script>
(async () => {
let stockfish = null;
await Stockfish().then(_stockfish => {
stockfish = _stockfish;
stockfish.addMessageListener(console.log);
});
stockfish.postMessage("uci");
})()
</script>
</body>
</html>
Opening localhost:5000/foo.html
and looking at the console shows the engine's id and options, followed by "uciok".
This is really, really cool, and I'm trying to get it to work inside of a Next.js project (created with npx create-next-app
).
The problem is that I get strange errors if I try to import it using ES6 syntax, i.e import Stockfish from '../../<path>'
. I'm able to add a "raw" <script>
as part of the JSX returned by a React component, but the Stockfish
exposed there is not available elsewhere. I also get some linting issues.
Do you maybe have some advice on how I could proceed? Perhaps it's more appropriate to post this elsewhere? :)
...could I maybe use a worker that talks to Fairy Stockfish?
An update on using a worker:
If foo.html
becomes:
<html>
<body>
<script>
const worker = new Worker('./worker.js');
</script>
</body>
</html>
and worker.js
contains:
importScripts("./lib/stockfish.js");
let stockfish = null;
Stockfish().then(_stockfish => {
stockfish = _stockfish;
stockfish.addMessageListener(console.log);
})
Then the console will output the following error (formatting changed):
wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok (stockfish.js:11)
falling back to ArrayBuffer instantiation (stockfish.js:11)
failed to asynchronously prepare wasm: CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0 (stockfish.js:11)
CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0 (stockfish.js:25)
Uncaught (in promise) RuntimeError: abort(CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0). Build with -s ASSERTIONS=1 for more info.
at M (stockfish.js:25:112)
at stockfish.js:138:293
Working solution:
"use client"
import React, { useEffect } from 'react';
export default function Component() {
useEffect(() => {
// @ts-ignore
console.log(Stockfish)
});
return (
<React.Fragment>
<script src="lib/stockfish.js"></script>
{ /* other things go here... */ }
</React.Fragment>
);
}
It is possible to include a <script>
alongside the rest of the component and refer to Stockfish
inside of an effect hook. It is necessary to also use @ts-ignore
or else the linter complains "Cannot find name 'Stockfish'
".
Is this a good solution? I'm really confused as to why it has to be done this way.
The pure Javascript code example two posts up by @sombor-shuffle should be the official documentation IMHO, the basic demo site and the fairyland demo site are both too mixed in with frameworks that the user probably won't be using.
Hey @zeth, I realized later that the async
... await
pattern can be safely omitted. Also, if you happen to be using Next.js, there is the <Script />
component that could be used instead of the vanilla <script />
tag. From what I understand it lets Next.js bundle Stockfish together with all other assets, producing a single minified main script file. I found that you then have to set the "strategy
" property to "beforeInteractive
" (for this package).
I agree that the basic demo could be more accessible and I wouldn't mind re-writing it in plain js, if there is any enthusiasm for it.
It wouldn't be terrible at all if you could import
Fairy Stockfish, although I lack whatever WebAssembly knowledge is required to make that possible.
Hello! I'm trying to use Fairy Stockfish inside of a Next.js project.
I installed the npm package fairy-stockfish-nnue.wasm.
Now, placing
<script src="stockfish.js"></script>
and then referencingStockfish
inside of another script element works just fine:However, it remains inaccessible to the rest of my application. This lead me to try to
import Stockfish from 'stockfish'
. Sadly, usingStockfish
now leads to an error:console.log(Stockfish)
givesModule not found: Can't resolve 'fs'
.Looking inside of stockfish.js, I can see that "fs" is indeed used, and from here on out I don't know how to proceed.
Any pointers to what I should do to be able to use Fairy Stockfish? :)