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

Using ace-builds with webpack #4782

Closed
komali2 opened this issue Apr 19, 2018 · 21 comments
Closed

Using ace-builds with webpack #4782

komali2 opened this issue Apr 19, 2018 · 21 comments

Comments

@komali2
Copy link

komali2 commented Apr 19, 2018

We are trying to use ace-builds with webpack.

We have used the line

var Ace = require('ace-builds/src/ace');

ERROR  Failed to compile with 91 errors                                                                                            12:26:03

These relative modules were not found:

* ../../lib/lang in ./node_modules/ace-builds/src/ace.js
* ../../lib/oop in ./node_modules/ace-builds/src/ace.js
<snip>

We have tried many iterations of "using ace editor with webpack," further documented on the master ace-editor repo.

We worked on this a long time before making an issue in either place, I am doing so now because I have been unable to find a definitive resource on using either ace, ace-builds, or brace with webpack on a repo that uses custom modes.

What is the proper way to use ace-builds with webpack?

@nightwing
Copy link
Member

For backwards compatibility current version of ace-builds/src does not work with webpack.
But you can use var ace = require('ace-builds'); or var ace = require('ace-builds/src-noconflict/ace');

There is a demo of using ace-builds with webpack at https://github.com/ajaxorg/ace/blob/master/demo/webpack/demo.js, please let me know if you have any questions about it, or have any suggestions on how to improve it.

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

This is great help, thank you for taking the time to reply.

That sorts out a lot of the dependency errors we were getting from ace, but for custom modes we're still having trouble figuring it out.

For example, when using ace without webpack (pure require.js), we would just

var TextMode = require("ace/mode/text").Mode;
var CStyleFoldMode = require("ace/mode/folding/cstyle").FoldMode;

However, I can't find, for example, mode/text in the ace-builds repo (or anything about cstyle)

Do you have any advice about this?

Once we sort this, I will be very happy to get together some suggestions on documentation for using custom modes with webpack. It's possible that my team and I are just missing something obvious, though!

EDIT: Maybe we are requiring those modes unecessarily? We would use it in our custom mode definition like:

var Mode = function() {
    this.HighlightRules = CustomHighlightRules;

    this.$outdent = new MatchingBraceOutdent();
    this.$behaviour = new CstyleBehaviour();
    this.foldingRules = new CStyleFoldMode();
};

@nightwing
Copy link
Member

There only a hacky way of doing this for now.

use

// load the javascript mode which contains cstyle helpers
require("ace-builds/src-noconflict/mode-javascript")
// use ace.require to get internal modules
var CStyleFoldMode = ace.require("ace/mode/folding/cstyle").FoldMode;

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

Ok, awesome, will try in a second. For the record, I tried also installing the entire ace-code-editor package alongside ace-builds, and for things like cstyle referring to them inside the ace-code-editor package, and got errors such as

jQuery.Deferred exception: Cannot read property 'split' of undefined TypeError: Cannot read property 'split' of undefined
    at AppConfig.exports.moduleUrl (webpack-internal:///./node_modules/ace-builds/src-noconflict/ace.js:4368:22)

Just to dissuade anybody from going down that route.

Will report back about above suggestion in new comment.

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

Appreciate the suggestion, this has given us a new avenue to explore. Had forgotten about ace.require (and the acequire equivalent of brace).

Unfortunately, we're getting a similar error to above

jQuery.Deferred exception: Cannot read property 'split' of undefined TypeError: Cannot read property 'split' of undefined
    at AppConfig.exports.moduleUrl (webpack-internal:///./node_modules/ace-builds/src-noconflict/ace.js:4368:22)

Just the initial report, still digging to learn more.

Thank you for all your help so far, we're getting further now than we have all week.

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

For some reason, this error is occuring simply by doing var Ace = require('ace-builds/src-noconflict/ace');, I must have made an error somewhere, looking further

EDIT: It was because I was setting mode to an empty object to debug.

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

This error was my fault.

The end of our custom mode file looked like

exports.Mode = Mode;

});

