Кажется, что есть несколько ловушек при расшатывании пакетов ESM. Первый улов заключается в том, что встряхивание деревьев работает только в производственном процессе, а второй - в том, что ваш package.json
должен содержать свойство sideEffects: false
. К сожалению, в процессе разработки покачивание дерева по-прежнему импортирует всю библиотеку для получения названного экспорта. Нажмите здесь дополнительную информацию о встряхивании дерева веб-пакетов.
Например (в разработке): импортировать снимок экрана exmaple
В приведенном выше примере я импортирую именованный экспорт с именем defaultLayoutCommands
; тем не менее, он по-прежнему показывает, что вся библиотека была импортирована, хотя webpack использует файл esm
. Однако, если я отделяю файл и импортирую его напрямую, он показывает меньший размер импорта. В производстве этот должен встряхнуть дерево, импортировать defaultLayoutCommands
и быть похожим на второй пример импорта. Тем не менее, тряска деревьев работает только с веб-пакетом И ESM.
При работе с CJS / UMD / AMD тряска деревьев не будет работать. Вместо этого вам придется объединить все ваши экспорты в один класс / объект (например, exports
объект). Затем, используя деструктуризацию ES6, вы можете выполнить этот метод.
Например, loda sh имеет все функции в одном файле, например:
function throttle(func, wait, options) {
var leading = true,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
'leading': leading,
'maxWait': wait,
'trailing': trailing
});
}
И затем присоединяет Функция в качестве метода для объекта:
lodash.add = add;
lodash.attempt = attempt;
lodash.camelCase = camelCase;
...
lodash.throttle = throttle;
lodash.thru = thru;
lodash.toArray = toArray;
...etc
И затем с помощью IIFE экспортируется объект lodash
. Приятно то, что вам может потребоваться несколько именованных импортов одновременно:
const { get, debounce, isEmpty } = require("lodash");
Недостатком является то, что вам требуется весь объект loda sh. Таким образом, чтобы обойти это, у них есть отдельные файлы (и / или npm пакеты !!!), чтобы ограничить импорт только тем, что нужно. Итак, они включили дополнительные файлы в папку пакета root:
...js
get.js
debounce.js
isEmpty.js
...js
Однако недостатком этого является то, что теперь у вас есть три импорта:
const get = require("lodash/get");
const debounce = require("lodash/debounce");
const isEmpty = require("lodash/isEmpty");
Но! У вас будет в целом меньший размер импорта ... однако размер пакета больше! Чтобы смягчить это, они разделили некоторые популярные методы на свои отдельные пакеты: loda sh .get , l oda sh .debounce и loda sh .isEmpty !
Итак, если подвести итог, если вы не планируете использовать CJS / UMD / AMD (как это делает loda sh), то тряска деревьев будет работать как ожидается в production при использовании webpack и ESM пакетов в клиенте . Однако, если вы включаете дополнительные сборки для большей совместимости, вам придется создать массив конфигураций свертки с разными inputs
и разными outputs
.
Например:
const resolutions = {
globals: {
react: "React",
"react-is": "reactIs",
},
exports: "named",
};
export default [
{
input: "./src/index.js", // this transforms the entire source
output: [
{
file: pkg.main,
format: "cjs",
...resolutions,
},
{
file: pkg.fallback,
format: "umd",
name: "My-Example-Library",
...resolutions,
},
{
file: pkg.module,
format: "esm",
...resolutions,
},
],
...etc
},
{
input: "./src/components/example.js", // this transforms just an "example.js" file and ouputs to a "dist/example.[build].js" file
output: [
{
file: "dist/example.cjs.js,
format: "cjs",
...resolutions,
},
{
file: dist/example.umd.js,
format: "umd",
name: "My-Example",
...resolutions,
},
],
...etc
}
]
Более подробную информацию о вариантах использования для различных сборок можно найти здесь .