Дублирование имен классов после использования Webpack в рабочем режиме с Uglify keep_fnames

Я работаю над библиотекой, которая во многом зависит от Function.prototype.name (для установки ярлыков в родительском экземпляре).

class FooSection {}
class BarSection {}

class Page {
  constructor(sections) {
    for (let SectionClass of sections) {
      this[SectionClass.name] = new SectionClass(this);
    }
  }
}

let page = new Page([
  FooSection,
  BarSection
]);

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

// ...
optimization: {
  minimizer: [
    new UglifyJsPlugin( {
                          uglifyOptions: {
                            keep_fnames: true
                          }
                        } )
  ]
}

Согласно документации, это должно сохранить имена моих функций. Удивительно, но вместо этого имена дублируются, так что Page внезапно становится Page_Page (примечание: этот блок кода написан мной, но примерно так выглядит результат ):

class FooSection_FooSection{}
class BarSection_BarSection{}
class Page_Page{
  constructor(t) {
    for(let s of t){this[s.name]=new s(this)}
  }
}
let p=new Page_Page([FooSection_FooSection,BarSection_BarSection])

Это невозможно воспроизвести только с помощью UglifyJS, поэтому он должен быть где-то внутри цепочки инструментов (webpack -> uglifyjs-webpack-plugin -> uglifyjs), но я не могу понять, где. Кто-нибудь испытал это еще?

Версии следующим образом:

  • веб-пакет: 4.6.0
  • uglifyjs-webpack-плагин: 1.2.5
  • углифайс: 3.3.9

Обновление:
Судя по комментариям, такая же проблема возникает при использовании uglifier TerserPlugin.


person Moritz Friedrich    schedule 24.04.2018    source источник
comment
@Piterden, к сожалению, я так и не понял этого и в конце концов прибегнул к альтернативному подходу ... Должно быть, вам потребовалось немало времени, чтобы найти здесь эту эзотерическую проблему;)   -  person Moritz Friedrich    schedule 20.12.2018


Ответы (1)


Это довольно старая тема, но я просто поместил ее здесь для справки, так как наткнулся на ту же проблему и, наконец, выяснил причину.

Такое поведение вызвано ModuleConcatenationPlugin веб-пакета, который перемещает все модули в глобальную область. по соображениям производительности. Это может привести к конфликту имен, и, таким образом, веб-пакет переименовывает классы и добавляет к ним префикс с именами файлов/модулей.

Вы можете отключить это поведение, установив concatenateModules в false в конфигурации вашего веб-пакета.

module.exports = {
  //...
  optimization: {
    concatenateModules: false
  }
};

Поскольку это не ошибка, и вы пишете библиотеку, вероятно, не стоит полагаться на такое поведение.

person jhx    schedule 05.05.2020