Корневой каталог для модуля node

У меня есть довольно стандартный node модуль с использованием babel для перевода нашего кода, который затем выводится в папку "lib". package.json указывает "main" на "lib/index.js", чтобы люди могли просто require('my-module')

Однако, если у меня есть подкаталог (например, my-module/server), то, когда они используют мой модуль, они должны сделать require('my-module/lib/server'). Я видел, как люди запускали шаги сборки, которые будут копировать package.json в lib, но это просто кажется мне взломанным и неправильным. Есть ли способ в npm указать основной каталог, в котором любой require() моего модуля будет запускаться в этом каталоге? Тогда я могу просто потребовать от пользователя ( "my-module/server" ) без части lib...

Ответы

Ответ 1

Я думаю, что лучшим решением является то, что у вас есть основной index.js, и на нем все подмодули, чтобы вы могли сделать что-то вроде require('your-module').server

Ответ 2

Это сложно, не видя структуру вашей папки, но вы можете:

  • используйте module.exports = для экспорта выходов babel
  • symlink другие файлы в каталог

package.json

{ "main": "lib" }

Библиотека/index.js

module.exports = require('./path-to-transpiled-code.js');

// Now also export all the other stuff in this folder dynamically

fs.readdirSync(DIRECTORY_TO_EXPORT, function (err, files) {
  if (err) { throw err; }
  files.forEach(function (file) {
    if (file !== 'index.js') {
      fs.symlinkSync(path.join(__dirname, file), path.join(DIRECTORY_TO_EXPORT, file));
    }
  })
});

Ответ 3

Если я правильно понял ваш вопрос, вам нужно всего лишь указать основной путь к модулю внутри package.json.

{
   "main": lib/index.js 
}

Где index.js - ваш основной файл вашего модуля. Для получения дополнительной информации проверьте документацию npm здесь

Ответ 4

Предположим, что у вас есть пакет my-module, а внутри есть подпапка my-submodule. Ваш файл my-module/package.json будет содержать следующую строку:

{
    ...,
    "main": "lib/index.js",
    ...
}

Это позволит вашему пакету потребоваться строка

var myMod = require('my-module');

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

{
    "main": "lib/index.js"
}

После этого вы можете использовать простой синтаксис require:

var mySubMod = require("my-module/my-submodule");

Ответ 5

У вас есть несколько вариантов того, как достичь своей цели.

Экспортировать все это в lib/index.js

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

  • + Полный контроль над тем, что является частью публичного API и что считается "private"
  • + Отличная игра с спецификациями модулей ES2015
  • - Не соответствует вашему требованию требовать компонент (server) с помощью прямого вызова require() с указанием пути к серверному модулю

Пример:

'use strict'

// this is whatever is the primary export of your module - be it a
// function, object or anything else which can have other properties
// assigned to it
const main = require('./main')
const server = require('./server')

module.exports = main
module.exports.server = server
// ...

Применение:

'use strict'

const mymodule = require('my-module')
const server = require('my-module').server
const { server } = require('my-module')

import { server } from 'my-module'

Создайте файлы входа для компонентов в корневом каталоге

Вы можете создавать отдельные файлы для каждого из компонентов, которые вы хотели бы представить как часть вашего общедоступного API в корневой папке вашего модуля.

  • + Удовлетворяет вашему требованию возможность требовать компонент через определенный путь
  • - Слегка более сложная структура требует дополнительного файла для каждого публичного компонента
  • - Не работает с модулями ES2015 (вы должны использовать полный путь к компоненту и не можете использовать синтаксис деструкции)

Пример структуры папок:

my-module
├── lib
│   ├── index.js
│   └── server.js
└── server.js

Файл my-module/server.js будет указывать только на фактическую реализацию:

'use strict'

module.exports = require('./lib/server')

Общие примечания

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