But I was only doing

var mode = require('@/lib/ace/mode/custom');

I should have been doing

var mode = require('@/lib/ace/mode/electricimp').Mode;

Then, later, i did set_mode on mode directly, when I should have been doing

session.setMode(new mode());

Will comment will full setup momentarily. Thank you for your help @nightwing , I think we've got it sorted!

@komali2
Copy link
Author

komali2 commented Apr 19, 2018

For those that come after:

  1. npm install ace-builds

  2. Change require statements to

var Ace = require('ace-builds/src-noconflict/ace');

  1. Give up on dynamically importing themes, do
    var theme_idle_fingers = require('ace-builds/src-noconflict/theme-idle_fingers');
    var theme_github = require('ace-builds/src-noconflict/theme-github');
    editor.set_theme(theme_github)
  1. At the top of your custom mode and custom highlight rules files, do
// load the javascript mode which contains cstyle helpers
require("ace-builds/src-noconflict/mode-javascript")
var Ace = require('ace-builds/src-noconflict/ace');
  1. Then you can pull in component modes like
// defines the parent mode
var TextMode = Ace.require("ace/mode/text").Mode;
var CStyleFoldMode = Ace.require("ace/mode/folding/cstyle").FoldMode;
var CstyleBehaviour = Ace.require("ace/mode/behaviour/cstyle").CstyleBehaviour;
  1. For posterity, highlight rules works just like modes:
var Ace = require('ace-builds/src-noconflict/ace');

// load the javascript mode which contains cstyle helpers
require("ace-builds/src-noconflict/mode-javascript")
var oop = Ace.require("ace/lib/oop");
var DocCommentHighlightRules = Ace.require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = Ace.require("ace/mode/text_highlight_rules").TextHighlightRules;
  1. Make sure you are importing / exporting and doing new when necessary. If the end of your custom mode file looks something like
var Mode = function() {
    this.HighlightRules = CustomHighlightRules;

    this.$outdent = new MatchingBraceOutdent();
    this.$behaviour = new CstyleBehaviour();
    this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);

(function() {
    //logic
}).call(Mode.prototype);

exports.Mode = Mode;

});

Then you need to do the following in your actual editor code:

var mode = require('@/lib/ace/mode/electricimp').Mode;

session.setMode(new mode());

@nightwing
Copy link
Member

Give up on dynamically importing themes, do

this is not nessesary

import "ace-builds/webpack-resolver";
editor.setTheme('ace/theme/github');

as shown in https://github.com/ajaxorg/ace/blob/master/demo/webpack/demo.js#L12, should work.

@XanderLuciano
Copy link

Another option is to leverage a CDN for loading themes / modes.

import 'ace-builds/src-min-noconflict/ace' // Load Ace Editor

// Import initial theme and mode so we don't have to wait for 2 extra HTTP requests
import 'ace-builds/src-min-noconflict/theme-chrome'
import 'ace-builds/src-min-noconflict/mode-javascript'

// cdnjs didn't have a "no-conflict" version, so we'll use jsdelivr
const CDN = 'https://cdn.jsdelivr.net/npm/ace-builds@1.3.3/src-min-noconflict';

// Now we tell ace to use the CDN locations to look for files
ace.config.set('basePath', CDN);
ace.config.set('modePath', CDN);
ace.config.set('themePath', CDN);
ace.config.set('workerPath', CDN);

// Create Editor
const editor = ace.edit('editor');

// Set Editor Theme and Mode
editor.setTheme('ace/theme/chrome');
editor.session.setMode('ace/mode/javascript');

Later on you can update the theme / mode, and it'll just fetch the corresponding files from the CDN dynamically. (or you can copy all the files from ace-builds/src-??/*.* to a public directory on your serve if you prefer to self host).

@Ray-Eldath
Copy link

