#javascript #npm #webpack
#javascript #npm #webpack
Вопрос:
Я работаю над библиотекой JavaScript, и я хочу, чтобы будущие пользователи могли выбирать плагины, которые они хотят добавить в свой проект, среди основной библиотеки. У меня несколько проблем с модулями и webpack. Я пишу псевдокод, чтобы дать представление о том, как организован код.
Мой index.js для основной библиотеки выглядит следующим образом:
import ClassA from "./classA";
import ClassB from "./classB";
export default class MyLib {
.....
}
export { ClassA, ClassB }
Я могу легко вывести библиотеку с помощью webpack:
output: {
path: ...
filename: 'mylib.min.js',
library: "MyLib",
libraryTarget: "umd"
}
Чтобы иметь возможность выбирать, какие плагины добавлять, я создаю разные пакеты npm (по одному для каждого плагина), добавляю MyLib в качестве внешней зависимости, а затем выполняю:
import {ClassA, ClassB} from "MyLib";
class PluginA extends ClassB {
constructor() {
this.test = new ClassA();
}
}
Это работает отлично, но при «компиляции» PluginA webpack будет включать MyLib в конечный js-файл для PluginA. Если я захочу включить несколько плагинов, в конечном итоге в коде будет несколько копий основной библиотеки.
Моя конечная цель — организовать код таким образом, чтобы его можно было легко установить с помощью следующих команд npm, не дублируя код повсюду:
npm install MyLib
npm install MyLib-PluginA
npm install MyLib-PluginB
Конечно, одним из очевидных решений было бы не использовать webpack для плагинов, но я бы хотел сохранить эту опцию в качестве последнего ресурса на случай, если больше ничего не сработает.
Спасибо!
Ответ №1:
Я бы не рекомендовал использовать webpack для создания ваших плагинов / библиотеки. Скорее, я бы позволил потребителю библиотеки выбирать свой собственный пакет. Вашим лучшим шагом для библиотеки должно быть просто преобразование (при необходимости) любого промежуточного кода, такого как JS с поддержкой babel или TypeScript, во что-то, что может быть безопасно require
обработано node.
Кроме того, каждый плагин должен иметь MyLib
как peerDependency
вместо обычной зависимости. Это гарантирует, что MyLib
это не будет вложено внутрь плагина node_modules
и, таким образом, позволит избежать объединения дубликатов. Плагины могли бы дополнительно использоваться MyLib
как devDependency
для модульных тестов, но важно то, что это никогда не бывает обычным dependency
.
Комментарии:
1. пока не уверен, стоит ли использовать просто babel вместо webpack, но предложение о peerDependecies очень важно! большое спасибо!
2. Это определенно правильный путь. В конце концов, когда вы устанавливаете зависимости вашего проекта, представьте, что некоторые из них использовали Webpack, другие — Rollup, некоторые — Parcel и т.д. Попытка настроить все это была бы кошмаром. Лучше всего просто предоставить свою библиотеку в стандартном формате (возможно, с использованием транспилятора, если вы хотите настроить таргетинг на более новую версию JS, чем стандартная) и позволить потребителю библиотек (т. Е. приложению конечного пользователя) решить, использовать Webpack или альтернативу. В конце концов, это то, что уже делает большинство других библиотек!
Ответ №2:
Покопавшись в документации webpack, я нашел решение, которое использует внешние компоненты webpack.
Из документации webpack:
Параметр конфигурации externals предоставляет способ исключения зависимостей из выходных пакетов.
Я только что добавил следующие строки в конфигурацию webpack для плагина:
module.exports = {
...,
externals: {
mylib: {
commonjs: 'MyLib',
commonjs2: 'MyLib',
amd: 'MyLib',
root: 'MyLib'
}
}
};
Документация Webpack:https://webpack.js.org/configuration/externals
Надеюсь, это поможет другим.