Модули JavaScript и плагины для веб-приложений - PullRequest
5 голосов
/ 31 мая 2019

Я поддерживаю (PHP) веб-приложение, которое состоит из ядра приложения и нескольких плагинов, которые можно добавить в ядро. Каждый экземпляр приложения может иметь собственный набор плагинов, в зависимости от назначения экземпляра. Ядро приложения и плагины разрабатываются в своих соответствующих репозиториях.

Если плагин установлен, он внедряет свой JavaScript в шаблоны внешнего интерфейса. Это может выглядеть следующим образом:

<script src="core.min.js"></script>
<script src="plugin-1.min.js"></script>
<script src="plugin-2.min.js"></script>

Порядок важен, потому что плагин может использовать ресурсы ядра или другой плагин, который был добавлен ранее. В настоящее время это совместное использование ресурсов реализовано в виде единой переменной в глобальной области, которая собирает ресурсы, которые «экспортируются» ядром и плагинами. В плагине к ресурсу можно получить доступ и использовать его через эту глобальную переменную:

var resource = myapp.core.resource;

Теперь на мой вопрос: Есть ли способ реализовать архитектуру ядра / плагина, описанную выше, с помощью модулей ES6 (с помощью Webpack или чего-то подобного)? Я хотел бы использовать более современный способ разработки JavaScript или даже использовать TypeScript, но я не знаю, можно ли это сделать или как это сделать. Я понимаю, что возможно было бы импортировать некоторые ресурсы из основного JavaScript в плагине, но не будет ли это также скомпилировано в файл JavaScript плагина? Это дублирует код.


Пояснение:

Базовое приложение и плагины разрабатываются в отдельных репозиториях, например как это:

core/src/main.js
plugin-1/src/main.js
plugin-2/src/main.js

Код для каждого хранилища встроен в пакет PHP. Конечный экземпляр приложения состоит из ядра приложения и нескольких плагинов, которые устанавливаются как пакеты PHP. JavaScript не перестраивается при установке пакета PHP.

Я мог бы импортировать некоторые ресурсы из ядра приложения в виде плагина, например:

import {resource} from '../../../core/src/main'

Однако это дублирует код ядра приложения, поскольку ядро ​​и плагин создаются отдельно.

Я спрашиваю, возможно ли создать конфигурацию сборки, которая «знает» об общих переменных между ядром и плагинами. Например, если я определю класс Main в ядре, он может быть встроен в глобальную переменную myapp.core.Main. Если я затем импортирую Main в один из плагинов, вместо него может быть решено использовать переменную myapp.core.Main. Вот как работает текущая реализация, но все это определяется вручную. Возможно, есть более разумный путь с современными инструментами сборки, такими как Webpack.

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Основной смысл упаковки ваших модулей в bundle.js заключается в том, что, хотя они преломляются в src, они все еще объединяются в один пакетный файл (иногда вы делите его на несколько по разным причинам).Webpack знает, что не нужно дублировать код, и это является его основой.Я приведу пример:

src:

root/src
root/src/main.js
root/src/plugin1.js
root/src/plugin2.js
root/src/utils/util1.js

, поэтому предположим, что main является точкой входа в ваше приложение.Он использует plugin1 и plugin2, и оба из них используют util1.

main.js:

import plugin1 from './plugin1'
import plugin2 from './plugin2'
//... Do stuff

plugin1.js:

import util1 from './utils/util1.js';

export default const plugin1 = ()=>{
  //.. Do stuff also with util1
}

plugin2.js:

import util1 from './utils/util1.js';

export default const plugin2 = ()=>{
  //.. Do stuff also with util1
}

util1.js:

export default const util1 = ()=>{
  //.. Do util things
}

Когда вы используете веб-пакет для связывания этого кода, он будет знать, не повторять код.Он также будет знать, что делать много качественных вещей, если вы настроите их правильно (и, честно говоря, по умолчанию это довольно хорошо с самого начала).Результат попадет в комплект и в любой сгенерированный файл index.html (я рекомендую этот метод, поскольку вы можете начать хэшировать имена источников и избежать проблем с кэшированием при обновлении.) Ручного.

dist:

root/dist/index.html
root/dist/bundle.js

index.html :

<!-- Would / Should have a script tag for the bundle. -->
<script src="bundle.js">

bundle.js:

// Here you would get a minified/uglified etc. version of your JS which is optimized according to the config. You will not get code repetition.

0 голосов
/ 10 июня 2019

Учитывая, что у вас есть отдельные репозитории для ядра и плагинов, я бы рекомендовал создавать пакеты для ядра и каждого плагина.
Итак, в ядре у вас будет package.json с "name": "@scope/core", в плагине 1 "name": "@scope/plugin1" e.t.c.
Затем вы соберете все пакеты, например, с помощью веб-пакета и опубликуете результат или поместите его куда-нибудь.

После этого вы можете использовать модули es6 с оператором import.

Допустим, в плагине2 вам нужно использовать основные функции, а также что-то из плагина1.

// package.json for plugin2
{
  "name": "@scope/plugin2",
  "dependencies": {
    "@scope/core": "1.0.0",
    "@scope/plugin1": "1.0.0"
  }
}

// some javascript in plugin2
import {coreResource} from '@scope/core';
import {p1Resource} from '@scope/plugin1';

Если вы не хотите публиковать свой код, вы можете поместить его где-нибудь локально и ссылаться на него в зависимостях типа

// package.json for plugin2
{
  "name": "@scope/plugin2",
  "dependencies": {
    "@scope/core": "file:/path/to/core",
    "@scope/plugin1": "file:/path/to/plugin1"
  }
}
...