mirror of
https://github.com/woutdp/live_svelte
synced 2026-05-24 09:28:21 +00:00
update installer and documentation
This commit is contained in:
parent
27d5540d69
commit
90a25b8205
8 changed files with 233 additions and 20 deletions
15
README.md
15
README.md
|
|
@ -81,6 +81,8 @@ Make sure you have it installed in production too. You might be using `node` in
|
|||
|
||||
You can make sure you have `node` installed by running `node --version` in your project directory.
|
||||
|
||||
You can also use **Bun** instead of Node.js/npm for installing dependencies and running Vite (see [Installation](#installation)); production SSR still uses Node.js.
|
||||
|
||||
If you don't want SSR, you can disable it by not setting `NodeJS.Supervisor` in `application.ex`. More on that in the [SSR](#ssr-server-side-rendering) section of this document.
|
||||
|
||||
## Installation
|
||||
|
|
@ -91,7 +93,7 @@ LiveSvelte uses [Vite](https://vite.dev/) for building and [phoenix_vite](https:
|
|||
|
||||
### Option A — Igniter installer (recommended)
|
||||
|
||||
Requires Phoenix 1.8+ and Node.js 19+.
|
||||
Requires Phoenix 1.8+ and Node.js 19+ (or Bun for package management and builds).
|
||||
|
||||
#### New project
|
||||
|
||||
|
|
@ -142,11 +144,12 @@ With phoenix_vite, the layout uses `PhoenixVite.Components.assets` and the endpo
|
|||
|
||||
Visit `http://localhost:4000/svelte_demo` to confirm the demo Svelte component is working.
|
||||
|
||||
Add `--bun` to use Bun instead of npm/npx:
|
||||
#### Using Bun
|
||||
|
||||
```bash
|
||||
mix igniter.install live_svelte --bun
|
||||
```
|
||||
Use the `--bun` flag to use Bun instead of npm/npx:
|
||||
|
||||
- **Existing project:** `mix igniter.install live_svelte --bun`
|
||||
- **New project:** `mix igniter.new my_app --with phx.new --install live_svelte --bun`
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -154,6 +157,8 @@ mix igniter.install live_svelte --bun
|
|||
|
||||
Use this if you prefer not to use Igniter, or need full control over the configuration.
|
||||
|
||||
To use **Bun** instead of npm when installing manually, add the `bun` dependency, set `config :phoenix_vite, PhoenixVite.Bun, ...`, and use `phoenix_vite.bun` in mix aliases and `PhoenixVite.Bun` in the Vite watcher. See the [Installation guide](https://hexdocs.pm/live_svelte/installation.html) for details.
|
||||
|
||||
**1.** Add dependencies to `mix.exs`:
|
||||
|
||||
```elixir
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Deploying a LiveSvelte application requires Node.js on the server for SSR (serve
|
|||
|
||||
## Requirements
|
||||
|
||||
- **Node.js 19+** on the production server (for `LiveSvelte.SSR.NodeJS`)
|
||||
- **Node.js 19+** on the production server (for `LiveSvelte.SSR.NodeJS`). If you use Bun for local builds, the production server still needs Node.js 19+ for SSR (the SSR bundle is run by Node.js).
|
||||
- Standard Phoenix/Elixir deployment tooling (releases, Docker, etc.)
|
||||
|
||||
## Build Steps
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ LiveSvelte uses [Vite](https://vitejs.dev/) for both client and SSR builds, repl
|
|||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 19+** — required for SSR (server-side rendering)
|
||||
- **Node.js 19+ or Bun** — for package management and Vite builds. Production SSR (when using `LiveSvelte.SSR.NodeJS`) still requires Node.js 19+ on the server.
|
||||
- **Elixir 1.17+**
|
||||
- **Phoenix 1.8+** — required for the Igniter installer
|
||||
- **Igniter** — the installation scaffolding tool
|
||||
|
|
@ -31,11 +31,14 @@ For a **new** project with LiveSvelte pre-installed:
|
|||
mix igniter.new my_app --with phx.new --install live_svelte
|
||||
```
|
||||
|
||||
Use the `--bun` flag to use `bun` instead of `npm`:
|
||||
#### Using Bun
|
||||
|
||||
```bash
|
||||
mix igniter.install live_svelte --bun
|
||||
```
|
||||
To use **Bun** instead of Node.js/npm for package management and Vite:
|
||||
|
||||
- **Existing project:** `mix igniter.install live_svelte --bun`
|
||||
- **New project:** `mix igniter.new my_app --with phx.new --install live_svelte --bun`
|
||||
|
||||
After install, `mix assets.setup` and `mix assets.build` use Bun (e.g. `bun install`, phoenix_vite's Bun task) instead of npm.
|
||||
|
||||
### Step 3: Install JS dependencies and build
|
||||
|
||||
|
|
@ -54,7 +57,7 @@ Running `mix igniter.install live_svelte` makes the following changes to your pr
|
|||
**`package.json`** (at project root) — the installer moves it from `assets/` and adds:
|
||||
- `live_svelte`, `phoenix_vite: "file:./deps/phoenix_vite"` (dev), and Svelte-related deps
|
||||
|
||||
**`config/config.exs`** — adds `config :phoenix_vite, PhoenixVite.Npm, ...`
|
||||
**`config/config.exs`** — adds `config :phoenix_vite, PhoenixVite.Npm, ...` (when using `--bun`, the installer configures `PhoenixVite.Bun` and Bun-based aliases instead).
|
||||
|
||||
**`assets/vite.config.mjs`** — adds the Svelte plugin, `liveSveltePlugin`, and `ssr: { noExternal: ... }`. A single config is used for both client and SSR builds (no separate `vite.ssr.config.js`); the SSR build is run via `phoenix_vite.npm vite build --ssr js/server.js --outDir ../priv/svelte`.
|
||||
|
||||
|
|
@ -143,6 +146,19 @@ If you must install manually (e.g. Phoenix < 1.8), the overall steps mirror the
|
|||
7. Configure SSR in `config/`
|
||||
8. **For instant Svelte/CSS HMR with phoenix_vite:** In `config/dev.exs`, add to your endpoint `static_url: [host: "localhost", port: 5173]` and in `watchers` add `vite: {PhoenixVite.Npm, :run, [:vite, ~w(dev)]}`. Without these, the layout serves built assets and changes to Svelte components will not hot-reload.
|
||||
|
||||
#### Using Bun with manual installation
|
||||
|
||||
To use **Bun** instead of npm when installing manually:
|
||||
|
||||
1. Add the optional dependency in `mix.exs`: `{:bun, ">= 1.5.1 and < 2.0.0-0"}`
|
||||
2. In `config/config.exs`, use `config :phoenix_vite, PhoenixVite.Bun, ...` (with the same options you would use for `PhoenixVite.Npm`; see [phoenix_vite](https://hexdocs.pm/phoenix_vite) for the Bun API).
|
||||
3. In `mix.exs` aliases, use `phoenix_vite.bun` instead of `phoenix_vite.npm`:
|
||||
- `"assets.setup": ["phoenix_vite.bun assets install", "tailwind.install --if-missing"]`
|
||||
- `"assets.build"`: same two `phoenix_vite.bun vite build ...` commands as in the npm version.
|
||||
4. In `config/dev.exs` watchers, use `vite: {PhoenixVite.Bun, :run, [:vite, ~w(dev)]}`.
|
||||
|
||||
Production SSR still uses Node.js (`LiveSvelte.SSR.NodeJS`); the server must have Node.js 19+ installed.
|
||||
|
||||
## Disabling SSR
|
||||
|
||||
If you don't need server-side rendering, disable it globally:
|
||||
|
|
|
|||
|
|
@ -49,4 +49,4 @@ Plain LiveView may be sufficient when:
|
|||
| Phoenix | 1.7+ (1.8+ for Igniter installer) |
|
||||
| Phoenix LiveView | 1.0+ |
|
||||
| Elixir | 1.17+ |
|
||||
| Node.js | 19+ (for SSR) |
|
||||
| Node.js or Bun | Node.js 19+ for SSR; Bun or Node.js 19+ for tooling |
|
||||
|
|
|
|||
192
guides/new_phoenix_app_without_ecto.md
Normal file
192
guides/new_phoenix_app_without_ecto.md
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
# New Phoenix project without Ecto (Igniter + LiveSvelte)
|
||||
|
||||
Step-by-step guide to create a new Phoenix app **without Ecto** inside the `live_svelte` folder, using the Igniter installer and the local LiveSvelte library.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Elixir 1.17+
|
||||
- Node.js 19+ (or Bun)
|
||||
- Phoenix 1.8+ (pulled in by Igniter)
|
||||
|
||||
## Step 1: Install the Igniter archive
|
||||
|
||||
From any directory:
|
||||
|
||||
```bash
|
||||
mix archive.install hex igniter_new
|
||||
```
|
||||
|
||||
## Step 2: Create the new Phoenix app inside `live_svelte`
|
||||
|
||||
Go to the `live_svelte` directory and run Igniter with `phx.new` and `--no-ecto`:
|
||||
|
||||
```bash
|
||||
cd /home/gevera/Projects/elixir/phx_live/live_svelte
|
||||
mix igniter.new my_app --with phx.new --with-args="--no-ecto" --install live_svelte
|
||||
```
|
||||
|
||||
Replace `my_app` with your app name (e.g. `alan_app`). This creates `live_svelte/my_app/` with Phoenix (no Ecto) and LiveSvelte pre-installed.
|
||||
|
||||
To use **Bun** instead of npm:
|
||||
|
||||
```bash
|
||||
mix igniter.new my_app --with phx.new --with-args="--no-ecto" --install live_svelte --bun
|
||||
```
|
||||
|
||||
## Step 3: Use the local LiveSvelte library (development)
|
||||
|
||||
The installer adds LiveSvelte from Hex. To use the **local** LiveSvelte in this repo instead:
|
||||
|
||||
1. **Edit the new app’s `mix.exs`**
|
||||
Find the `live_svelte` dependency and change it to a path dependency:
|
||||
|
||||
```elixir
|
||||
# Change from:
|
||||
# {:live_svelte, "~> 0.17.x"},
|
||||
# To:
|
||||
{:live_svelte, path: ".."},
|
||||
```
|
||||
|
||||
2. **Edit the new app’s `package.json`**
|
||||
Point `live_svelte` and Phoenix deps to the local/relative paths (same layout as `example_project` and the fixed `alan_app`):
|
||||
|
||||
- `live_svelte`: use `"file:.."` (parent directory = LiveSvelte root).
|
||||
- Phoenix-related deps: use `"file:./deps/..."` (Mix puts them in `my_app/deps/`).
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
"dependencies": {
|
||||
"live_svelte": "file:..",
|
||||
"phoenix": "file:./deps/phoenix",
|
||||
"phoenix_html": "file:./deps/phoenix_html",
|
||||
"phoenix_live_view": "file:./deps/phoenix_live_view",
|
||||
"topbar": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"phoenix_vite": "file:./deps/phoenix_vite",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
If your `package.json` has `file:../deps/...`, change those to `file:./deps/...` and `live_svelte` to `file:..`.
|
||||
|
||||
## Step 4: Install dependencies and run
|
||||
|
||||
From the **new app** directory:
|
||||
|
||||
```bash
|
||||
cd my_app
|
||||
mix deps.get
|
||||
mix assets.setup
|
||||
mix phx.server
|
||||
```
|
||||
|
||||
Open `http://localhost:4000` and visit `/svelte_demo` to confirm LiveSvelte works.
|
||||
|
||||
## Summary
|
||||
|
||||
| Step | Command / action |
|
||||
|------|-------------------|
|
||||
| 1 | `mix archive.install hex igniter_new` |
|
||||
| 2 | `cd live_svelte` then `mix igniter.new my_app --with phx.new --with-args="--no-ecto" --install live_svelte` |
|
||||
| 3 | In `my_app`: set `{:live_svelte, path: ".."}` in `mix.exs` and fix `package.json` to `live_svelte: "file:.."` and Phoenix deps to `file:./deps/...` |
|
||||
| 4 | `cd my_app`, `mix deps.get`, `mix assets.setup`, `mix phx.server` |
|
||||
|
||||
Optional: add `--bun` to the `igniter.new` command to use Bun instead of npm.
|
||||
|
||||
---
|
||||
|
||||
## If `igniter.new` fails with "dependencies were not loaded"
|
||||
|
||||
Igniter can fail with:
|
||||
|
||||
```text
|
||||
** (RuntimeError) cannot retrieve dependencies information because dependencies were not loaded.
|
||||
Please invoke one of "deps.loadpaths", "loadpaths", or "compile" Mix task
|
||||
```
|
||||
|
||||
That happens when it creates the new app and then tries to compile before the new project’s deps are loaded. The app directory (e.g. `my_app/`) is still created by `phx.new`; only the LiveSvelte install step didn’t run. You can finish setup by hand.
|
||||
|
||||
### Recover the existing app (e.g. `my_app`)
|
||||
|
||||
1. **Go into the new app and load deps:**
|
||||
|
||||
```bash
|
||||
cd live_svelte/my_app
|
||||
mix deps.get
|
||||
mix compile
|
||||
```
|
||||
|
||||
2. **Add LiveSvelte and Phoenix Vite to `mix.exs`** in the `deps/0` list (and keep `igniter` if it’s there):
|
||||
|
||||
```elixir
|
||||
{:phoenix_vite, "~> 0.4"},
|
||||
{:live_svelte, path: ".."}
|
||||
```
|
||||
|
||||
3. **Fetch deps and run the LiveSvelte installer:**
|
||||
|
||||
```bash
|
||||
mix deps.get
|
||||
mix igniter.install live_svelte
|
||||
```
|
||||
|
||||
Use `--bun` if you want Bun: `mix igniter.install live_svelte --bun`.
|
||||
|
||||
4. **Fix `package.json` for local LiveSvelte** (same as Step 3 in the main flow):
|
||||
|
||||
- `"live_svelte": "file:.."`
|
||||
- Phoenix deps: `"file:./deps/phoenix"`, `"file:./deps/phoenix_html"`, `"file:./deps/phoenix_live_view"`
|
||||
- In devDependencies: `"phoenix_vite": "file:./deps/phoenix_vite"`
|
||||
|
||||
5. **Install assets and run:**
|
||||
|
||||
```bash
|
||||
mix assets.setup
|
||||
mix phx.server
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alternative: create with `phx.new` then install LiveSvelte
|
||||
|
||||
To avoid `igniter.new` entirely (e.g. if the "dependencies were not loaded" error keeps happening):
|
||||
|
||||
1. **Create a Phoenix app without Ecto** from the `live_svelte` directory:
|
||||
|
||||
```bash
|
||||
cd live_svelte
|
||||
mix phx.new my_app --no-ecto
|
||||
```
|
||||
|
||||
(You need the `phx_new` archive: `mix archive.install hex phx_new`.)
|
||||
|
||||
2. **Add Igniter and LiveSvelte** in the new app’s `mix.exs` (in `deps/0`):
|
||||
|
||||
```elixir
|
||||
{:igniter, "~> 0.6", only: [:dev, :test]},
|
||||
{:phoenix_vite, "~> 0.4"},
|
||||
{:live_svelte, path: ".."}
|
||||
```
|
||||
|
||||
3. **Install deps and run the LiveSvelte installer:**
|
||||
|
||||
```bash
|
||||
cd my_app
|
||||
mix deps.get
|
||||
mix igniter.install live_svelte
|
||||
```
|
||||
|
||||
Use `mix igniter.install live_svelte --bun` for Bun.
|
||||
|
||||
4. **Fix `package.json`** so the app uses the local LiveSvelte and local Phoenix deps (same as Step 3 above: `live_svelte` → `"file:.."`, Phoenix deps → `"file:./deps/..."`).
|
||||
|
||||
5. **Setup assets and run:**
|
||||
|
||||
```bash
|
||||
mix assets.setup
|
||||
mix phx.server
|
||||
```
|
||||
|
||||
This way you never run `igniter.new`; you use `phx.new` and then `igniter.install live_svelte`.
|
||||
|
|
@ -60,7 +60,7 @@ This injects Svelte component CSS directly into the JS bundle instead of extract
|
|||
|
||||
**Cause:** The `liveSveltePlugin` is missing from one or both Vite configs.
|
||||
|
||||
**Fix:** Ensure `liveSveltePlugin()` is in `vite.config.mjs` and that `ssr: { noExternal: ... }` is set. The same config is used for both client and SSR builds (via `phoenix_vite.npm vite build --ssr js/server.js ...`).
|
||||
**Fix:** Ensure `liveSveltePlugin()` is in `vite.config.mjs` and that `ssr: { noExternal: ... }` is set. The same config is used for both client and SSR builds (via `phoenix_vite.npm vite build --ssr js/server.js ...`). If you use Bun, the same steps apply with `phoenix_vite.bun` and `PhoenixVite.Bun`.
|
||||
|
||||
```js
|
||||
// assets/vite.config.mjs
|
||||
|
|
@ -236,4 +236,4 @@ config :my_app, MyAppWeb.Endpoint,
|
|||
]
|
||||
```
|
||||
|
||||
Without these, the layout serves built assets from `priv/static` and Svelte/CSS changes do not hot-reload.
|
||||
(If you use Bun, use `PhoenixVite.Bun` and `phoenix_vite.bun` in aliases instead.) Without these, the layout serves built assets from `priv/static` and Svelte/CSS changes do not hot-reload.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ defmodule Mix.Tasks.LiveSvelte.Install do
|
|||
"config.exs",
|
||||
:phoenix_vite,
|
||||
[PhoenixVite.Npm, :assets],
|
||||
{:code, Sourceror.parse_string!(~s|[args: [], cd: __DIR__]|)}
|
||||
{:code, Sourceror.parse_string!(~s|[args: [], cd: Path.expand("..", __DIR__)]|)}
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ defmodule Mix.Tasks.LiveSvelte.Install do
|
|||
content,
|
||||
~r/([ \t]*)(children = \[)/,
|
||||
"\\1node_js_children =\n" <>
|
||||
"\\1 if Application.compile_env(:live_svelte, :ssr_module, nil) == LiveSvelte.SSR.NodeJS do\n" <>
|
||||
"\\1 if Application.get_env(:live_svelte, :ssr_module, nil) == LiveSvelte.SSR.NodeJS do\n" <>
|
||||
"\\1 [{NodeJS.Supervisor, [path: LiveSvelte.SSR.NodeJS.server_path(), pool_size: 4]}]\n" <>
|
||||
"\\1 else\n" <>
|
||||
"\\1 []\n" <>
|
||||
|
|
|
|||
|
|
@ -146,12 +146,12 @@ defmodule Mix.Tasks.LiveSvelte.InstallTest do
|
|||
assert content =~ "NodeJS.Supervisor"
|
||||
end
|
||||
|
||||
test "NodeJS.Supervisor is wrapped in compile_env guard, not unconditional" do
|
||||
test "NodeJS.Supervisor is wrapped in get_env guard, not unconditional" do
|
||||
result = run_installer()
|
||||
content = file_content(result, "lib/test/application.ex")
|
||||
|
||||
assert content =~ "Application.compile_env(:live_svelte, :ssr_module",
|
||||
"NodeJS.Supervisor must be wrapped in a compile_env guard so it only starts in prod"
|
||||
assert content =~ "Application.get_env(:live_svelte, :ssr_module",
|
||||
"NodeJS.Supervisor must be wrapped in a get_env guard so it only starts in prod"
|
||||
|
||||
refute content =~ ~r/children\s*=\s*\[\s*\{NodeJS\.Supervisor/,
|
||||
"NodeJS.Supervisor must not be a bare unconditional entry in the children list"
|
||||
|
|
|
|||
Loading…
Reference in a new issue