Webpack, включая неиспользуемый экспорт в окончательный пакет (не тряска дерева)

У меня есть настройка, в которой index.js библиотеки (основная точка входа) экспортирует все в библиотеке ... поэтому его настройка выглядит следующим образом:

export * from "./mod1"
export * from "./mod2"
// etc...

(взгляните)

Когда я импортирую 1 из экспортированных библиотек из этой точки входа, похоже, что Webpack не может встряхнуть дерево вывода. запуск webpack -p фактически включает всю библиотеку в пакет, хотя был импортирован только один экспорт. При запуске webpack (непроизводственный пакет) во всем файле отображается unused harmony export .... (167 раз), но почему они не удаляются?

У меня есть тестовая установка, показывающая эту проблему здесь: https://github.com/purtuga/webpack-bundle-test

Надеюсь, что кто-то (умнее меня :)) поможет определить, что я делаю неправильно.

/Павел


person Paul T.    schedule 03.02.2018    source источник
comment
Вы нашли лучшее решение для этого? Я столкнулся с той же проблемой.   -  person Apidcloud    schedule 22.03.2019
comment
У меня есть смысл перейти на Webpack 4, и я думаю, что у меня больше нет этой проблемы, но: я не возвращался к нему, чтобы проверить (используя тестовый проект, который я настроил). Если у меня будет время, я сделаю это и доложу здесь.   -  person Paul T.    schedule 23.03.2019
comment
Я открыл новое сообщение с моей проблемой: stackoverflow.com/questions/55320774/   -  person Apidcloud    schedule 24.03.2019
comment
Спасибо @Apidcloud. Я тоже буду следить за этим, а также поделился вашим вопросом в Твиттере, чтобы посмотреть, сможет ли более широкое сообщество взглянуть на него.   -  person Paul T.    schedule 25.03.2019


Ответы (2)


Когда вы объединяете приложение без преобразований (например, Babel) и минификации (например, UglifyJS), вы получаете: неиспользованный экспорт гармонии.

Теперь Webpack 2+ отмечает только неиспользуемый код и не экспортирует его внутри модуля. Он извлекает все и оставляет неиспользуемый код для библиотек минификации.

Для этого вы можете использовать UglifyJS с babel. UglifyJS пока не поддерживает новые языковые функции Javascript ES2015 +. Вам понадобится Babel, чтобы перенести код на ES5, а затем использовать UglifyJS для очистки неиспользуемого кода.

Вам понадобится файл .babelrc с:

Мы должны указать предустановке (в нашем случае babel-preset-env) пропустить транспиляцию модуля.

{
  "presets": [
    ["env", {
      "loose": true,
      "modules": false
    }]
  ]
}

и соответствующая конфигурация веб-пакета:

module: {
  rules: [
    { test: /\.js$/, loader: 'babel-loader' }
  ]
},

plugins: [
  new webpack.LoaderOptionsPlugin({
    minimize: true,
    debug: false
  }),
  new webpack.optimize.UglifyJsPlugin({
    compress: {
      warnings: true
    },
    output: {
      comments: false
    },
    sourceMap: false
  })
]

ИЛИ

Babili - лучший вариант, поскольку Babili удалит неиспользуемый код перед транспиляцией. Гораздо проще обнаружить неиспользуемые классы до перехода на ES5. Встряхивание дерева также будет работать для объявлений классов, а не только для функций.

Тебе понадобится:

npm install babili babili-webpack-plugin --save-dev

Используйте следующий плагин в конфигурации вашего веб-пакета, например:

plugins: [
  new BabiliPlugin()
]

Также существует оптимизированный способ использования бабили в качестве предустановки. Вы можете сослаться на их сайт, чтобы использовать его в качестве предустановки для babel-loader.

person SomberTuna    schedule 16.02.2018
comment
спасибо за ответ ... Но это не помогает. Да, я понимаю, как на самом деле происходит встряхивание дерева ... и все, что вы описали выше, верно для моего примера (взгляните на тестовое репозиторий git, которое я предоставил) - поэтому я ожидал, что мертвый код будет отброшен, когда пакет был уменьшен (webpack -p) - но это не тот случай ... Я действительно в тупике на этом ... - person Paul T.; 16.02.2018

Я клонировал ваш "webpack-bundle-test" и вот что я сделал.

  1. Папка src "common-micro-libs" скопирована из https://github.com/purtuga/common-micro-libs.
  2. Отредактировал код в mod3.js на: import { objectExtend } from "./common-micro-libs" export default mod3 = objectExtend({}, { text: "module 3" });

  3. Я запустил webpack локально и нашел 167 комментариев о "неиспользованных гармониях".

  4. С webpack -p я получил следующие результаты:  введите описание изображения здесь
  5. Код в mod3.js изменен на import objectExtend from "./common-micro-libs/jsutils/objectExtend.js" export default mod3 = objectExtend({}, { text: "module 3" });.
  6. С указанным выше изменением я смог увидеть следующее уменьшение размера пакета  введите описание изображения здесь

Я считаю, что при импорте зависимостей лучше импортировать только необходимую функцию / компонент из библиотеки, и это будет более эффективно упаковано в бандл. Я не могу объяснить, почему так, хотя я следовал тому же принципу при импорте утилит в свой проект при использовании lodash, и он отлично работает. Можете ли вы провести тесты и сообщить мне?

person SomberTuna    schedule 17.02.2018
comment
Привет, Приеш - спасибо за ответ. Некоторое время я импортировал зависимости из одного файла lib-name/src/.../, поэтому знаю, что это работает. Но я пытался сделать правую часть from короткой, используя только имя пакета библиотеки и получая оттуда именованный импорт (import { foo } from "lib-name" - и именно тогда я обнаружил эту проблему, для которой я хочу понять, почему это происходит Я не уверен, кто виноват: это webpack в том виде, в котором он определил неиспользуемые harmony импортные файлы в пакете (таким образом, Uglify не может их отбросить) или это Uglify? Спасибо за попытку - person Paul T.; 17.02.2018
comment
Вы нашли способ лучше? У меня такая же проблема: / - person Apidcloud; 22.03.2019
comment
В treehaking webpack 4 вы не можете установить свойство sideEffects в вашем package.json. Это дает подсказки компилятору webpack о мертвом коде. - person SomberTuna; 03.04.2019