Почему мой сценарий выдает "Не удается переопределить свойство: i" Ошибка только после минимизации?
У меня есть сценарий, который добавляет методы к объекту, чтобы держать все в одном месте чисто. Это хорошо работает с unminified js, но как только оно минимизируется, оно ломается, и я не знаю почему. Кто-нибудь имеет опыт с этим, который может привести меня к решению? Почему мой сценарий выдает "Не удается переопределить свойство: i" Ошибка только после минимизации?
Strategy.js
const Strategy = {};
Object.defineProperty(Strategy, 'map', { value: new Map() });
Object.defineProperty(Strategy, 'registerStrategy', {
value: function registerStrategy(fn) {
if (fn.name) {
this.map.set(fn.name, fn);
return Object.defineProperty(Strategy, fn.name, { value: fn });
}
return false;
},
});
export default Strategy;
Стратегия-1.js
import Strategy from '../strategy';
export function strategy1(param) {
return param + ' this is strategy 1.';
}
Strategy.registerStrategy(strategy1);
Стратегия-2.js
import Strategy from '../strategy';
export function strategy2(param) {
return param + ' this is strategy 2.';
}
Strategy.registerStrategy(strategy2);
webpack.config.js
import path from 'path';
const webpackConfig = {
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: ['env'],
},
}],
},
],
},
mode: 'development',
watch,
devtool: 'source-map',
entry: './src/js/main.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, './dist/'),
},
};
export default webpackConfig;
Обновление на основе ответа от loganfsmyth
Strategy.js
const Strategy = {};
Object.defineProperty(Strategy, 'map', { value: new Map() });
Object.defineProperty(Strategy, 'registerStrategy', {
value: function registerStrategy(fnName, fn) {
if (fnName) {
this.map.set(fnName, fn);
return Object.defineProperty(Strategy, fnName, {
value: fn,
writable: true,
configurable: false,
});
}
return false;
},
});
Strategy.registerStrategies = (strats) => {
Object.keys(strats).forEach((name) => {
Strategy.registerStrategy(name, strats[name]);
});
};
export default Strategy;
1 ответ
Вообще полагаться на имена функций для чего-либо кроме целей отладки - плохая идея. Минификаторы и другие инструменты часто переименовывают переменные и функции для достижения своей цели - сделать код меньше. Это ведет к fn.name
возвращая другое значение, так что если вы жестко закодировали это имя в других местах, где минификатор может либо не изменить его, либо изменить его на что-то другое, ваш код сломается.
Для случая, подобного вашему, я бы вообще ожидал, что функция будет такой:
Strategy.registerStrategy('strategy2', strategy2);
и затем вы можете обобщить его и использовать синтаксис сокращений объектов ES6:
Strategy.registerStrategies({ strategy2 });
и эта функция будет
Strategy.registerStrategies = function(strats) {
Object.keys(strats).forEach(name => {
Strategy.registerStrategy(name, strats[name]);
});
};