@XanderLuciano Many thanks! This certainly helps!
I think this issue could be closed.

@sumbria
Copy link

sumbria commented Nov 23, 2018

You can try this:

npm i ace-builds
import 'ace-builds';
import 'ace-builds/webpack-resolver';
ace.edit("editor", {
	mode: "ace/mode/html",
	theme: "ace/theme/dracula",
	maxLines: 50,
	minLines: 10,
	fontSize: 18
});
<div id="editor"></div>

@toasterpic
Copy link

toasterpic commented Apr 26, 2020

import 'ace-builds/webpack-resolver';

Bundles a lot of stuff not being used by this example, bloating vendor.js. You could instead import only what you will end-up using. In the example above the following would have been sufficient.

import * as ace from 'ace-builds'
import 'ace-builds/src-noconflict/mode-html'
import 'ace-builds/src-noconflict/theme-dracula'

@vdh
Copy link

vdh commented Aug 17, 2021

ace-builds/src-noconflict/worker-json.js appears to have require issues in Webpack as well 😞

@tcstory
Copy link

tcstory commented Sep 6, 2021

ace-builds/src-noconflict/worker-json.js appears to have require issues in Webpack as well

I used the following code and everything is ok

const Ace = require('ace-builds/src-noconflict/ace')
require('ace-builds/src-noconflict/mode-json5')
require('ace-builds/src-noconflict/theme-github')

    const editor = Ace.edit(this.$refs.editor, {
      mode: 'ace/mode/json5',
      theme: 'ace/theme/github',
      maxLines: 50,
      minLines: 10,
      fontSize: 18
    })

@KresimirJurkovic
Copy link

You can try this:

npm i ace-builds
import 'ace-builds';
import 'ace-builds/webpack-resolver';
ace.edit("editor", {
	mode: "ace/mode/html",
	theme: "ace/theme/dracula",
	maxLines: 50,
	minLines: 10,
	fontSize: 18
});
<div id="editor"></div>

This beats using CDN, because there is a possibility of hosting a project using ace editor that has no internet connection and thus cannot connect to the CDN.

@SinnerAir
Copy link

I use webpack 5.74.0 with ESM modules. Not worked ext-language_tools . Output warnings enableSnippets is reported as misspelled option name

This helped me:

import ace from 'ace-builds/src-noconflict/ace.js';

import ext from 'ace-builds/src-noconflict/ext-language_tools.js';
import extSearch from 'ace-builds/src-noconflict/ext-searchbox.js';

ace.define('ace/ext/language_tools', null, ext);
ace.define('ace/ext/searchbox', null, extSearch);

@AidanWelch
Copy link

You can try this:

npm i ace-builds
import 'ace-builds';
import 'ace-builds/webpack-resolver';
ace.edit("editor", {
	mode: "ace/mode/html",
	theme: "ace/theme/dracula",
	maxLines: 50,
	minLines: 10,
	fontSize: 18
});
<div id="editor"></div>

This relies on file-loader being installed, which is deprecated.

@nightwing
Copy link
Member

Please see https://github.com/ajaxorg/ace-samples/tree/master/samples/ace-builds-webpack for a working version of ace-builds with webpack and language-tools

For new versions of webpack use import 'ace-builds/esm-resolver' https://github.com/ajaxorg/ace-builds/blob/master/esm-resolver.js which does not use file loader.

@TimChinye
Copy link

TimChinye commented Apr 11, 2024

I'm confused, so what are we supposed to do if we loaded Ace in via cdnjs, and not webpack or other?

@jbuddha
Copy link

jbuddha commented Apr 29, 2024

Please see https://github.com/ajaxorg/ace-samples/tree/master/samples/ace-builds-webpack for a working version of ace-builds with webpack and language-tools

For new versions of webpack use import 'ace-builds/esm-resolver' https://github.com/ajaxorg/ace-builds/blob/master/esm-resolver.js which does not use file loader.

This worked for me.

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

No branches or pull requests