How to use JSON with react-ace?

5.5k Views Asked by At

Im using react-ace and trying the readme example with java syntax. Works great. But I can't seem to set it to JSON.

Java works

import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-java";
import "ace-builds/src-noconflict/theme-github";

<AceEditor
    mode="java"
    theme="github"
    name="UNIQUE_ID_OF_DIV"
    editorProps={{ $blockScrolling: true }}
/>  

JSON does not work?

import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-github";

<AceEditor
    mode="json"
    theme="github"
    name="UNIQUE_ID_OF_DIV"
    editorProps={{ $blockScrolling: true }}
/>  

The error

Refused to execute script from '...../worker-json.js' because its MIME type ('text/html') is not executable. (anonymous) @ 2f896707-86be-497a-93b2-e1711942d7c7:1 2f896707-86be-497a-93b2-e1711942d7c7:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at '...../worker-json.js' failed to load.

How to use JSON?

4

There are 4 best solutions below

5
tmhao2005 On

From my understanding, you would need to do either way to resolve the worker problem.

  • Import this ace-builds/webpack-resolver:
import AceEditor from "react-ace";

import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-github";

import 'ace-builds/webpack-resolver';
  • Use file-loader to load worker-json file & then configure ace worker:
import AceEditor from "react-ace";

import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-github";

import ace from "ace-builds";

// `webpack` would return the url for `worker-json.js`
// then we use it to configure `ace`
import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";

ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl);
3
Honey On

Try to setOption useWorker: false

      <AceEditor
        mode="json"
        theme="github"
        onChange={onChange}
        name="UNIQUE_ID_OF_DIV"
        editorProps={{ $blockScrolling: true }}
        setOptions={{
          useWorker: false
        }}
      />
0
esta On

One way I made it work was to use mode/json5 (json5 is a superset of json so it work normal) instead of mode/json. Looking at the some github issue on this problem it seems to have few good options to be able to use mode/json.

  • not every project works to import the worker via webpack/file-loader
  • using the webpack-resolver makes the build to big

Some issues on ace own library and some componentes of some other frameworks that use ace.

0
Oleksandr Pyrozhok On

For those searching how to implement workers now, when file-upload is deprecated with Webpack 5 asset/resource.

webpack config:

rules: [
  {
      test: /ace-builds.*\/worker-.*$/,
      type: "asset/resource"
  },
],

component:

import AceEditor from "react-ace";
import { config } from "ace-builds";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/ext-language_tools";
import jsWorkerUrl from "ace-builds/src-noconflict/worker-javascript";
config.setModuleUrl("ace/mode/javascript_worker", jsWorkerUrl);

To fix the typescript "no module declaration" error, just add the global.d.ts file to your src folder:

declare module "ace-builds/src-noconflict/worker-javascript";