Búsqueda de sitios web

javascript - Error al compilar el paquete NPM Stockfish.js (motor de ajedrez) como un Web Worker con Angular8


El objetivo es una aplicación Angular que pueda ejecutarse y jugar contra un motor de ajedrez en el navegador. Quiero ejecutar Stockfish.js como un Web Worker. Al llamar al constructor Worker() con el URI que apunta al archivo stockfish.js, Angular no logra compilar con un error 'Module build failed'.

Esta es una aplicación nueva de Angular que acabo de comenzar para probar el motor de ajedrez en el navegador. Estoy ejecutando...

Angular CLI: 8.0.3 Node: 10.16.0 OS: darwin x64 Angular: 8.0.2 Motor de ajedrez: Stockfish.js 10.0 de NPM

Como una verificación de cordura, serví un archivo HTML y JS simple ejecutando stockfish.js como un Web Worker y funciona bien. El mismo código sin Typescript y Angular.

No he encontrado ningún ejemplo, ni problemas con personas usando un paquete NPM grande de terceros como este como un Web Worker en sus proyectos Angular.

Siento que me está faltando algo con lo que el archivo stockfish.js está intentando hacer con el archivo stockfish.wasm que al compilador de Angular no le gusta.

Este código lo obtuve de la documentación de Angular, en la sección sobre Web Workers. Y estoy pasando la ruta a stockfish al constructor Worker().

app/app.component.ts

  const worker = new Worker ('../../node_modules/stockfish/src/stockfish.js', { type: 'module' });
  worker.onmessage = ({ data }) => {
    console.log(`page got message: ${data}`);
  };
  worker.postMessage('isready');

Este es el archivo de configuración que generó Angular CLI

tsconfig.worker.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/worker",
    "lib": [
      "es2018",
      "webworker"
    ],
    "types": []
  },
  "include": [
    "src/**/*.worker.ts"
  ]
}

Estructura de archivos de Stockfish

node_modules
 - stockfish
    -src
      license.js
      stockfish.asm.js
      stockfish.js
      stockfish.wasm

Este es el error que obtengo cuando Angular compila...

Module build failed (from ./node_modules/worker-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/Users/nicksugar/Chess/node_modules/stockfish/src'
    at factory.create (/Users/nicksugar/Chess/node_modules/webpack/lib/Compilation.js:823:10)
    at factory (/Users/nicksugar/Chess/node_modules/webpack/lib/NormalModuleFactory.js:397:22)
    at resolver (/Users/nicksugar/Chess/node_modules/webpack/lib/NormalModuleFactory.js:130:21)
    at asyncLib.parallel (/Users/nicksugar/Chess/node_modules/webpack/lib/NormalModuleFactory.js:224:22)
    at /Users/nicksugar/Chess/node_modules/neo-async/async.js:2830:7
    at /Users/nicksugar/Chess/node_modules/neo-async/async.js:6877:13
    at normalResolver.resolve (/Users/nicksugar/Chess/node_modules/webpack/lib/NormalModuleFactory.js:214:25)
    at doResolve (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/Resolver.js:184:12)
    at hook.callAsync (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/nicksugar/Chess/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at resolver.doResolve (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:37:5)
    at hook.callAsync (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/nicksugar/Chess/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at hook.callAsync (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/nicksugar/Chess/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at resolver.doResolve (/Users/nicksugar/Chess/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:42:38)```

Respuesta #1

Intenta instalar un constructor angular personalizado y con webpack deshabilita fs

ejecuta npm i -D @angular-builders/custom-webpack

edita tu angular.json para indicarle que use el módulo custom-webpack para extender la configuración virtual con tu archivo webpack.config.js Crea tu propio webpack.config.js:

module.exports = {
    node: {
        fs: 'empty'
      }
};

Consulta este enlace para más detalles