Doing mix assets.deploy after integrating LiveSvelte

I have integrated LiveSvelt into my project, and after doing so i decided to setup create a release of my application using docker but i got an error saying that ** (Mix) The task "node" could not be found, that’s probably because LiveSvelte setup tutorial told me to change mix assets.deploy alias from:

"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]

to:

"assets.deploy": [
    "tailwind default --minify",
     "node build.js --deploy --prefix assets",
     "phx.digest"
]

Which resulted in an error saying that node(and also build.js after a fix) cannot be found so i changed it to cmd node assets/build.js --deploy --prefix assets
Now i get this error which says that files: “js/server.js”, “js/app.js” and “tsconfig.json” don’t exist even though i see that they exist, here’s exact error message.

✘ [ERROR] Cannot find tsconfig file "tsconfig.json"

✘ [ERROR] Cannot find tsconfig file "tsconfig.json"

✘ [ERROR] Could not resolve "js/server.js"

✘ [ERROR] Could not resolve "js/app.js"

2 errors
2 errors
/home/wojtek/justrunit/assets/node_modules/esbuild/lib/main.js:1604
  let error = new Error(`${text}${summary}`);
              ^

Error: Build failed with 2 errors:
error: Cannot find tsconfig file "tsconfig.json"
error: Could not resolve "js/server.js"
    at failureErrorWithLog (/home/wojtek/justrunit/assets/node_modules/esbuild/lib/main.js:1604:15)
    at /home/wojtek/justrunit/assets/node_modules/esbuild/lib/main.js:1056:28
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  errors: [
    {
      detail: undefined,
      id: '',
      location: null,
      notes: [],
      pluginName: '',
      text: 'Cannot find tsconfig file "tsconfig.json"'
    },
    {
      detail: undefined,
      id: '',
      location: null,
      notes: [],
      pluginName: '',
      text: 'Could not resolve "js/server.js"'
    }
  ],
  warnings: []
}

I woud really appreciate some guidance as i am stuck with this error for a few days now, thank you.

Did you add node to your docker environment?

Requirements

For Server-Side Rendering (SSR) to work you need node (version 19 or later) installed in your environment.

Make sure you have it installed in production too. You might be using node in the build step, but it might actually not be installed in your production environment.

You can make sure you have node installed by running node --version in your project directory.

source: GitHub - woutdp/live_svelte: Svelte inside Phoenix LiveView with seamless end-to-end reactivity

1 Like

in my dockerfile i have this line:

RUN apt-get update && apt-get install -y nodejs npm

so it should’ve been installed.

I think i should mention that the issue is present when i run mix assets.deploy and also when i try doing docker compose up

Did you check that those files exist inside of the container? You can check it by starting a new container off your image with a bash session to try to ls and debug from there.

1 Like

Thank you for your reply

I extracted filesystem out of the image and both node and npm were in there, and when i tried executing RUN node --version and RUN npm --version they both returned their versions as expected, i have npm 10 and node 22 installed if that matters.

Here is my whole dockerfile, i haven’t modified anything except installing curl so i can get access to more recent version of node and then installing it.

# Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian
# instead of Alpine to avoid DNS resolution issues in production.
#
# https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu
# https://hub.docker.com/_/ubuntu?tab=tags
#
# This file is based on these images:
#
#   - https://hub.docker.com/r/hexpm/elixir/tags - for the build image
#   - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20240130-slim - for the release image
#   - https://pkgs.org/ - resource for finding needed packages
#   - Ex: hexpm/elixir:1.16.2-erlang-26.2.2-debian-bullseye-20240130-slim
#
ARG ELIXIR_VERSION=1.16.2
ARG OTP_VERSION=26.2.2
ARG DEBIAN_VERSION=bullseye-20240130-slim

ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"

FROM ${BUILDER_IMAGE} as builder

