Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not load worker #725

Open
sergibondarenko opened this issue Oct 15, 2019 · 34 comments
Open

Could not load worker #725

sergibondarenko opened this issue Oct 15, 2019 · 34 comments

Comments

@sergibondarenko
Copy link

sergibondarenko commented Oct 15, 2019

Problem

Couldn't load worker, JSON syntax validation doesn't work. I see Could not load worker warning in the browser console.

Also, I tried to import the json worker

import "ace-builds/src-noconflict/worker-json";

and got the error

TypeError: Cannot read property 'window' of undefined

Sample code to reproduce the issue

import React from "react";
import ReactDOM from "react-dom";
import AceEditor from "react-ace";

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

let text =
  '{\n  "id": 0,\n  ' +
  '"script": """\n   function add(x, y) {\n      return x + y;\n   }\n   add(1, 2);\n   """' +
  ',\n   "descr": "add two numbers"\n}';

function App() {
  return (
    <div className="App">
      <h1>Code Editor Demo</h1>
      <AceEditor
        mode="json"
        theme="github"
        onChange={(value, stat) => {
          console.log("onChange", value, stat);
        }}
        value={text}
        name="UNIQUE_ID_OF_DIV"
        editorProps={{ $blockScrolling: true }}
      />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

References

Codesandbox https://codesandbox.io/embed/ace-worker-3-vrr68

@ZeD3v
Copy link

ZeD3v commented Oct 17, 2019

I'm experiencing something similar for CSS, getting the following error in browser console:

Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:9000/settings/landing-page/worker-css.js' failed to load.

When attempting to import worker directly

import 'ace-builds/src-noconflict/worker-css';

My build failed with:

ERROR in ../node_modules/ace-builds/src-noconflict/worker-css.js
Module not found: Error: Can't resolve 'ace/lib/es5-shim' in 'path/to/node_modules/ace-builds/src-noconflict'

@nightwing
Copy link

nightwing commented Oct 17, 2019

You need to either include the webpack-resolver

import "ace-builds/webpack-resolver";

or configure the url for each mode separately

import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";
ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl)
import cssWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-css";
ace.config.setModuleUrl("ace/mode/css_worker", cssWorkerUrl)

both methods require "file-loader"

also react-ace tries to load brace if ace is not already imported so ace-builds needs to be imported before react-ace.

import "ace-builds";
import AceEditor from "react-ace";

@arjunu
Copy link

arjunu commented Oct 18, 2019

@nightwing that works but importing ace-builds before react-ace fails in Firefox for me. I got it to work with:

import AceEditor from 'react-ace';
import 'ace-builds/webpack-resolver';
// then the mode, theme & extension
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-tomorrow_night';
import 'ace-builds/src-noconflict/ext-searchbox';

But I couldn't get it to work with my tests. The webpack-resolver import line fails in tests with

TypeError: Cannot read property 'setModuleUrl' of undefined

I'm guessing I need mock ace with something like

global.ace = require('ace-builds/src-min-noconflict/ace');

@mattjstar
Copy link

Did anyone get this working with create-react-app? Mine gets stuck compiling forever if I add:

import 'ace-builds/webpack-resolver';

@ghost
Copy link

ghost commented Oct 24, 2019

I fixed by adding useWorker: false to setOptions if importing modules directly. If this is a good solution, README.md basic usage should be updated unless I'm missing something.

@mattjstar
Copy link

mattjstar commented Oct 25, 2019

@khoomeister that got rid of all the warnings, but did your performance get noticeably worse (that could just be my implementation)?

(thanks for the tip btw!)

@sourovroy
Copy link

setOptions={{ useWorker: false }}

works for me. Thanks @khoomeister

@doneumark
Copy link

also still having this issue.
does using "useWorker has any downsides? what does those workers do exactly?

@caprica
Copy link

caprica commented Nov 28, 2019

I'm using a create-react-app project.

The only thing I needed to do was to add this in my App.tsx:

import 'ace-builds/webpack-resolver'

Setting useWorker to false disables syntax checking at least, maybe other things, so I didn't want to use that.

I don't know yet if this is good enough to make it work with tests as per arjunu's comment above.

@bespokebob
Copy link

bespokebob commented Dec 5, 2019

Adding webpack-resolver to my create-react-app project leads to a huge increase in compile time, and adds hundreds of files to the build directory - I assume one for each module in ace-builds that it configures. Configuring the url for just the modules that I need works fine, though.

This seems like it's an issue with either react-scripts or ace-builds, not react-ace.

@jan-osch
Copy link

So far I am happy with react-ace, thanks for all the hard work guys!

I was attempting to upgrade to version 8 but I failed due to issues with worker, so for now I am staying at 7.

I am using "react-scripts": "3.2.0" (Create React App)

I could not get worker to load, and the following errors were displayed in the console:

03226918-0f44-4ac8-b073-1abc2ed64713:1 Refused to execute script from 'http://localhost:8000/worker-javascript.js' because its MIME type ('text/html') is not executable.
(anonymous) @ 03226918-0f44-4ac8-b073-1abc2ed64713:1
9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1 Refused to execute script from 'http://localhost:8000/worker-javascript.js' because its MIME type ('text/html') is not executable.
(anonymous) @ 9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1
03226918-0f44-4ac8-b073-1abc2ed64713:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8000/worker-javascript.js' failed to load.
    at blob:http://localhost:8000/03226918-0f44-4ac8-b073-1abc2ed64713:1:1
(anonymous) @ 03226918-0f44-4ac8-b073-1abc2ed64713:1
9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8000/worker-javascript.js' failed to load.
    at blob:http://localhost:8000/9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1:1
(anonymous) @ 9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1

Disabling the worker is not an option for me. I tried adding the webpack-resolver using import 'ace-builds/webpack-resolver'; but my app would not compile - the compilation was hanging indefinitely.

I also attempted to add it manually using the file-loader and setModuleUrl but then I got the error with missing ace/lib/es5-shim.

It seems that this issue is related to #733 #755 and ajaxorg/ace#4770

@bitconym
Copy link

@mattjstar I got it working with:

import 'ace-builds'
import 'ace-builds/webpack-resolver'

So import ace-builds before the resolver (any anything else relater to the AceEditor)

See @arjunu answer above.

@Holgrabus
Copy link

Holgrabus commented Jan 8, 2020

I added the last 3 lines to add javascript-worker :

import AceEditor from "react-ace";
import "ace-builds/src-min-noconflict/mode-javascript";
import "ace-builds/src-min-noconflict/theme-tomorrow_night_eighties";
import "ace-builds/src-min-noconflict/ext-language_tools";
import "ace-builds/src-min-noconflict/ext-spellcheck";
import "ace-builds/src-min-noconflict/snippets/javascript";
import 'ace-builds/src-min-noconflict/ext-searchbox';
const ace = require('ace-builds/src-noconflict/ace');
ace.config.set("basePath", "https://cdn.jsdelivr.net/npm/ace-builds@1.4.3/src-noconflict/");
ace.config.setModuleUrl('ace/mode/javascript_worker', "https://cdn.jsdelivr.net/npm/ace-builds@1.4.3/src-noconflict/worker-javascript.js");

You can copy/paste the file worker-javascript.js in your local environment if you don't want to be dependant of cdn.jsdelivr.net.

@pranavwani
Copy link

pranavwani commented Mar 22, 2020

You need to either include the webpack-resolver

import "ace-builds/webpack-resolver";

or configure the url for each mode separately

import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";
ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl)
import cssWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-css";
ace.config.setModuleUrl("ace/mode/css_worker", cssWorkerUrl)

