Я хочу сделать свой модуль ES импортируемым в обоих следующих стилях:
import * as mylib from "./mylib.mjs";
import mylib from "./mylib.mjs";
Затем я написал mylib.mjs в следующем стиле:
export function foo(){
}
export function bar(){
}
export function baz(){
}
// ... and many export functions...(1)
export default {foo, bar, baz, /* ... and many function names...(2) */};
Но мне всегда приходится беспокоиться о том, что некоторые имена отсутствуют в export default(2). Если добавляется новый export functions(1), мне придется добавить его также в function names(2). Я часто об этом забываю.
В CommonJS использование exports делает это более разумным. Есть ли какая-либо переменная, эквивалентная exports в модуле ES?
exports.foo=function () {
};
exports.bar=function () {
};
exports.baz=function () {
};
exports.default=exports;// No need to change here when function export is added.
То, что вы пытаетесь сделать, для меня - это запах кода, а для меня - указание на код низкого качества, написанный не-js-программистом. ИМХО правильный ответ - не делать этого
Почему все отрицательные голоса? Целесообразно это или нет, это актуальный вопрос, и люди могут делать то, что хотят.
использование import mylib from "./mylib.mjs" вместо import * as mylib from "./mylib.mjs" выглядит нехорошо, сбивает с толку, DRY/SSOT в некоторой степени нарушен
Я бы сказал, что импорт пространства имен (import * as) — это антишаблон. Почему, потому что модули es могут импортировать модули cjs, а узел пытается определить именованный экспорт , но этот процесс не идеален, поэтому для лучшей совместимости рекомендуется использовать подход к импорту по умолчанию. Например, namespace.foo может выдать ссылочную ошибку, если foo не удалось обнаружить с помощью эвристики. Руководство по стилю airbnb также не рекомендует этого делать. Лучше быть конкретным и просто использовать именованный экспорт.
Иногда вам нужен экспорт default, например, реакция отложенной загрузки, но я бы вообще держался от них подальше и полагался на встряхивание деревьев от сборщиков и т. д. и постоянное использование импорта пространства имен только создает потенциальную путаницу и, возможно, раздутый граф модуля, по моему мнению.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я бы не советовал этого делать, так как считаю, что файлы стволов — это антишаблон, и лучше иметь один способ загрузки ваших модулей, но что-то, что вы могли бы сделать, чтобы приблизиться к тому, что вы хотите, — это организовать свой проект следующим образом: этот:
.
└── src/
├── mylib/
│ └── mod.mjs
├── mylib.mjs
└── consumer.mjs
mylib/mod.mjs
export function foo(){
}
export function bar(){
}
export function baz(){
}
mylib.mjs
export * from './mylib/mod.mjs'
export * as default from './mylib/mod.mjs'
потребитель.mjs
import * as mylibNs from './mylib.mjs'
import mylib from './mylib.mjs'
Для управления экспортом требуется дополнительный файл, но вам не придется обновлять экспортированные имена в нескольких местах.
Конечно, если вас устраивают циклические ссылки в ваших модулях, вы можете иметь только один файл вроде этого:
mylib.mjs
export function foo() {
}
export function bar() {
}
export function baz() {
}
export * as default from './mylib.mjs'
Оно будет использоваться так же, как и раньше, но свойство default будет ссылкой на сам модуль, т. е. mylib.default === mylib.
Это было протестировано с использованием Node.js v20.12.0.
«Я хочу, чтобы мой ES-модуль можно было импортировать в обоих следующих стилях» — у вас есть для этого веская причина? Кажется, это намного хуже, чем просто остановиться на
import * as mylib.