Как работает require ("атом")?


Atom предоставляет некоторые глобальные API, к которым можно получить доступ из require('atom')

Как это функционально работает? Пакеты Atom явно не имеют Atom в качестве зависимости, но они все еще могут это сделать. Более того, как я могу сделать это в моем собственном электронном приложении с моим собственным глобальным пакетом?

1 2

1 ответ:

Я сам исследовал и проанализировал источник атома, чтобы определить, как это происходит, и вот что я придумал.

Атом пакетов необходимо использовать обычный узел требует. Однако, согласноapm readme:

Другим существенным отличием является то, что пакеты Atom устанавливаются на ~/.atom / packages вместо локальной папки node_modules...

Таким образом, пакет require('atom') не извлекается из родительского каталога node_modules, как обычно модули узлов. Вместо этого Atom переопределяет загрузчик модуля, чтобы немного изменить его поведение.

Более конкретно, они переопределяют Module._resolveFilename Вот так:

Module = require 'module'

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

Он пытается решить путь модуля с помощью собственной логики кэша модуля, прежде чем перейти к нормальному поведению. Это делается по нескольким причинам, которые я могу сказать.

    Это позволяет им жестко закодировать путь встроенных модулей, таких как 'atom', Даже если нормальное поведение никогда бы его не обнаружило.
  1. это предотвращает двойную загрузку зависимостей пакетов, если пакеты имеют одинаковую зависимость с совместимыми версиями. Если packageA загружает лодаш@4.x. x и позже packageB пытается загрузить lodash@>=3, затем Atom вмешивается и дает packageB lodash, который загрузил packageA.