both methods require "file-loader"

also react-ace tries to load brace if ace is not already imported so ace-builds needs to be imported before react-ace.

import "ace-builds";
import AceEditor from "react-ace";

This works perfectly. Define worker URL before using any mode or theme

import "ace-builds"
import ACE from "react-ace/dist/react-ace.min";

import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";
ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl);
import xmlWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-xml";
ace.config.setModuleUrl("ace/mode/xml_worker", xmlWorkerUrl);
import jsWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-javascript";
ace.config.setModuleUrl("ace/mode/javascript_worker", jsWorkerUrl);

import "ace-builds/src-min-noconflict/mode-typescript";
import "ace-builds/src-min-noconflict/mode-javascript";
import "ace-builds/src-min-noconflict/mode-graphqlschema";
import "ace-builds/src-min-noconflict/mode-json";
import "ace-builds/src-min-noconflict/mode-xml";
import "ace-builds/src-min-noconflict/mode-markdown";
import "ace-builds/src-min-noconflict/mode-html";
import "ace-builds/src-min-noconflict/theme-github";
import "ace-builds/src-min-noconflict/theme-tomorrow";
import "ace-builds/src-min-noconflict/theme-kuroir";
import "ace-builds/src-min-noconflict/ext-searchbox";

also no need to set: setOptions={{ useWorker: false }}
#725 (comment)

@MattNot
Copy link

MattNot commented Mar 26, 2020

What if i want to have a custom worker that is not in the ace-builds/src-.../ folder?
I need to use it with an ANTLR parser done by me.

@jchonde
Copy link

jchonde commented Mar 27, 2020

I leave the full NextJS@9.3 integration here.

import dynamic from "next/dynamic";

const AceEditor = dynamic(
  async () => {
    const reactAce = await import("react-ace");

    // prevent warning in console about misspelled props name.
    await import("ace-builds/src-min-noconflict/ext-language_tools");

    // import your theme/mode here. <AceEditor mode="javascript" theme="solarized_dark" />
    await import("ace-builds/src-min-noconflict/mode-javascript");
    await import("ace-builds/src-min-noconflict/theme-solarized_dark");

    // as @Holgrabus commented you can paste these file into your /public folder.
    // You will have to set basePath and setModuleUrl accordingly.
    let ace = require("ace-builds/src-min-noconflict/ace");
    ace.config.set(
      "basePath",
      "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/"
    );
    ace.config.setModuleUrl(
      "ace/mode/javascript_worker",
      "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/worker-javascript.js"
    );

    return reactAce;
  },
  {
    ssr: false // react-ace doesn't support server side rendering as it uses the window object.
  }
);

export default () =>  <AceEditor mode="javascript" theme="solarized_dark" />

@MattNot
Copy link

MattNot commented Mar 27, 2020

@jan-osch so if I want to use my "customWorker.js" for example, i've to set ace.config.setModuleUrl("ace/mode/myWorker", "/customWorker.js") ? (putting customWorker.js in the /public folder)

@jamesej
Copy link

jamesej commented May 15, 2020

If you want to use the workarounds in Typescript you'll need to do this to set ace config:

import { config } from 'ace-builds';

config.set(
  "basePath",
  "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/"
);
config.setModuleUrl(
   "ace/mode/javascript_worker",
   "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/worker-javascript.js"
);

@aboganas
Copy link

I added the following test to Webpack

  module: {
    rules: [
      {
        test: /ace-builds.*\/worker-.*$/,
        loader: 'file-loader',
        options: {
          esModule: false,
          name: '[name].[hash:8].[ext]',
        },
      },
    ],
  },

then I was able to import as following

import ace from 'ace-builds/src-noconflict/ace';
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';

ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);

@johnjackweir
Copy link
Contributor

I'm importing as suggested by @pranavwani but now am running into the error
Cannot read property 'Range' of undefined. "Error loading module." when ace.tsx is attempting to import ace/range.

I believe that the issue is that since window.ace is defined, even though I want to be using ace-builds, ace keeps falling back on the ace.acequire syntax in editorOptions. Has anyone come across a workaround for this issue?

@legolasNg
Copy link

I added the following test to Webpack

  module: {
    rules: [
      {
        test: /ace-builds.*\/worker-.*$/,
        loader: 'file-loader',
        options: {
          esModule: false,
          name: '[name].[hash:8].[ext]',
        },
      },
    ],
  },

then I was able to import as following

import ace from 'ace-builds/src-noconflict/ace';
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';

ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);

you can also do that without modify webpack config

import ace from 'ace-builds/src-noconflict/ace';
/* eslint import/no-webpack-loader-syntax: off */
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';

ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);

dbartholomae added a commit to startup-cto/christmas-delivery that referenced this issue Dec 20, 2020
They were causing issues (see securingsincity/react-ace#725) and were not necessary anyways.
@p3x-robot
Copy link

do you guys how to solve this as file-loader is deprecated, how can we configrue ace now without file-loader?

@mgoldenbe
Copy link

What is the status of this issue? Although importing webpack-resolver works, it makes compilation super-slow, so cannot be considered a permanent solution.

@mgoldenbe
Copy link

mgoldenbe commented Jul 19, 2021

The following seems to have worked for me. The key is the order of imports and the last three lines (including the comment!) I got it from this reply.

import 'ace-builds'
import AceEditor from 'react-ace';
import ace from 'ace-builds/src-noconflict/ace'
// import mode-<language> , this imports the style and colors for the selected language.
import 'ace-builds/src-noconflict/mode-xml';
// there are many themes to import, I liked monokai.
import 'ace-builds/src-noconflict/theme-github';
// this is an optional import just improved the interaction.
import 'ace-builds/src-noconflict/ext-language_tools';
import 'ace-builds/src-noconflict/ext-beautify';
// eslint-disable-next-line import/no-webpack-loader-syntax
import xmlWorkerUrl from "!!file-loader!ace-builds/src-noconflict/worker-xml";
ace.config.setModuleUrl("ace/mode/xml_worker", xmlWorkerUrl);

@er-dev
Copy link

er-dev commented Sep 8, 2021

None of these suggestions are working for me. I am getting the same Cannot read property 'window' of undefined as the OP.

When I use:

import AceEditor from 'react-ace'
import 'ace-builds/webpack-resolver'
import 'ace-builds/src-noconflict/mode-javascript'

I get the following error: 61b85f295f78e37ba4d607ea64fab1e8.js:1 Uncaught TypeError: Cannot read property 'window' of undefined

After comparing ace-builds/src-noconflict/worker-javascript.js to my generated version, there are some changes:

  1. use strict' is added to the file at the top, right above 'no use strict'`
  2. The self-executing function at the start:
!(function (window) {
  if (typeof window.window != 'undefined' && window.document) return
})(this)

Turns into:

!(function (window) {
  if (typeof window.window != "undefined" && window.document) return;
})(void 0);

I believe this is causing me and the OPs issue. Any idea why these files would be transformed like this?

@AlmogBaku
Copy link

Adding webpack-resolver creating 100+ js files when building the project
#1168

@mattduggan
Copy link

I had trouble getting webpack-resolver to play nicely with Jest and couldn't figure out the magic moduleNameMapper pattern.

I was able to work around this in Webpack v5 by using an Asset Module targeting the worker* files in ace-build:

// webpack.config.js
module: {
  rules: [
    {
      test: /worker-.*\.js/,
      include: [/node_modules\/ace-build/],
      type: 'asset/resource',
    }
  ]
}
// editor.js
import ace from 'ace-builds/src-noconflict/ace';
import 'ace-builds/src-noconflict/mode-json';
import jsonWorker from 'ace-builds/src-noconflict/worker-json';

ace.config.setModuleUrl('ace/mode/json_worker', jsonWorker);

@haftav
Copy link

haftav commented Apr 1, 2022

For those of you using Vite, I was able to get it working using Explicit URL Imports (appending ?url to the end of the worker import):

import ace from 'ace-builds/src-noconflict/ace';
import jsonWorkerUrl from 'ace-builds/src-noconflict/worker-json?url';

ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerUrl);

// ... mode and theme imports here

@AmazingYuan
Copy link

AmazingYuan commented May 19, 2022

import ace from 'ace-builds/src-min-noconflict/ace';
import 'ace-builds/webpack-resolver'; 

This solution works for me, it solves all my import problems, include worker execute problem.

@Cactusx09
Copy link

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";

@jumasheff
Copy link

jumasheff commented Jan 28, 2023

@Cactusx09 thank you!!!

For those who don't know how to add webpack configs to a nextjs project, here's my snippet:
next.config.js:

const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  ...
  webpack: (config, options) => {
    config.module.rules.push({
      test: /ace-builds.*\/worker-.*$/,
      type: 'asset/resource',
    });
    return config;
  },
};

module.exports = nextConfig;

@miletbaker
Copy link

If you want to use the workarounds in Typescript you'll need to do this to set ace config:

import { config } from 'ace-builds';

config.set(
  "basePath",
  "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/"
);
config.setModuleUrl(
   "ace/mode/javascript_worker",
   "https://cdn.jsdelivr.net/npm/ace-builds@1.4.8/src-noconflict/worker-javascript.js"
);

Thanks

This is also the solution if you don't use WebPack or create-react-app

@Dragusin-Cristian
Copy link

setOptions={{ useWorker: false }}

works for me. Thanks @khoomeister

Yes, it works also for me.

@dolphin0618
Copy link

dolphin0618 commented Sep 5, 2023

if you use vite, you can ...

import { viteStaticCopy } from 'vite-plugin-static-copy'

export default defineConfig(() => {
    plugins: [
      viteStaticCopy({
        targets: [
          {
            src: [
              'node_modules/ace-builds/src-min-noconflict/ace.js',
              'node_modules/ace-builds/src-min-noconflict/mode-json.js',
              'node_modules/ace-builds/src-min-noconflict/worker-json.js'
            ],
            dest: 'node_modules/ace-builds/src-min-noconflict/'
          }
        ]
      })],
    })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests