These are notes on trying to develop a front-end editor text editor, at this point, using ProseMirror.

Setting up a JavaScript development environment

ProseMirror is set up as a bunch of separate building blocks which we'll put together from different pieces using our own glue code. The example code makes use of lots of import statements.

node, npm, and yarn seem to be the way to handle these things, so let's install those things. node is a JavaScript runtime that provides some I/O for letting it do things on the local machine. Yarn is a JavaScript package manager.

brew install node yarn

To use yarn within a project, we'll create a new directory and then run:

yarn init

Then we can add our dependencies, like the various ProseMirror modules, using yarn without the global modifier, e.g.:

yarn add prosemirror-view

However, in order to actually be able to use our imported dependencies in JavaScript, we will have to use something like webpack to compile the code together. webpack will probably also let us do things like minify the code or otherwise put it in good shape for deployment. So:

yarn global add webpack

We can run webpack without configuration, but let's be more explicit and create a webpack.config.js file in the root of the project:

const path = require('path')

module.exports = {
  mode: 'development', // Compiles with development settings
  entry: './src/index.js', // This is the default value, added to be explicit
  output: { // This is the default value, added to be explicit
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  devtool: 'inline-source-map', // Compile with source maps
  resolve: {
    modules: [ // Specifies where to look for modules
      path.resolve('src'),
      'node_modules' // default location for yarn to install stuff
    ]
  }
};

We could then run webpack to compile our main.js file from the index.js every time, and then use something like python -m SimpleHTTPServer to serve up our ./dist/index.html page, but running webpack could get to be tedious.

Instead, webpack-dev-server can help us here:

yarn add webpack-cli webpack-dev-server

We'll also update the configuration to use this development server:

const path = require('path')

module.exports = {
  mode: 'development', // Compiles with development settings
  entry: './src/index.js', // This is the default value, added to be explicit
  output: { // This is the default value, added to be explicit
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  devtool: 'inline-source-map', // Compile with source maps
  resolve: {
    modules: [ // Specifies where to look for modules
      path.resolve('src'),
      'node_modules' // default location for yarn to install stuff
    ]
  },
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};

Because we left out the global here, the webpack-dev-server is installed only locally in the project, and therefore is run by:

node_modules/.bin/webpack-dev-server

This will start a local web server for testing and will automatically recompile the code whenever it detects a change, and also cause the web page to automatically reload.

To get Emacs lsp-mode working with JavaScript, we'll need the typescript-language-server:

yarn global add typescript-language-server

The Emacs code for setting up JavaScript looks like:

(use-package js2-mode
  :config
  (flycheck-mode)
  (setq js-indent-level 2)
  (require 'lsp)
  (add-hook 'js-mode-hook #'lsp)
  (add-hook 'js-mode-hook 'js2-minor-mode)
  )