Search code examples
reactjsesbuild

EsBuild StartService replacement


I am new to esBuild and ReactJS and following a guid I decided to building a custom CLI Transpiling application. I got to the point that I am entering a text in textarea but on the console in the client the following error message came out Host version "0.8.27" does not match binary version "0.9.0". I know that I am using an older version, I did try to find a way to resolve the problem first with going trough the documentation since they have completly throw away the startService() method on the new version. But I couldn't find any possible solution to my problem, is there someone with the knowledge to help me solve the problem. Here is my code which has to start the transpiling:

const startService = async () => {
ref.current = await esbuild.startService({
  worker: true,
  wasmURL: '/esbuild.wasm'
})
  }

 useEffect(() => {
    startService()
  }, [])

  const onClick = async () => {
    if (!ref.current) {
      return;
    }
    const result = await ref.current.build({
      entryPoints: ['index.js'],
      bundle: true,
      write: false,
      plugins: [unpkgPathPlugin()]
    })
    console.log(result );
    setCode(result)
  }

Solution

  • Note that there is no async API available when running in the browser. Also, I didn't want to be throwing 'already initialized' every time I hot reloaded while editing. This is how I set this up:

    import { useState, useEffect } from 'react';
    import './App.css';
    import * as esbuild from 'esbuild-wasm';
    
    function App() {
      const [input, setInput] = useState('');
      const [code, setCode] = useState('');
    
      useEffect(() => {
        // This ugly code is to avoid calling initialize() more than once
        try {
          esbuild.build({});
        } catch (error) {
          if (error instanceof Error && error.message.includes('initialize')) {
            esbuild.initialize({
              worker: false,
              wasmURL: '/esbuild.wasm',
            });
          } else {
            throw error;
          }
        }
      }, []);
    
      const onClick = () => {
        esbuild
          .transform(input, {
            loader: 'jsx',
            target: 'es2015',
          })
          .then((result) => {
            setCode(result.code);
          });
      };
    
      return (
        <div className="App">
          <textarea
            value={input}
            onChange={(e) => setInput(e.target.value)}></textarea>
          <div>
            <button onClick={onClick}>Submit</button>
          </div>
          <pre>{code}</pre>
        </div>
      );
    }
    
    export default App;