Почему мой сценарий выдает «Не удается переопределить свойство: i» Ошибка только после минимизации? - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть скрипт, который добавляет методы к объекту, чтобы хранить все в одном месте.Это хорошо работает с 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 Ответ

0 голосов
/ 16 февраля 2019

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

ДляВ случае, подобном вашему, я бы обычно ожидал, что функция будет иметь вид:

Strategy.registerStrategy('strategy2', strategy2);

, а затем вы можете обобщить его и воспользоваться синтаксисом сокращений объектов ES6:

Strategy.registerStrategies({ strategy2 });

ииметь эту функцию быть

Strategy.registerStrategies = function(strats) {
  Object.keys(strats).forEach(name => {
    Strategy.registerStrategy(name, strats[name]);
  });
};
...