m m -
d e v

newsite.. .

workinprogress!

broken,unfinishedbutlookifyoulike.. .

expectfrequentchanges!

Vanilla JS

6 minute read

My favourite flavour... although I don't mind a cone and a Flake.

Toolchain

I enjoy using plain/vanilla JS where possible. For my own projects I try to avoid the sprawl and long build times of NPM.

I do like to split my code up into separate modules though, and to be able to benefit from bundling/minification etc, for which I use esbuild. I also want to be able to use SCSS and JSDoc for type annotations. So I do allow myself some minimal tooling (the cone and Flake).

My setup looks like this…

esbuild - Download a build

  • JS bundler
    Combine separate modules into a single JS file, minifying/compressing if required
  • Tree shaker
    Avoid bloat by making sure only those modules/functions which are used get added

I use esbuild for most JS projects, so I installed a standalone build which can be run from anywhere — but it can also be installed using npm or other methods.

SASS - How to Install SASS

  • Compiler and bundler
    Converts SASS/SCSS files into CSS

JSDoc - Documentation

  • Automated documentation creation
    HTML docs for your methods, classes and variables will be created based on your code comments
  • Type annotations
    Comments in your code can tell JSDoc which data types your code expects

Type annotations you provide (in specially-formatted comments) will be used to automatically create detailed documentation for your project.

Docs are created as HTML files, with lots of clickable cross-references. The files can be styled based on a templating system and CSS styling.

Lots of modern editors/IDEs will also use your type annotations to provide type hints and draw attention to potential problems eg if you try to pass an argument of the wrong type you’ll get a warning.

Example of Project Setup Using Tmux/Vim

I usually write a simple bash script for most projects. I’ll run this script when I want to start a session of working on a specific project.

Below is an example build script (for my ‘Pipe Dream’ game) which does the following:

  1. Enters the project directory
  2. Uses tmux to open a few window panes/splits:
    • esbuild watching for changes to JS
    • SASS watching for changes to CSS
    • JSDoc watching the src directory (in reality I’d often skip this and run it manually on-demand, as it can be slow)
    • git status, pane left open for commits etc
    • A simple Python server so I can test the app in a browser
  3. Opens a vim session with the relevant source files ready for editing
#!/bin/bash

# Open a JS project using esbuild, SASS and vim

work_dir="$HOME"/pipe-dream/

'tmux' \
    new-window -c "$work_dir" "esbuild src/main.js --outfile=www/js/pipe-dream.js --target=es6 --bundle --minify --sourcemap --global-name=PIPEDREAM --format=iife --watch" \; \
    split-window -c "$work_dir" "sass --watch src/scss/:www/css/" \; \
    split-window -c "$work_dir" "jsdoc src/ -c jsdoc.config" \; \
    split-window -c "$work_dir" "git status; bash -i" \; \
    split-window -c "$work_dir" "python -m http.server --directory www/" \; \
    select-layout even-vertical \; \
    new-window -c "$work_dir" "vim -S vim.Session" \; \

Vim Configuration

I’m one of those Vim people. People say its codebase is bloated but in use it always feels crisp and fast to me. Because of the way you manipulate text objects and leap around the page it somehow feels efficient on low-powered/slow devices, and works particularly well with e-ink devices.

Some people argue that they’re faster while using Vim than they are in other code editors. I’m not sure if I’m faster (I might be), but I’m from the school of thought that if your bottleneck when writing code is your typing speed, that might not be a good thing.

More importantly for me, I like the way Vim makes you think about text, as beautifully described in this classic stackoverflow answer ‘Your problem with Vim is that you don’t grok vi’.

I don’t like my coding environment to be too noisy or intrusive, but there are some powerful IDE features available nowadays and I don’t want to cut off my nose to spite my face.

Below is some info on some Vim plugins I use to help with JS development.

coc-nvim - Code of Conquer project repo

Although the ’nvim’ stands for Neovim (the popular Vim fork), COC also works very well in modern versions of normal Vim. This plugin allows VSCode-type IDE features, being based on the Language Server Protocol standard.

Very simply, a language server is a tool which understands a specific language, and can be used by your editor/IDE to analyse and give feedback on your code as you write it. It can do things like:

  • Syntax highlighting
  • Code completion
  • Draw attention to errors and give warnings about code
  • Help when refactoring code

COC isn’t a language server itself but it allows you to install and maintain whichever servers you need for the languages you use.

For example the language server I use for JS is coc-tsserver. The ’ts’ stands for TypeScript but it works very well with standard JS too. Along with the benefits mentioned above, this language server allows you to use type-checking, like TypeScript but without the compilation step. It also provides documentation and hints on using standard built-in JS methods.

You annotate your code by providing special comments in JSDoc syntax. When these comments/annotations are present, COC and the language server give you lots of hints while writing code, and warn you if you try to provide arguments of the wrong type.

Here is an example (from the official docs) showing what the JSDoc syntax looks like:

/** Class representing a point. */
class Point {
    /**
     * Create a point.
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     */
    constructor(x, y) {
        // ...
    }

    /**
     * Get the x value.
     * @return {number} The x value.
     */
    getX() {
        // ...
    }

    /**
     * Get the y value.
     * @return {number} The y value.
     */
    getY() {
        // ...
    }

    /**
     * Convert a string containing two comma-separated numbers into a point.
     * @param {string} str - The string containing two comma-separated numbers.
     * @return {Point} A Point object.
     */
    static fromString(str) {
        // ...
    }
}

Sometimes the help is a little noisy though…

I love the functionality, but for me it’s a bit over-eager, eg if I’m half-way through typing a word I don’t need a popup telling me the word doesn’t exist.

coc-nvim does also provide a small symbol at the start of each line where it detects an error or wants to warn about something. So I like to leave the symbol visible, but hide the info popups by default. I add a keyboard shortcut so I can show/hide the explanation of the error/warning when I want to.

To stop the popups:

// In ~/.vim/coc-settings.json

{
  ...
  "diagnostic.enableMessage": "jump",
  ...
}

To add the show/hide keyboard shortcuts to Vim:

" In ~/.vimrc

nmap <silent> gh <Plug>(coc-float-hide)
nmap <silent> gl <Plug>(coc-diagnostic-info)

Prettier

This opinionated code formatter formats your code according to some fairly strict rules and has few configurable options (ie it’s their way or the highway).

I think most people find at least some of the rules disagreeable, but the point of this kind of tool is that it does a ‘decent, not perfect’ job, but provides a standard for formatting and removes the need for discussing, disagreement and wasted time.

I found it a little annoying at first but then got over myself and prefer now to use it whenever possible.