#javascript #ecmascript-6 #es6-modules
#javascript #ecmascript-6 #es6-модули
Вопрос:
Учитывая стороннюю библиотеку, которая экспортирует функцию и использует эту функцию в своей внутренней логике — есть ли какой-либо способ переопределить эту функцию? Например:
third-party.js
export function a() {
console.log('a');
}
export function b() {
a();
}
my-module.js
import * as tp from 'third-party';
//Re-define, something like this
Object.defineProperty(tp, 'a', { writable: true, value: () => console.log('c')});
//Call b and get the re-define function called
tp.b(); //Expected output: 'c'
Несколько основных моментов:
- Мне это нужно не для тестирования, а для производства (да, я знаю, что это был бы грязный взлом)
- Да, я знаю, что импорт представляет собой просмотры только для чтения в реальном времени, я ищу обходной путь для преодоления этого ограничения
- Нет, я не могу изменить код сторонней библиотеки
- Мне нужно мое изменение, чтобы фактически изменить логику третьей стороны. Я хотел бы вызвать функцию, которая вызывает,
a
а неa
саму себя.
Комментарии:
1. Нет, это невозможно сделать без исправления кода (что может быть возможно с помощью скрипта), если
a()
ссылка на вызов относится к локальнойa
переменной.2. В какой среде это выполняется? Вы используете пользовательский загрузчик, пакет или что-то в этомроде?
3. Нет, это чистая среда узла. Однако у меня есть определенная степень гибкости для моего скрипта. Это означает, что я мог бы объединить ее (чего я сейчас не делаю).
4. Вы можете попробовать поэкспериментировать с github.com/elastic/require-in-the-middle
Ответ №1:
Экспортируемый модуль доступен только для чтения. Итак, вы не можете этого сделать.
delete tp.a;
tp.a = () => {
console.log('c')
}
tp.a() // 'c'
tp.b() // You'll still get 'a'
// it's because, b is calling exported function a
Если вы хотите, tp.b()
чтобы значение было переопределено, тогда вы не экспортируете их, а вызываете экземпляр. В вашем примере кода просто a
не b
экспортируйте. Но поскольку вы пытаетесь переопределить ее из сторонней библиотеки. Это невозможно сделать.
Но если вы настаиваете на их использовании, тогда вы должны переопределить обе функции.
const obj = {...tp}
obj.a = () => {
console.log('c')
}
obj.b() // 'a'
obj.b = () => {
obj.a()
}
obj.b() // 'c'
Комментарии:
1. Я попробовал это, и это не сработало. Проблема здесь заключается в экспорте, а не в присвоении объекту. Вопрос конкретно касается экспорта.
2. Я внес небольшую модификацию , чтобы соответствовать вопросу, и это не работает. Я бы хотел вызвать,
b
а неa
. Извините, но ваш ответ не отвечает на вопрос.3. Обновил мой ответ. То, что вы ищете, невозможно.