DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Edited on

How CodeMirror v6 dev setup retrieves packages without a monorepo

In the OSS community, it is quite common to come across monorepo projects where the workspaces and packages are all in a single repository. CodeMirror has a different style to the way packages are managed, each package that is used is a repository on its own. In this article, we analyse what these packages are that CodeMirror uses and how they are installed when you want to setup CodeMirror v6 locally to contribute.

bin/packages.js

Before we analyse the install function, let’s first understand the variours packages that make up the CodeMirror. You

will find these packages listed in bin/packages.js file

Image description

These below are the core packages:

exports.core = [
 "state",
 "view",
 "language",
 "commands",
 "search",
 "autocomplete",
 "lint",
 "collab",
 "language-data",
 "codemirror",
]
Enter fullscreen mode Exit fullscreen mode

These below are the non-core packages.

exports.nonCore = [
 "lang-javascript",
 "lang-java",
 "lang-json",
 "lang-cpp",
 "lang-php",
 "lang-python",
 "lang-go",
 "lang-css",
 "lang-sass",
 "lang-html",
 "lang-sql",
 "lang-rust",
 "lang-xml",
 "lang-markdown",
 "lang-lezer",
 "lang-wast",
 "lang-angular",
 "lang-vue",
 "lang-liquid",
 "lang-less",
 "lang-yaml",
 "legacy-modes",
 "theme-one-dark",
 "merge"
]
Enter fullscreen mode Exit fullscreen mode

You will find repositories in the CodeMirror organisation for all these packages shown above. There is no single repository containing all these packages like in a monorepo, instead you have all these repositories that make up the CodeMirror.

exports.core and exports.nonCore

You will find that these packages are accessed via a function named loadPackages.

Image description

You might be wondering what exports.all here is in the above image, at line 42. It is interesting how the concat is made on exports.core and exports.nonCore and this you have all these packages merged into one array and assigned to exports.all.

exports.loadPackages

let packages = exports.all.map(n => new Pkg(n))
Enter fullscreen mode Exit fullscreen mode

Using map on exports.all, new Pkg class is instantiated using the Pkg class that’s shown below:

class Pkg {
 constructor(name) {
 this.name = name
 this.dir = join(__dirname, "..", name)
 this.main = null
 if (name != "legacy-modes" && fs.existsSync(this.dir)) {
 let files = fs.readdirSync(join(this.dir, "src")).filter(f => /^[^.]+\.ts$/.test(f))
 let main = files.length == 1 ? files[0] : files.includes("index.ts") ? "index.ts"
 : files.includes(name.replace(/^(theme-|lang-)/, "") + ".ts") ? name.replace(/^(theme-|lang-)/, "") + ".ts" : null
 if (!main) throw new Error("Couldn't find a main script for " + name)
 this.main = join(this.dir, "src", main)
 }
 }
}
Enter fullscreen mode Exit fullscreen mode

It technically sets name, dir and main.

let packageNames = Object.create(null)
for (let p of packages) packageNames[p.name] = p
Enter fullscreen mode Exit fullscreen mode

Image description

Object.create(null) creates an empty object, that’s fancy way of creating a obj that would otherwise be just obj = {} and finally below is the return statement.

return {
  packages, 
  packageNames, 
  buildPackages: packages.filter(p => p.main)
}
Enter fullscreen mode Exit fullscreen mode

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on an interesting project. Send me an email at ramu.narasinga@gmail.com

My Github - https://github.com/ramu-narasinga
My website - https://ramunarasinga.com
My Youtube channel - https://www.youtube.com/@thinkthroo
Learning platform - https://thinkthroo.com
Codebase Architecture - https://app.thinkthroo.com/architecture
Best practices - https://app.thinkthroo.com/best-practices
Production-grade projects - https://app.thinkthroo.com/production-grade-projects

References

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

  2. https://github.com/codemirror/dev/blob/main/bin/packages.js

  3. https://github.com/orgs/codemirror/repositories

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay