Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

ace bug #38

Open
izengliang opened this issue Oct 5, 2014 · 23 comments
Open

ace bug #38

izengliang opened this issue Oct 5, 2014 · 23 comments

Comments

@izengliang
Copy link

System.import("ace").then(function (ace) {
    var editor = ace.edit("editor");
    editor.getSession().setMode("ace/mode/javascript"); 
})

print

GET http://localhost:63342/jshow-ui/mode-javascript.js

no found!

@guybedford
Copy link
Member

Ace does need some careful configuring... I'll see if I can check it out this week and suggest some configuration for it.

@ivanbacher
Copy link
Contributor

Any update on this issue?

Ace also allows you to change the base path:
ace.config.set('basePath', '/jspm_packages/github/ajaxorg/ace-builds@1.1.8/');

This solves the problem of not finding the files, but introduces another problem:
screen shot 2015-01-28 at 13 10 04

The mode or template files need a reference to ACE

@guybedford
Copy link
Member

@BuildingJarl nice work! That looks like it could be fixed with a shim on install:

  jspm install ace -o "{ shim: { 'path/to/theme-monokai': { deps: ['../relpath/to/ace'] } }}"

Do post back if you make progress.

@ivanbacher
Copy link
Contributor

@guybedford Thanks for the help, but unfourtunatly it doesnt seem to be working. This could also be because of my limited understanding.

I have tried the following:

jspm install ace -o "{ shim: { 'github:ajaxorg/ace-builds@1.1.8/theme-clouds': { deps: ['./ace'] } }}"

jspm install ace -o "{ shim: { 'github:ajaxorg/ace-builds@1.1.8/theme-clouds': { deps: ['github:ajaxorg/ace-builds@1.1.8/ace'] } }}"

Both resulting in the wrong object being exported
screen shot 2015-01-29 at 11 32 18

when installing ace normally

jspm install ace

The following object is exported, which is correct:

screen shot 2015-01-29 at 11 34 19

@guybedford
Copy link
Member

@BuildingJarl you can fix the object with shim.ace = { exports: 'ace' }.

@ivanbacher
Copy link
Contributor

@guybedford
Alright, at this point I am somewhat confused to how this works.

The ace editor calls this function: editor.setTheme("ace/theme/clouds"); which sends a get request for a file theme-clouds.js. The request thinks that the file is located at http://localhost:8080/theme-clouds.js which is incorrect.

By using this function: ace.config.set('basePath', '/jspm_packages/github/ajaxorg/ace-builds@1.1.8/'); the get request finds the correct file, but an error occurs when loading the file. The error is on line 3 which is the following statement, define("ace/theme/clouds",["require","exports","module","ace/lib/dom"], function(require, exports, module) { ... }

This is the normal procedure for changing themes:
To change the theme simply include the Theme's JavaScript file
<script src="src/theme-twilight.js" type="text/javascript" charset="utf-8"></script>
and configure the editor to use the theme:
editor.setTheme("ace/theme/twilight");

@guybedford
Copy link
Member

Right, so Ace is trying to do its own module loading it seems, expecting an AMD environment.

By default, SystemJS doesn't make the main code environment an AMD one (window.define is not defined). We can do this with https://github.com/systemjs/systemjs/wiki/Module-Format-Support#requirejs-support, but it is not a very modular approach.

Perhaps see if there is a way in the Ace API to "inject" the theme in and load the module manually - something like:

// myace-with-clouds-theme.js
import ace from 'ace';
import clouds from 'ace/theme/clouds';
ace.injectTheme(clouds); // <--- what would this line be?
export default ace;

@ivanbacher
Copy link
Contributor

Unfortunately I have not found a way to do what you suggested, but I managed to get the theme and the mode changed used a quick and dirty fix. All I did was copy the source from the theme-twilight file into the ace source. This is not a good solution and I will try to find another one.

@ivanbacher
Copy link
Contributor

@guybedford I have found a different solution:

jspm install github:ajaxorg/ace-builds -o "{ directories: { lib: 'src-noconflict' }, main: 'ace', format: 'global', shim: { 'ace-builds': { exports: 'ace' }, 'ace-builds/theme-monokai': { deps: ['ace-builds'] }, 'ace-builds/mode-html': { deps: ['ace-builds']} } }" -f

import ace from "ace-builds";
import "ace-builds/theme-monokai";
import "ace-builds/mode-html";

var editor = ace.edit("editor");

editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");

One problem still remains: Ace requires an external script for a web-worker when changing the mode. I think this is for showing errors.

screen shot 2015-01-30 at 16 52 54

@guybedford
Copy link
Member

@BuildingJarl this is great!! It looks like you've nearly worked this out.

For the source mode worker, does it help if you make ./worker-html an extra dependency in the shim for the mode-html?

@ivanbacher
Copy link
Contributor

@guybedford No, unfortunately that doesn't work. But there is another way to get the webworker to load. Im not sure if this is the correct way of doing it though.

In ACE the following line loads the worker

try {
        this.$worker = new Worker(workerUrl);
    } catch(e) {
        ...
    }

This issues a get request for the worker.js file. The get request doesnt know where the files is located, so we have to configure ACE's basepath. Like so:

ace.config.set("basePath", "/jspm_packages/github/ajaxorg/ace-builds@1.1.8/");

Now, the web worker is able to load and no errors pop up in the console.

The whole code being:

import ace from "ace-builds";
import "ace-builds/theme-monokai";
import "ace-builds/mode-html";

var editor = ace.edit("editor");

ace.config.set("basePath", "/jspm_packages/github/ajaxorg/ace-builds@1.1.8/");

editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");

Result:

screen shot 2015-02-02 at 11 14 15

@guybedford
Copy link
Member

AMAZING!

This would be a really good argument for allowing an init function to be set in the shim config, that could do this automatically with a parameter to the path. I've added that back for reconsideration in the SystemJS update.

@MadMub
Copy link

MadMub commented Oct 29, 2015

@guybedford Wondering if the workaround suggested by @BuildingJarl can be improved without having to directly reference the install path. Basically could we leverage jspm/systemjs so that

import ace from "ace-builds";
import "ace-builds/theme-monokai";
import "ace-builds/mode-html";

var editor = ace.edit("editor");

ace.config.set("basePath", "/jspm_packages/github/ajaxorg/ace-builds@1.1.8/");

editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");

Becomes something like:

import ace from "ace-builds";
import "ace-builds/theme-monokai";
import "ace-builds/mode-html";
import system from "systemjs";

var editor = ace.edit("editor");

ace.config.set("basePath", system.resolvePath('ace-builds'));

editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");

I'm not really sure if systemjs/jspm has an API method like that, or if it's possible (I tried briefly to find it in either API but figured it would be easier to ask you @guybedford )

@guybedford
Copy link
Member

You could try using System.normalizeSync('ace-builds').

@MadMub
Copy link

MadMub commented Nov 2, 2015

This works perfect in development mode (where I have a filesystem), but in my production build I have a giant SFX, so I'm not sure how to workout setting a "basePath", if only ace had the option to pass in a web-worker object instead of a path

@MadMub
Copy link

MadMub commented Nov 3, 2015

@guybedford Just a quick follow up, I found a project dedicated to hacking ace.js to have inlined web workers. https://github.com/thlorenz/brace

The package works in a development build no problem (without need of setting basePath). However I have run into a setback when building a SFX. The build executes, however it errors out on the first ace.define call. My guess is that Systemjs is building the subsequent calls in brace/index.js before the initial export and definition of ace itself. The exporting seems rather strange (to me) so its hard for me to debug.

It looks like index.jx first executes an anonymous function namespaced to "ace" and then runs ace's proprietary ace.define for subsequent ace modules and extensions. Perhaps if my import syntax were different, or maybe there is a way in jspm/systemjs to specify order when bundling a given module? Any thoughts or pointers are greatly appreciated thank you.

Link to brace/index.js
https://github.com/thlorenz/brace/blob/master/index.js

@MadMub
Copy link

MadMub commented Nov 3, 2015

I have made some progress. Stock brace works in production workflow (although since stock does not set mode, obviously the web worker does not load). From there, I globally shimmed the theme file as such:

meta: {
        'npm:brace@0.5.1/theme/monokai': {
            deps: ['npm:brace@0.5.1/index']
        }
    }

This worked, giving me hope to do the same with the mode and worker:

meta: {
        'npm:brace@0.5.1/theme/monokai': {
            deps: ['npm:brace@0.5.1/index']
        },
        'npm:brace@0.5.1/mode/javascript': {
            deps: ['npm:brace@0.5.1/index']
        },
        'npm:brace@0.5.1/worker/javascript': {
            deps: ['npm:brace@0.5.1/index']
        }
    }

Alas I am getting the ace is not defined error during the mode files System.registerDynamic call. @guybedford Any clue why the dependency global worked for the theme file but not the mode/worker file? Does Systemjs not allow declaring the same dependency twice?

@MadMub
Copy link

MadMub commented Nov 3, 2015

Success! the shim was perfect, however in the file in which i set the mode to javascript I needed to import the worker file (despite never explicitly using it). Here is the final code to load up ace:

import ace from 'brace';
import 'brace/theme/monokai';
import 'brace/mode/javascript';
import 'brace/worker/javascript';

var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");

Where every theme, extension, mode, worker needs to be shimmed in the config file:

meta: {
    "brace/theme/monokai": {
      "deps": [
        "brace"
      ]
    },
    "brace/mode/javascript": {
      "deps": [
        "brace"
      ]
    },
    "brace/worker/javascript": {
      "deps": [
        "brace"
      ]
    }
  }

Caveat
this is using brace: https://github.com/thlorenz/brace

jspm install npm:brace

@jdanyow
Copy link
Contributor

jdanyow commented Jan 4, 2016

this worked for me:

jspm install ace

then...

import ace from 'ace';

// get the path to the ace theme/mode assets- eg "http://localhost:9000/jspm_packages/github/ajaxorg/ace-builds@1.2.2.js"
let base = System.normalizeSync('ace'); 
// strip the trailing ".js" from the path:
base = base.substr(0, base.length - 3);
// configure ace with the base path
ace.config.set('basePath', base);

// now we're ready to use Ace
let editor = ace.edit(someElement);
editor.setTheme('ace/theme/monokai');
editor.getSession().setMode('ace/mode/javascript');

♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️ ♠️

@justin-schroeder
Copy link

Huge props to @jdanyow for his approach. Since ace seems pretty set on using its own module loading, it seems that not trying to hack around it will lead to the most stable results in the long run.

@naivefun
Copy link

@jdanyow Thanks for you solution. But seems it's not working for extension.
for example:
ace.require('ace/ext/language_tools'); or ace.require('language_tools'); is not loading. any way to fix this? thanks.

@naivefun
Copy link

Hey this fixes my problem:

import "ace/ext-language_tools";

Thanks for the tips anyway.

@3cp
Copy link

3cp commented Jul 28, 2016

follow @MadMub 's example, the meta definition can be simplified to

meta: {
    "brace/*": {
      "deps": [
        "brace"
      ]
    }
  },

works on jspm 0.16.39 systemjs 0.19.31.

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

No branches or pull requests

8 participants