2016-06-03 2 views
2

Я пытаюсь создать веб-приложение с помощью Webpack, и я ударил немного стены с определенной частью дизайна - надеюсь, кто-то здесь будет иметь опыт делать подобные вещи (или знать достаточно, чтобы сказать мне, что я делаю это совершенно неправильно)!Требовать набор модулей на основе константы DefinePlugin

В принципе, у нас есть приложение «Угловая панель», состоящее из «оболочки» (общий пользовательский интерфейс, службы управления сеансом и т. Д.) И набор модулей (автономные разделы приложения, которые можно подключить к оболочке). Сложный момент в том, что это приложение будет распространено среди нескольких клиентов, каждому из которых потребуется другой набор модулей, и ему потребуются несколько разные параметры конфигурации.

Я сделал некоторый прогресс с этим до сих пор с помощью DefinePlugin для загрузки в файле конфигурации JSON в качестве константы при построении времени:

const envConfig = require(`./config/${yargs.argv.env || "dev"}`); 

... 

new webpack.DefinePlugin({   
    __ENV__: Object.keys(envConfig).reduce((obj, key) => { 
     obj[key] = JSON.stringify(envConfig[key]); 
     return obj; 
    }, {}) 
}) 

Затем я попытался использовать динамический требуется включать только указанные модули, например:

__ENV__.modules.map((id) => require(`./modules/${id}/index.ts`).default) 

Это рода работали - правые модули загружаются, но Webpack не подхватывает на то, что __ENV__ никогда не будет меняться во время выполнения, поэтому бушель Сам файл ild включает в себя всех модулей, включая отключенных. Очевидно, что это увеличило бы размер файла без необходимости для клиентов, которым нужен только один модуль, поэтому я не очень доволен им.

Итак, чтобы уменьшить его до простого вопроса - есть простой способ загрузить определенный набор модулей на основе константы DefinePlugin (или есть альтернативный способ достижения того, чего я пытаюсь достичь) ? Я чувствую, что есть что-то очевидное, которого я должен упустить.

ответ

1

Вы можете настроить resolve.alias и настроить его для каждого клиента. Это даст вам такую ​​настройку, которую вы хотите.

+0

Не могу поверить, что я не думал об этом ... спасибо за помощь! –

+0

Это круто. Замечательно, что это сработало для вас. :) –

1

Я придумал достойное (?) Решение этой проблемы после принятия совета bebraw - думал, что отправлю его в качестве дополнительного ответа, если кто-нибудь столкнется с тем же вопросом или захочет реализовать что-то подобное. Я использую TypeScript, но такой же подход, вероятно, отлично работает в JavaScript с ES6 или без него.

В принципе, я теперь каталог под названием config в моем src, который содержит подкаталог для каждого клиента, например так:

config 
├── dev 
├── cust1 
└── cust2 

Каждый из них содержит info.ts файл, который экспортирует константы, такие как REST конечной точки URL-адрес:

export default { 
    name: "Company Name", 
    server: "http://localhost:8810", 
    service: "ServiceName" 
} 

И modules.ts файла, который экспортирует массив модулей для передачи в функцию загрузчика моего приложения:

import util from "../../modules/util"; 
import session from "../../modules/session"; 
import shell from "../../modules/shell"; 
import stock from "../../modules/stock"; 

export default [ 
    util, 
    session, 
    shell, 
    stock, 
]; 

Они должны быть отдельными - моя первоначальная реализация имела один файл .ts для каждой конфигурации, но это означало, что я столкнулся с циклической зависимостью, когда пытался импортировать константы из модулей.

Тогда я просто добавил resolve.alias на основе аргументов командной строки:

alias: { 
    "config": path.join(__dirname, `src/config/${yargs.argv.env || "dev"}/`) 
} 

Теперь я могу переключить, что config/info и config/modules относятся только по телефону:

webpack --env dev 
webpack --env cust1 
webpack --env cust2 

мне еще нужно посмотрите, как это работает на практике, и, возможно, усовершенствовать интерфейс для разных экспонатов, но в качестве отправной точки мне это нравится!

Смежные вопросы