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.
- 
Do not use the ace-buildsNPM package, because you won't be able to load it properly. Instead, usebrace:yarn add brace
- 
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()
  }
})