Search code examples
javascripttypescriptcompilationesbuild

I am using ESBuild to compile JS for use in the browser. When I attempt to import CSS, I get [ERROR] Unexpected "." How can i go about fixing this?


I am building a JS notebook that runs in the browser. I am using ESBuild to do the compiling. I am trying to get it to handle a CSS import such as <import 'bulma/css/bulma.css'>. No matter what, I get the following error:

✘ [ERROR] Unexpected "."

a:https://unpkg.com/bulma/css/bulma.css:3:0:
  3 │ .button, .input, .textarea, .select select, .file-cta,
    ╵ ^

I have written the plugin for handling onLoad() to deal with CSS, but it seems my program is not even making it that far before it errors.

Here is the plugin:

import axios from 'axios';
import * as esbuild from 'esbuild-wasm';
import localforage from 'localforage';

const fileCache = localforage.createInstance({
  name: 'fileCache',
});

export const outputCodeFetcher = (inputCode: string) => {
  return {
    name: 'output-code-fetch',
    setup(build: esbuild.PluginBuild) {
      build.onLoad({ filter: /.*/ }, async (args: esbuild.OnLoadArgs) => {
        if (args.path === 'index.js') {
          return {
            loader: 'jsx',
            contents: inputCode,
          };
        }

        const cachedResult = await fileCache.getItem(args.path);

        if (cachedResult) {
          return cachedResult;
        }

        const { data, request } = await axios.get(args.path);

        console.log(request);

        const fileType = args.path.match(/.css$/) ? 'css' : 'jsx';

        const escapedData = (data: string) => {
          return data
            .replace(/\n/g, '')
            .replace(/"/g, '\\"')
            .replace(/'/g, "\\'");
        };

        const contents =
          fileType === 'css'
            ? `
          const style = document.createElement('style');
          style.innerText = '${escapedData(data)}';
          document.head.appendChild(style);
        `
            : data;
        const axiosResult = {
          loader: 'jsx',
          contents: contents,
          resolveDir: new URL('./', request.responseURL).pathname,
        };

        await fileCache.setItem(args.path, axiosResult);
        return axiosResult;
      });
    },
  };
};

Here is the app that runs the ESBuild instance:

import { useState } from 'react';
import {
  inputCodePathResolver,
  outputCodeFetcher,
  startEsbuildService,
} from './plugins';

const App = () => {
  const [input, setInput] = useState('');
  const [code, setCode] = useState('');

  const onClick = async () => {
    const esBuildRef = await startEsbuildService();
    // const result = await esBuildRef.transform(input, {
    //   loader: 'jsx',
    //   target: 'es2015',
    // });
    const result = await esBuildRef.build({
      entryPoints: ['index.js'],
      sourcemap: 'external',
      bundle: true,
      write: false,
      plugins: [inputCodePathResolver(), outputCodeFetcher(input)],
      define: {
        // 'process.env.NODE_ENV': '"production"',
        global: 'window',
      },
      outdir: 'out',
    });
    console.log(result);

    setCode(result.outputFiles[1].text);
  };

  return (
    <>
      <div>
        <textarea
          value={input}
          onChange={(event) => setInput(event.target.value)}
        ></textarea>
        <div>
          <button onClick={onClick}>Submit</button>
        </div>
        <pre>{code}</pre>
      </div>
    </>
  );
};

export default App;

Thank you for any insight.

I have tried to format the CSS file to handle the CSS in a JS snippet, but I don't believe the program is making it that far. I have tried reformatting the instance of ESBuild in the app, but I have gotten no results from that either. I also tried to get esbuild-sass-plugin to work with esbuild-wasm, but no luck there either. I have scoured all related questions on SO and cannot find a case of this specific problem with a viable solution.


Solution

  • I'm unable to reproduce the issue.

    I have cloned your repo, and then started dev server: npm run dev.

    enter image description here

    As you can see, I have no errors. In this case, I suspect that its some caching issue on your end.

    1. Delete your node_modules, and then reinstall dependencies using npm ci.
    2. Delete your build directory: dist, .vite. Restart server using npm run dev.
    3. Take a look and see where else it can cached