Blog
How CodeMirror v6 setup command handles CLI arguments?

How CodeMirror v6 setup command handles CLI arguments?

In this article, we analyse how the CodeMirror v6 development environment setup script processes CLI arguments. This function is used in setting up development environment for Codemirror v6 as mentioned in their repository.

CodeMirror does not use Monorepo setup, instead it clones the packages that are repositories on their own as part of install command.

Wait what install command? In the CodeMirror v6 repository,
README.md has this below information about setting up the dev env.

CodeMirror Readme:

This is the central repository for CodeMirror. It holds the bug tracker and development scripts.

If you want to use CodeMirror, install the separate packages from npm, and ignore the contents of this repository. If you want to develop on CodeMirror, this repository provides scripts to install and work with the various packages.

To get started, make sure you are running node.js version 16. After cloning the repository, run

node bin/cm.js install

To clone the packages that make up the system, install dependencies, and build the packages. At any time you can rebuild packages, either by running npm run prepare in their subdirectory, or all at once with

node bin/cm.js build

Developing is best done by setting up

npm run dev

Which starts a server that automatically rebuilds the packages when their code changes and exposes a dev server on port 8090 running the demo and browser tests.

install CLI argument

When you run the command node bin/cm.js install, this executes the script bin/cm.js that runs a function named start(), found at the bottom of bin/cm.js

cm.js has the install function at line 81, but does it mean you could just down the function you want to execute in a script as a CLI argument and it would not get called? No, I don’t think so. install would be an argument passed in via CLI and start function does some processing. Below is the start function code picked from CodeMirror v6 source code.

function start() {
  let command = process.argv[2]
  if (command && !["install", "--help"].includes(command)) assertInstalled()
  let args = process.argv.slice(3)
  let cmdFn = {
    packages: listPackages,
    status,
    build,
    devserver,
    release,
    unreleased,
    install,
    clean,
    commit,
    push,
    grep,
    "build-readme": buildReadme,
    test,
    run: runCmd,
    "--help": () => help(0)
  }[command]
  if (!cmdFn || cmdFn.length > args.length) help(1)
  new Promise(r => r(cmdFn.apply(null, args))).catch(e => error(e))
}

Argument is accessed via let command = process.argv[2], this means command now has the value “install”. Then next step is assert if the project has been already installed using the below shown check:

if (command && !["install", " - help"].includes(command)) assertInstalled()

If you passed in any additional arguments after install, they get asssigned to args variable and then cmdFn is decided using an object as shown below:

let args = process.argv.slice(3)
let cmdFn = {
 packages: listPackages,
 status,
 build,
 devserver,
 release,
 unreleased,
 install,
 clean,
 commit,
 push,
 grep,
 "build-readme": buildReadme,
 test,
 run: runCmd,
 " - help": () => help(0)
}[command]

Since command value is install and cmdFn object has “install” key/value pair, value here would be the install function itself.

if (!cmdFn || cmdFn.length > args.length) help(1)
new Promise(r => r(cmdFn.apply(null, args))).catch(e => error(e))

If there’s no function available for the argument you passed, help is called that basically shows a list of supported functions.

and then install is called with apply. Read more about apply in JavaScript.

About us:

At Thinkthroo, we study large open source projects and provide architectural guides. We have developed reusable Components, built with tailwind, that you can use in your project. We offer Next.js, React and Node development services.

Book a meeting with us to discuss your project.

References:

  1. https://github.com/codemirror/dev/blob/main/bin/cm.js#L90

  2. https://github.com/codemirror/dev/blob/main/bin/cm.js#L81

  3. https://github.com/codemirror/dev/blob/main/bin/cm.js#L13

  4. https://github.com/codemirror/dev/tree/main

  5. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply