https://github.com/gilest/phoenix_importmap
Use ESM with importmap to efficiently serve JavaScript without transpiling or bundling.
https://github.com/gilest/phoenix_importmap
assets esmodules importmaps javascript phoenix
Last synced: about 1 month ago
JSON representation
Use ESM with importmap to efficiently serve JavaScript without transpiling or bundling.
- Host: GitHub
- URL: https://github.com/gilest/phoenix_importmap
- Owner: gilest
- License: mit
- Created: 2024-12-09T23:59:19.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-03-10T11:07:19.000Z (2 months ago)
- Last Synced: 2025-03-27T17:35:53.965Z (about 2 months ago)
- Topics: assets, esmodules, importmaps, javascript, phoenix
- Language: Elixir
- Homepage: https://hexdocs.pm/phoenix_importmap
- Size: 55.7 KB
- Stars: 31
- Watchers: 2
- Forks: 1
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Phoenix Importmap
[](https://github.com/gilest/phoenix_importmap/actions/workflows/ci.yml)
Use [ES/JS Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) with [importmap](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) to efficiently serve JavaScript without transpiling or bundling.
With this approach you'll ship many small JavaScript files instead of one big JavaScript file.
Import maps are [supported natively](https://caniuse.com/?search=importmap) in all major, modern browsers.
## Installation
The package can be installed by adding `phoenix_importmap` to your list of dependencies in mix.exs:
```elixir
def deps do
[
{:phoenix_importmap, "~> 0.4.0"}
]
end
```If you are using the esbuild package you may also remove it, along with its configuration.
In `config/dev.exs` add the asset watcher to your `Endpoint` configuration:
```elixir
watchers: [
assets: {PhoenixImportmap, :copy_and_watch, [~w(/assets)]},
]
```In `config/config.exs` add an importmap. The following is a good start for a conventional Phoenix app:
```elixir
config :phoenix_importmap, :importmap, %{
app: "/assets/js/app.js",
topbar: "/assets/vendor/topbar.js",
phoenix_html: "/deps/phoenix_html/priv/static/phoenix_html.js",
phoenix: "/deps/phoenix/priv/static/phoenix.mjs",
phoenix_live_view: "/deps/phoenix_live_view/priv/static/phoenix_live_view.esm.js"
}
```If you are using topbar, replace the relative topbar import in `assets/app/app.js` with a module specifier. This asset will be resolved by our importmap:
```js
import topbar from 'topbar';
```You'll also need to replace the contents of `assets/vendor/topbar.js` with a wrapped version that supports ESM, like this [from jsDelivr](https://cdn.jsdelivr.net/npm/[email protected]/topbar.js/+esm).
In `lib//components/layouts/root.html.heex` replace the `app.js` `` tag.
Be sure to use your own project's module name in place of `YourAppWeb`.
```html
<script type="importmap">
<%= PhoenixImportmap.importmap(YourAppWeb.Endpoint) %>import 'app';
```
Finally, in `mix.exs` update your assets aliases to replace esbuild with this library:
```
"assets.setup": ["tailwind.install --if-missing"],
"assets.build": ["tailwind default", "phoenix_importmap.copy"],
"assets.deploy": ["tailwind default --minify", "phoenix_importmap.copy", "phx.digest"]
```The [phoenix_importmap_example repository](https://github.com/gilest/phoenix_importmap_example) demonstrates configuring a newly-generated Phoenix app.
## Importmap configuration
- `:importmap` - Map representing your assets. This is used to copy and watch files, and resolve public paths in `PhoenixImportmap.importmap()`
## Asset path configuration
The defaults should work out of the box with a conventional Phoenix application. There are two global configuration options available.
- `:copy_destination_path` - Where your mapped assets will be copied to. Defaults to `/priv/static/assets` which is the default path for to serve assets from.
- `:public_asset_path_prefix` - The public path from which your assets are served. Defaults to `/priv/static` which is the default path for `Plug.Static` to serve `/` at.