Сделать плагин листовки доступным как импорт или напрямую из заголовка html - PullRequest
1 голос
/ 07 февраля 2020

Я создал плагин для листовки (npm package ), и я хочу, чтобы он был доступен либо как импорт ES6, либо как скрипт в HTML заголовок.

Желаемое поведение

Например, я хочу, чтобы оба этих варианта были возможны:

// As an npm package
import 'leaflet-arrowheads'
// From your HTML header
<script type="text/javascript" src="./leaflet.arrowheads.js"></sript>

Мой плагин имеет зависимость, leaflet geometryutil . Таким образом, код выглядит примерно так:

import 'leaflet.geometryutil'

L.Polyline.include({
   ...my plugin code here
})

L.LayerGroup.include({
   ... a bit more code here
})

Это работает при использовании модулей ES6, где leaflet.geometryutil устанавливается как зависимость моего пакета. Но при использовании в заголовке файла HTML это, очевидно, не сработает. (Конечно, любой, кто пытается это сделать, должен будет иметь сценарий leaflet.geometryutil в своем заголовке где-то перед моим плагином - это ясно объяснено в моем файле readme для github.)

Моя текущая стратегия состояла в том, чтобы просто иметь 2 ветви github - один с оператором импорта и один без . Но я пытаюсь понять, что я могу сделать, чтобы объединить эти две ветви и получить один фрагмент кода, который работает в обеих ситуациях. Мои две идеи на данный момент таковы:

Использовать динамический c import

Импортировать модуль geometryutil, только если он еще не присутствует в пространстве имен Leaflet:

if(!L.GeometryUtil){
   import('leaflet-geometryutil')
      .then( GeometryUtil => {
         console.log('all good')
      })
      .catch( err => throw(err) )
}

L.Polyline.include({ ..plugin code... })

Это не работает, потому что обещание import не возвращается до тех пор, пока не выполнится мой код L.Polyline.include, поэтому любое использование GeometryUtil внутри моего кода возвращает GeometryUtil не определено. Это работает в сценарии заголовка HTML, где у автора есть тег сценария GeometryUtil перед тегом моего плагина, потому что оператор if возвращает false и обещание импорта не выполняется.

Есть ли другой способ написать динамический оператор импорта c так, чтобы код плагина выполнялся только после обещания импорта, а затем был должным образом импортирован в другой модуль, который создает пользователь плагина?

Используйте инструмент сборки, такой как webpack

Кажется, я смогу достичь sh моей цели с помощью webpack. Основываясь на документации веб-пакета о авторских библиотеках , я мог бы сделать что-то вроде

output: {
    path: './dist',
    filename: 'leaflet.arrowheads.js',
    library: 'arrowheads',
    libraryTarget:'umd'
}

Но я не совсем уверен, как точно настроить вывод. Документы объясняют, что это предоставит глобальную переменную arrowheads, но это не то, что нужно. Плагин, который я создаю, на самом деле не предоставляет новую переменную, а скорее добавляет к существующей библиотеке листовок.

Как я могу настроить webpack.config для сборки плагина так, чтобы он 1: доступен как импорт (который сам импортирует свою зависимость leaflet.geometryutil), а также 2: доступен как тег сценария из заголовка HTML, который автоматически изменяет объект листовки L как задумано?

Есть ли третий вариант, о котором я не думаю?

Спасибо за чтение.

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Это обычная головоломка для библиотек внешнего интерфейса.

Это правда, что веб-пакет может предложить некоторые решения, такие же, как для Rollup (который является движком сборки, используемым Leaflet).

Что касается import Dynami c, он прекрасно работает, когда вы создаете приложение, и импорт Dynami c управляется вашим механизмом сборки, но я не буду полагаться на него при написании библиотеки, для которой вы не знаете, если среда / Механизм сборки, используемый проектом-потребителем, будет поддерживать его.

В вашем случае вы даже можете избавить себя от необходимости использовать механизм сборки и необходимость играть, пытаясь правильно его настроить.

все, вы правильно заметили (и следовали соглашению Leaflet), что большинство плагинов Leaflet ничего не экспортируют в глобальную область или в импортер, но имеют побочный эффект добавления некоторого поведения в пространство имен Leaflet L. Таким образом, при использовании средства импорта движка сборки нам просто нужно сделать:

import "leaflet";
import "leaflet-arrowheads"; // nothing in curly braces

Поэтому вашей библиотеке даже не нужно ничего экспортировать (т. Е. Вы можете избавиться от export default до вашего L.Polyline.include).

Теперь вы можете начать искать возможное решение: иметь общий файл для импорта и сценария HTML, содержащий только ваш код L.Polyline.include; у вас есть отдельный файл записи импорта (то есть то, на что вы ссылаетесь в package.json/main, который импортирует ваши зависимости и ваш общий файл. Кстати, вы даже можете импортировать Leaflet в этот файл!

пакет. json

{
   "main": "index.js" // npm convention, not even needed if your file is named "index.js"
}

index. js

import "leaflet";
import "leaflet.geometryutil";
import "./src/leaflet-arrowheads.js"; // common file

src / leaflet-arrowheads. js

L.Polyline.include() // etc.

Затем у вас есть один общий файл для обслуживания, нет необходимости использовать отдельную ветку, все публикуется в npm, т.е. бесплатные CDN (например, unpkg, cdn js и jsDelivr) смогут напрямую обслуживайте ваш общий файл, готовый к HTML использованию сценария!

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

Но для сценария HTML вам все равно придется импортировать зависимость «вручную», то есть вы все равно должны сообщать пользователям вашего библиотека, чтобы включить зависимость в го eir HTML scripts.

Этого можно избежать, связав зависимость с вашим плагином, как правило, введя теперь движок сборки. В этом случае обычной практикой является создание нескольких версий: 1 со всеми связанными зависимостями, так что пользователю вашей библиотеки требуется только 1 импорт; 1 только с вашим кодом, позволяя пользователю вашей библиотеки управлять импортом зависимостей (обычно так, чтобы они имели контроль над версией, а также могли использовать их directclty без дублирования кода и т. Д. c.). Для этого указанный выше индексный файл также используется в качестве точки входа в сборку. Затем вы должны указать, что не включать в комплект: исключить Leaflet и, возможно, Leaflet-geometryUtil.

0 голосов
/ 07 февраля 2020

Я делаю следующее для своего сайта ... После конечного тега body включите следующую строку <?php include_once("files_java/_java_loader.php");?> Файл _java_loader. php выглядит следующим образом ...

<?php
$script_Array = explode("/", $_SERVER['SCRIPT_FILENAME']);
$script_Name  = $script_Array[count($script_Array)-1];

// Load module specific scripts for each module
switch ($script_Name) {
    case 'maps.php':
    case 'map_all.php':
    case 'neighbors.php':
    case 'view_large_map.php':
         ?><script type="text/javascript" src="<?php echo SERVER_PATH; ?>files_java/mapper.js"></script><?php echo PHP_EOL;
         ?><script type="text/javascript" src="<?php echo SERVER_PATH; ?>files_java/initMaps.js"></script><?php echo PHP_EOL;
         ?><script type="text/javascript" src="<?php echo SERVER_PATH; ?>files_java/downloadXML.js"></script><?php echo PHP_EOL;
         ?><script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAXPvUkWaeVfdwQjtlBZwlZND0-0bcYpZs" defer></script><?php echo PHP_EOL;
    break;
}?>

Таким образом Вы можете установить определенные c файлы для загрузки для определенных c модулей. Над оператором $ script_array включены все ссылки javascript, необходимые для всех модулей.

Я использую аналогичную структуру и для CSS загрузок.

jdadwilson

...