Spec-Zone.ru › Phoenix

Phoenix.LiveView.ColocatedJS

Исходный код

Специальный HEEx :type, который во время компиляции извлекает любой код JavaScript из совместно расположенного тега <script>.

Примечание: для использования ColocatedJS необходим Phoenix 1.8 или новее.

Совместно расположенный JavaScript — это более обобщённая версия Phoenix.LiveView.ColocatedHook. Фактически совместно расположенные хуки построены поверх ColocatedJS.

С помощью ColocatedJS можно определять любой код JavaScript (веб-компоненты, глобальные обработчики событий и т. д.), которому не обязательно требуются возможности хуков. Например:

<script :type={Phoenix.LiveView.ColocatedJS} name="MyWebComponent">
  export default class MyWebComponent extends HTMLElement {
    connectedCallback() {
      this.innerHTML = "Hello, world!";
    }
  }
</script>

Затем в файле app.js его можно импортировать следующим образом:

import colocated from "phoenix-colocated/my_app";
customElements.define("my-web-component", colocated.MyWebComponent);

В этом примере фактически не нужно добавлять специальный код веб-компонента в файл app.js, поскольку можно также напрямую вызвать customElements.define в совместно расположенном JavaScript. Однако этот пример показывает, как получить доступ к экспортированным значениям в своём бандле.

Примечание о зависимостях и umbrella-проектах

Для каждого приложения, использующего совместно расположенный JavaScript, в папке phoenix-colocated создаётся отдельный каталог. Это обеспечивает чёткое разделение хуков и кода зависимостей, а также приложений внутри umbrella-проектов.

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

Внутреннее устройство

При компиляции шаблона совместно расположенный JavaScript извлекается в специальную папку внутри Mix.Project.build_path(), которая называется phoenix-colocated. Её можно настроить, как описано ниже, но важно, чтобы это был каталог, не отслеживаемый системой контроля версий, поскольку исходным кодом служат компоненты. Кроме того, каталог используется несколькими приложениями (это также относится к приложениям в umbrella-проектах), поэтому обычно он должен быть общим, а не предназначенным для одного приложения.

Структура каталога совместно расположенного JS:

_build/$MIX_ENV/phoenix-colocated/
_build/$MIX_ENV/phoenix-colocated/my_app/
_build/$MIX_ENV/phoenix-colocated/my_app/index.js
_build/$MIX_ENV/phoenix-colocated/my_app/MyAppWeb.DemoLive/line_HASH.js
_build/$MIX_ENV/phoenix-colocated/my_dependency/MyDependency.Module/line_HASH.js
...

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

Чтобы использовать совместно расположенный JS из app.js, необходимо настроить сборщик так, чтобы он разрешал поиск в папке phoenix-colocated. В новых приложениях Phoenix эта настройка уже добавлена в конфигурацию esbuild в файле config.exs:

config :esbuild,
  ...
  my_app: [
    args:
      ~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
    cd: Path.expand("../assets", __DIR__),
    env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
  ]

Здесь важна переменная среды NODE_PATH, которая указывает esbuild искать пакеты также в папке deps, а также Mix.Project.build_path(), которая указывает на _build/$MIX_ENV. Если используется другой сборщик, его нужно настроить соответствующим образом. Если настроить NODE_PATH невозможно, можно также изменить папку, в которую LiveView записывает совместно расположенный JavaScript, задав параметр :target_directory в файле config.exs:

config :phoenix_live_view, :colocated_assets,
  target_directory: Path.expand("../assets/node_modules/phoenix-colocated", __DIR__)

В качестве альтернативы можно создать символическую ссылку на папку phoenix-colocated внутри папки node_modules.

Совет

Если удалить или изменить содержимое папки :target_directory, используйте mix clean --all и mix compile, чтобы заново сгенерировать весь совместно расположенный JavaScript.

Предупреждение!

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

Импорт в совместно расположенном JS

Файлы совместно расположенного JS полностью обрабатываются сборщиком. В приложениях Phoenix это обычно esbuild. Поскольку совместно расположенный JS извлекается в папку за пределами стандартной папки assets, при импорте других файлов из совместно расположенного JS нужно соблюдать особую осторожность:

def sha256(assigns) do
  ~H"""
  <div id="sha-256" phx-hook=".Sha256">Hello World</div>
  <script :type={Phoenix.LiveView.ColocatedHook} name=".Sha256">
    import { sha256 } from "my-example-sha256-library"
    import { reverse } from "@/vendor/vendored-file"
    export default {
      mounted() {
        this.el.innerHTML = sha256(reverse(this.el.innerHTML))
      }
    }
  </script>
  """
end

Зависимости из node_modules должны работать без дополнительной настройки, но нельзя просто указать папку assets/vendor с помощью относительного пути. Вместо этого сборщик нужно настроить так, чтобы он обрабатывал псевдоним вида @ и разрешал его в локальную папку assets. В конфигурации esbuild для новых приложений Phoenix 1.8 эта настройка задана по умолчанию с помощью параметра alias в esbuild; это можно увидеть во фрагменте конфигурации выше (--alias=@=.).

Если расположение node_modules — не assets/node_modules и не node_modules, возможно, потребуется настроить параметр :node_modules_path:

# mix.exs
def project do
  [
    ...
    compilers: [:phoenix_live_view] ++ Mix.compilers(),
    phoenix_live_view: [colocated_js: [node_modules_path: "assets/node_modules"]],
    ...
  ]
end

В этом примере показано поведение по умолчанию.

Примечание: в отличие от :target_directory, :node_modules_path — это параметр конкретного проекта, который нужно задать в файле mix.exs.

Параметры

Совместно расположенный JavaScript можно настроить с помощью атрибутов тега <script>. Поддерживаются следующие атрибуты:

  • name — имя, под которым экспорт по умолчанию скрипта доступен при импорте манифеста. Если атрибут не указан, файл будет импортирован только ради побочных эффектов.

  • key — пользовательский ключ для экспорта. Он используется Phoenix.LiveView.ColocatedHook, чтобы экспортировать все хуки под именованным экспортом hooks (export { ... as hooks }). Например, для каждого совместно расположенного скрипта, определяющего веб-компонент, можно задать значение web_components, а затем импортировать их все как import { web_components } from "phoenix-colocated/my_app". По умолчанию используется значение :default, то есть экспорт будет доступен под экспортом default манифеста. Значение должно быть допустимым идентификатором JavaScript. Если этот атрибут задан, также требуется name.

  • extension — пользовательское расширение для извлечённого файла. По умолчанию используется js.

  • manifest — пользовательский файл манифеста вместо стандартного index.js. Например, web_components.ts. Если изменить манифест, потребуется также изменить пути импорта JavaScript.

Пакет Hex Предпросмотр Hex Просмотреть llms.txt Скачать версию ePub

Создано с помощью ExDoc (v0.40.3) для Elixir programming language

© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix-live-view.hexdocs.pm/Phoenix.LiveView.ColocatedJS.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API