ajaxorg / ace

Ace (Ajax.org Cloud9 Editor)
https://ace.c9.io
Other
26.74k stars 5.28k forks source link

Using with npm can't load worker-json.js #3913

Closed rsercano closed 5 years ago

rsercano commented 5 years ago

Hello, first of all thanks for this great editor, I'm trying to use it within MeteorJS (a NodeJS framework), so the below code works perfectly without worker (syntax highlighting).

const Ace = require('ace-builds');

require('ace-builds/src-min-noconflict/mode-json');
require('ace-builds/src-min-noconflict/theme-github');

But that doesn't highlight incorrect JSON as expected, if I add below line;

require('ace-builds/src-min-noconflict/worker-json');

It starts to throw;

Unable to resolve some modules:

 "ace/lib/es5-shim" in
/home/sercan/WebstormProjects/nosqlclient-master/node_modules/ace-builds/src-min-noconflict/worker-json.js
(web.browser)

If you notice problems related to these missing modules, consider running:

  meteor npm install --save ace

I tried to check your syntax highlighting page but it seems like pretty old. How can one make worker work within this way ?

nightwing commented 5 years ago

This happens because worker-json is meant to be loaded in a webworker.

Does meteorjs use webpack? If yes you can add require("ace-builds/webpack-resolver") instead of /mode-json and theme-github requires, and install webpacks file-loader plugin similar to https://github.com/ajaxorg/ace/blob/master/demo/webpack/demo.js#L12

Alternatively if you do not want webpack to create chunks for all of ace modes use ace.config.setModuleUrl('ace/mode/json_worker', require('file-loader!./src-noconflict/worker-json.js'))

rsercano commented 5 years ago

Thanks for quick reply, but unfortunately both ways are not working, I don't think meteor supports file-loader!. syntax, is there any workaround for this issue ?

nightwing commented 5 years ago

Is there any way in meteor to either get url for the file or create a webworker or load a file as a string?

rsercano commented 5 years ago

I'm not really sure (probably there're some painful ways), but I would prefer an easy way to do this instead of loading file as a string, thank you for quick reply tho.

nightwing commented 5 years ago

After some more research i think meteors builtin bundler does not allow to do any of the above, the only workaround i can think of is to load worker files either from cdn or from meteors public folder by using basePath options:

ace.config.set(
    "basePath", 
    "https://cdn.jsdelivr.net/npm/ace-builds@1.4.3/src-noconflict/"
)
rsercano commented 5 years ago

Thank you for your efforts @nightwing, should I set this config before; require('ace-builds/src-min-noconflict/worker-json'); ?

p.s. that way it still complains about resolving ace/lib/es5-shim And if I don't add require line the worker is not working.

nightwing commented 5 years ago

config.set should be used instead of require('ace-builds/src-min-noconflict/worker-json');. If you do not include that line are there any other errors shown in console? maybe cors is blocking the https://cdn.jsdelivr.net/npm/ace-builds@1.4.3/src-noconflict/worker-json.js file?

rsercano commented 5 years ago

No actually nothing happens, this is where I put it There's no error in the console.

nightwing commented 5 years ago

The link was very helpful, this happens because jsoneditor includes an older version of ace, either remove import of jsoneditor or use the version of ace used by it

const Ace = require('brace');

require('brace/mode/json');
require('brace/theme/github');
require('brace/worker/json'); // this works with brace because it includes json worker as a string
rsercano commented 5 years ago

You're a gem thank you, interestingly I had to keep ace-builds npm package but it's okay, closing this

josdejong commented 5 years ago

I solved this issue of not being able to load worker-json.js by:

  1. Create a pre-build step which loads the contents of the webworker, turns it into a a data url with the contents of the worker, and stores that in a file src/generated/json-worker-data-url.js which looks something like:

    const jsonWorkerDataUrl = 'data:application/javascript;base64,...' 
    // ... is the base 64 encoded contents of the worker
  2. Load the generated file with data url in my code so it's embedded in the bundle, and use it like this:

    ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerDataUrl)`

For reference here is the commit containing this solution: https://github.com/josdejong/jsoneditor/commit/920289084409f687361fe3177f3940854951bc70

Similar issue: #4060 (just for reference)

pash90 commented 4 years ago

After some more research i think meteors builtin bundler does not allow to do any of the above, the only workaround i can think of is to load worker files either from cdn or from meteors public folder by using basePath options:

ace.config.set(
    "basePath", 
    "https://cdn.jsdelivr.net/npm/ace-builds@1.4.3/src-noconflict/"
)

This works for me in React as well. Got the same issue but none of the answers worked there.

Malfurion-S commented 4 years ago

I solved this issue of not being able to load worker-json.js by: ace.config.setModuleUrl("ace/mode/json_worker", require("file-loader!ace-builds/src-noconflict/worker-json.js")) I think using 'file-loader!./src-noconflict/xxx' outside node-module 'ace-builds' not works.