Встроенный модуль util
узла предлагает метод проверки того, является ли модуль допустимым Объект пространства имен модуля . Но его использование ограничено только модулями, загруженными с помощью операторов import
и , имеющих принудительное имя модуля.
От узла util
docs
/* The two lines below are assumed (Not in original docs) */
import util from 'util' // load built-in module via import (works)
const util = require('util') // load built-in module via require (CommonJS, also works)
import * as ns from './a.js'; // import module with "coerced" namespace
let checkType = util.types.isModuleNamespaceObject(ns);
console.log(checkType) // Returns true
С .isModuleNamespaceObject(<module>)
, который является рабочим узлом API, предлагает.
Однако , следующие примеры НЕ работают
1. import
модуль как экспорт в пространство имен из файла (локального)
// Assume util module is already imported/required
import { ns } from './a.js'; // Assumes "a.js" has an export "ns"
let checkType = util.types.isModuleNamespaceObject(ns);
console.log(checkType) // Returns false
2. import
модуль как экспорт по умолчанию из файла (локальный)
// Assume util module is already imported/required
import ns from './a.js'; // Assumes "a.js" has default export
let checkType = util.types.isModuleNamespaceObject(ns);
console.log(checkType) // Returns false
3. require
модуль как экспорт в пространство имен из файла (локального)
// Assume util module is already imported/required
const { ns } = require('./a.js'); // Assumes "a.js" exports "ns"
let checkType = util.types.isModuleNamespaceObject(ns);
console.log(checkType) // Returns false
4. require
модуль как экспорт по умолчанию из файла (локальный)
// Assume util module is already imported/required
const ns = require('./a.js'); // Assumes "a.js" provides default export using
// "module.exports", otherwise ".default" would
// need to be appended to the require statement
// had "a.js" provided default export using
// "export default".
// Also assumes no external module or config exists
// that messes with Node's module resolution (i.e. esm)
let checkType = util.types.isModuleNamespaceObject(ns);
console.log(checkType) // Returns false
Существует ли существующий способ ввода модулей проверки, который удовлетворяет каждому приведенному выше нерабочему примеру?
и (при условии, что на первый вопрос можно ответить «да» и как)
Существует ли способ указать модули проверки как встроенные, локальные или внешние?
Где:
встроенный относится к модулю, доступному во время выполнения узла (например, «os», «http», «net» и c.)
local относится к модулю, загруженному через файл (т.е. «./a.js")
external относится к модулю, в котором для загрузки сначала требуется удаленная загрузка через реестр (например, «loda sh», «bluebird», «moment» и т. Д. c .)
Где я сейчас пытаюсь понять это ...
Мне совсем не повезло с вопросом 1.
- Собственный объект
module
узла ( также доступен как import/require
) предлагает ключ id
, но после загрузки модуля его значением является путь к файлу, из которого он был загружен. module.exports
и module.children
также не очень помогают. - Собственный объект узла
require
предлагает .cache
, но это считается ненадежным, и метод .resolve
, но он должен вызываться вместе с модуль require
выписка. Тем не менее, возвращаемое значение - это путь к файлу, в который экспортируется модуль. - Собственный объект
process
узла предлагает отличный метод .binding(<module_name>)
, который будет работать, но для этого требуется <module_name>
может быть задано как typeof <module_name> === 'string'
.
На вопрос 2 нетрудно найти работоспособное решение.
- встроено типы модулей могут быть проверены с использованием возвращаемого значения из
process.builtIns
, которое является array
встроенными модулями в виде строк, доступных Node во время выполнения. - локальные типы модулей могут быть проверил их путь экспорта. Если он не находится в папке
node_modules
, не указан в package.json
проекта как dep или devDep и находится непосредственно в кодовой базе проекта, то можно с уверенностью предположить, что это local . - внешние типы модулей могут быть проверены с использованием того же logi c, что и проверка локальных типов, очевидно, только обратное должно быть истинным.
Возможные решения:
Возможность анализировать строку, используемую в операторе require/import
, а затем возвращать значение process.bind()
.
Где я Я застрял в попытке понять, есть ли способ go синтаксического анализа строки, используемой в операторе require
, на который ссылается через переменную?
Итак:
const { magicParser } = require('magicParser') // import/require the parser
const foo = require('bar') // require external module
const baz = require('./qux') // require local module
const os = require('os') // require built-in module
let externalName = magicParser(foo) // Returns 'bar'
let localName = magicParser(baz) // Returns './qux'
let builtInName = magicParser(os) // Returns 'os'
// Then for solving the last bit, some psuedo logic like...
const pkg = require('path/to/project/root/package.json')
// External type...
for (let [k,v] of Object.entries(externalName)) {
// code that checks key/prop values in pacakge.json for matching name....
}
// Local type...
require('fs').exist(`${process.cwd()}/${localName}) // true/false
// Built-in type...
process.builtIns.filter(name => name === builtInName) // true/false