# install build dependencies
RUN apt-get update -y && apt-get install -y build-essential git curl \
    && apt-get clean && rm -f /var/lib/apt/lists/*_*

RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash -

RUN apt-get install -y nodejs

RUN npm --version
RUN node --version
    
# prepare build dir
WORKDIR /app

# install hex + rebar
RUN mix local.hex --force && \
    mix local.rebar --force

# set build ENV
ENV MIX_ENV="prod"

# install mix dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only $MIX_ENV
RUN mkdir config

# copy compile-time config files before we compile dependencies
# to ensure any relevant config change will trigger the dependencies
# to be re-compiled.
COPY config/config.exs config/${MIX_ENV}.exs config/
RUN mix deps.compile

COPY priv priv

COPY lib lib

COPY assets assets

# compile assets
RUN mix assets.deploy

# Compile the release
RUN mix compile

# Changes to config/runtime.exs don't require recompiling the code
COPY config/runtime.exs config/

COPY rel rel
RUN mix release

# start a new build stage so that the final image will only contain
# the compiled release and other runtime necessities
FROM ${RUNNER_IMAGE}
RUN apt-get update -y && \
  apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \
  && apt-get clean && rm -f /var/lib/apt/lists/*_*


# Set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

WORKDIR "/app"
RUN chown nobody /app

# set runner ENV
ENV MIX_ENV="prod"

# Only copy the final release from the build stage
COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/justrunit ./

USER nobody

# If using an environment that doesn't automatically reap zombie processes, it is
# advised to add an init process such as tini via `apt-get install`
# above and adding an entrypoint. See https://github.com/krallin/tini for details
# ENTRYPOINT ["/tini", "--"]

CMD ["/app/bin/server"]

Besides that nothing have changed and trying to build an image still results in:

** (Mix) The task "node" could not be found
The command '/bin/sh -c mix assets.deploy' returned a non-zero code: 1

For the error above the problem is there’s no task “node”. Update your mix.exs such that it becomes cmd node .... The cmd task can run shell commands.

1 Like

After that we might need to look at the file build.js, it might be making wrong assumptions about the current working directory and therefore cannot find the other files it seems to reference.

1 Like

Okay, so LiveSvelte documentation is wrong? It would be kind of weird that a package with over 1k stars on github has a wrong setup guide and no one noticed.

Thanks for help, i will try to change few things here and there in build.js and will post results.

Hmm, the LiveSvelte docs mentions adding RUN npm install to the Dockerfile.

2. Modify the generated Dockerfile to install curl, which is used to install nodejs (version 19 or greater), and also add a step to install our npm dependencies:
...
+ # install all npm packages in assets directory
+ WORKDIR /app/assets
+ RUN npm install

source: Deployment: Deploying on Fly.io | LiveSvelte Readme

1 Like

That’s correct, i was surprised because because i had to add cmd before node build.js --deploy --prefix assets. I did everything which was said in docs regarding Dockerfile.

You may send a PR to fix the docs. Compare the Windows and Linux/macOS instructions in the README, they are surprisingly different.

Also notice the example project uses the cmd task:

1 Like

aaand it works, it seems all i had to do is replace:
node build.js --deploy --prefix assets
with:
cmd --cd assets node build.js --deploy
and while i still receive some error regarding css the app compiles and runs.

Now i’m left with only one error:

web-1    | 13:54:41.894 request_id=F-V5MIiDS_IkfdAAAADi [info] GET /assets/app.css
web-1    | 13:54:41.895 request_id=F-V5MIiDS_IkfdAAAADi [info] Sent 404 in 227µs

I tried to remove "tailwind default --minify" so it matches example project and replacing it with tailwind default --minify --output ./priv/static/assets/app.css, the first solution haven’t caused any changes and the second one worked only partially as the default tailwind classes were applied but styles specified on my pages weren’t applied.

I ran cat on assets/css/app.css after RUN mix assets.deploy and i got this:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

It seems that that those imports should’ve been replaced with actual classes which happens after doing tailwind default --minify --output ./priv/static/assets/app.css so it may actually be a solution to this problem, it made even more sense when i noticed this error:

warn - No utility classes were detected in your source files. If this is unexpected, double-check the content option in your Tailwind CSS configuration.
warn - https://tailwindcss.com/docs/content-configuration

I expected tailwind.config.js misconfiguration which causes some of the files not being detected by tailwind but it seems fine:

content: [
    "./js/**/*.js",
    "../lib/justrunit_web.ex",
    "../lib/justrunit_web/**/*.*ex",
    "./svelte/**/*.svelte"
  ],

Uhuuu! Super! :rocket: Almost there!

By any chance, is your project open source?

Is the tailwind config file inside the assets directory?

1 Like

I’m building something similar to codesandbox.io and i was planning to make it source-available self-hosted alternative but i haven’t yet found an appropriate license.

It is there

Source code of my project is now available on github if you want to take a look.

Hi Wojciech, I think you need to change this line justrunit/mix.exs at 4b5b9684d9ab14d946feb173b8b00b6f1a191a87 · justrundotit/justrunit · GitHub

to

tailwind justrunit --minify

That’s to match your config in justrunit/config/config.exs at 4b5b9684d9ab14d946feb173b8b00b6f1a191a87 · justrundotit/justrunit · GitHub.

The new app template has changed somewhat recently from the “default” profile to use the name of the app (Use umbrella apps names instead of "default" by agonzalezro · Pull Request #5683 · phoenixframework/phoenix · GitHub, oh well 7 months ago).

I wish that will be the last step to get it working. Good luck with your app!

1 Like

I’m having a similar issue trying to deploy to fly.io using livesvelte.

It’s breaking on the same step, mix assets.deploy

I get a different error, I’m hoping others have seen this because I’ve triple-checked every setting I can find and still get it.

Rebuilding...

Done in 235ms.
✘ [ERROR] Could not resolve "../svelte/**/*.svelte"

    js/app.js:25:28:
      25 │ import * as Components from "../svelte/**/*.svelte"
         ╵                             ~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".svelte" files: svelte/Header.svelte

    js/svelte-entry.js:2:28:
      2 │ import HeaderComponent from '../svelte/Header.svelte';
        ╵                             ~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".svelte" files: svelte/Sidebar.svelte

    js/svelte-entry.js:1:29:
      1 │ import SidebarComponent from '../svelte/Sidebar.svelte';
        ╵                              ~~~~~~~~~~~~~~~~~~~~~~~~~~

3 errors

UPDATE:
Replacing the command:
mix assets.deploy

With this command:
mix cmd ‘cd assets && node build.js --deploy’

Seems to fix the problem. I had to update my dockerfile to use this command as well.

1 Like