How to: Use Ace editor in a Webpack project

Updated . Posted . Visible to the public.

The Ace editor Show archive.org snapshot is a great enhancement when you want users to supply some kind of code (HTML, JavaScript, Ruby, etc).
It offers syntax highlighting and some neat features like auto-indenting.

For Webpack 3+

Integrate as described in the documentation Show archive.org snapshot . For example load ace Editor like this:

  function loadAceEditor() {
    return import(/* webpackChunkName: "ace" */ 'ace-builds/src-noconflict/ace').then(() => {
      return import(/* webpackChunkName: "ace" */ 'ace-builds/webpack-resolver.js')
    })
  }

For Webpack 2 and below

Integrating it with Webpack as described in the documentation Show archive.org snapshot -- by using ace-builds and ace-builds/webpack-resolver -- failed pretty hard for Webpack 2.
The following works for Ruby on Rails with Webpacker / Webpack 2.

  1. Do not use the ace-builds NPM package, because you won't be able to load it properly. Instead, use brace:

    yarn add brace
    
  2. You can then import and use ace, mode configuration, and styles like so:

    ^

    import ace from 'brace'
    import 'brace/mode/html'
    import 'brace/theme/monokai'
        
    let editor = ace.edit(element)
    ...
    

Full-fledged example for an Unpoly compiler Show archive.org snapshot that will improve your <textarea html-editor>:

import ace from 'brace'
import 'brace/mode/html'
import 'brace/theme/monokai'

up.compiler('[html-editor]', ($element) => {
  let $editorContainer = $('<div>').insertAfter($element)
  let editor = ace.edit($editorContainer.get(0))
  let session = editor.getSession()

  editor.setOptions({
    mode: 'ace/mode/html',
    theme: 'ace/theme/monokai',
    minLines: 50,
    maxLines: 50,
    fontSize: '16px',
    wrap: true,
    useSoftTabs: true,
    tabSize: 2,
  })

  // If we enable Ace on the textarea directly, it will lose its value and never send any changes to the server.
  // Instead, we use a container element and sync any changes into the textarea.
  $element.hide()
  session.setValue($element.val())
  session.on('change', () => {
    $element.val(session.getValue())
  })

  return () => {
    editor.destroy()
  }
})
Arne Hartherz
Last edit
Judith Roth
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2018-11-23 20:16)