Rahat Ahmed
Rahat Ahmed

Reputation: 2180

How does require('atom') work?

Atom exposes some global APIs that you can access from require('atom')

How does this functionally work? Atom packages don't explicitly have atom as a dependency, yet they can still do this. Moreover, how can I do this in my own Electron application with my own global package?

Upvotes: 2

Views: 293

Answers (1)

Rahat Ahmed
Rahat Ahmed

Reputation: 2180

I've gone through and analyzed Atom's source myself to determine how this happens, and this is what I've come up with.

Atom packages are required using the normal node require. However, according to the apm readme:

The other major difference is that Atom packages are installed to ~/.atom/packages instead of a local node_modules folder...

So the require('atom') package isn't retrieved from a parent node_modules directory like normal node modules. Instead, Atom overrides the module loader to change the behavior a bit.

More specifically, they override Module._resolveFilename like so:

Module = require 'module'

Module._resolveFilename = (relativePath, parentModule) ->
  resolvedPath = resolveModulePath(relativePath, parentModule)
  resolvedPath ?= resolveFilePath(relativePath, parentModule)
  resolvedPath ? originalResolveFilename(relativePath, parentModule)

It attempts to resolve the path of a module with its own module cache logic before defaulting to normal behavior. This is done for a couple reasons that I can tell.

  1. It lets them hardcode the path of builtin modules like 'atom', even though the normal behavior would never have found it.
  2. It prevents loading package dependencies twice when packages have the same dependency with compatible versions. If packageA loads [email protected] and later packageB attempts to load lodash@>=3, then Atom steps in and gives packageB the lodash that packageA loaded.

Upvotes: 1

Related Questions