Отложить загрузку JavaScript в темах и компонентах

Благодаря @david у нас появился очень чистый паттерн для «жадной» загрузки JavaScript в темах.

Это означает, что вы просто помещаете файлы *.js.es6 в директорию javascripts, и всё работает точно так же, как с плагинами — это великолепно.

Например, вот как теперь создаётся инициализатор, имеющий 100% паритет с плагинами:

  • Создайте файл с именем /javascripts/discourse/initializers/my-init.js.es6
import { withPluginApi } from "discourse/lib/plugin-api";

function initialize(api) {
  // инициализация через api здесь
}

export default {
  name: "discourse-otp",

  initialize() {
    withPluginApi("0.8.28", initialize);
  }
};

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

Однако в некоторых случаях нам может потребоваться опционально поставлять JS-нагрузку.

Например, предположим, что мы декорируем посты, но только те, которые содержат очень специфичный Markdown. Нет смысла загружать 100 КБ библиотеку, пока мы не уверены, что будем её использовать.

Я обошёл это в своём компоненте, следуя этому изящному изменению:

С помощью:

import loadScript from "discourse/lib/load-script";

function generateOtp($elem) {
  loadScript(settings.theme_uploads.jsotp).then(() => {
     // здесь код
  });
}

Это означало:

  1. Мне нужно было добавить .js в «разрешённые расширения темы».
  2. Мне нужно было добавить обход CSP для конкретного актива в «список источников скриптов политики безопасности контента».
  3. Мне нужно было указать имя актива в моём файле about.json.

Для автора компонента темы это слишком много препятствий, ведь у вас нет шансов в игре по распространению, если требуется такой уровень ниндзя.

Я думаю, чтобы сделать это удобным, у нас есть два варианта на выбор:

  1. Мы можем научить систему автоматически применять CSP к .js-активам в активных темах и по умолчанию разрешать темам загружать .js.

  2. Мы можем перейти к чему-то вроде javascript_cache, которое используется для JS тем без отложенной загрузки.

Я склоняюсь к варианту 1, потому что добавление .js в разрешённые расширения темы кажется тривиальным, а автоматическое применение CSP не должно быть невозможным.

@pmusaraj / @Johani / @Osama, есть ли у вас какие-либо мысли по этому поводу?

Возможность ссылаться на загрузки тем в JS — отличное дополнение! :100:

Это кажется мне вполне логичным, ведь всё, что можно сделать в .js-файле, уже можно реализовать в файлах папки javascripts темы. Поэтому я не вижу никакого вреда в том, чтобы по умолчанию разрешать темам загружать .js-файлы.

Возобновляю обсуждение, так как осталось только настроить CSP для разрешения загрузки js-файлов тем. Файлы js уже давно разрешены по умолчанию для загрузки в темы.

Если загрузка js-файлов тем не будет блокироваться CSP, то такие компоненты, как Image Annotator - Allows you to annotate images in the previewer, не будут нуждаться в загрузке своих зависимостей на главной странице (~170 КБ в формате gzip). Например, этому компоненту понадобится загружать эти зависимости только при открытии редактора. Кроме того, анонимным пользователям они никогда не понадобятся.

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

Слово «позволит» взято в кавычки, потому что можно использовать их в виде blob-объектов, но гораздо удобнее иметь их в отдельных файлах, а не возиться с JavaScript-кодом внутри строки.

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

Другого чистого способа обойти ограничения CSP нет: обслуживание файлов воркеров с того же домена решает эту огромную проблему.

Обратите внимание… это уже выпущено :confetti_ball: