Cmder

Mix tasks for installing and invoking cmder. The raison d'etre for this module is to prevent zombies.

Installation

If you are going to run commands in production, then you add cmder as dependency on all environments but only start it in dev:

def deps do
  [
    {:cmder, "~> 0.0.2", runtime: Mix.env() == :dev}
  ]
end

However, if you run commands only during development, then it only needs to be a dev dependency:

def deps do
  [
    {:cmder, "~> 0.0.2", only: :dev}
  ]
end

Profiles

The first argument to cmder is an execution profile. You can define multiple execution profiles with the current directory, the OS environment, and default arguments to the cmder task:

config :cmder,
  tailwindcss: [
    args: ~w(--input=css/app.css --output=../priv/static/assets/app.css --postcss),
    cd: Path.expand("../assets", __DIR__)
  ]

When mix cmder tailwindcss is invoked, the task arguments will be appended to the ones configured above. Note profiles must be configured in your config/config.exs, as cmder runs without starting your application (and therefore it won't pick settings in config/runtime.exs).

Adding to Phoenix

To add cmder to an application using Phoenix, you need only four steps. Installation requires that Phoenix watchers can accept module-function-args as possible since Phoenix 1.6.0.

First add it as a dependency in your mix.exs:

def deps do
  [
    {:phoenix, "~> 1.6.0"},
    {:cmder, "~> 0.0.2", runtime: Mix.env() == :dev}
  ]
end

Now let's change config/config.exs to configure cmder to list the file contents of the priv/static/assets directory:

config :cmder,
  tailwindcss: [
    path: Path.expand("../assets/node_modules/.bin", __DIR__),
    args: ~w(--input=css/app.css --output=../priv/static/assets/app.css --postcss),
    cd: Path.expand("../assets", __DIR__)
  ],
  cpx: [
    prevent_zombie: true,
    path: Path.expand("../assets/node_modules/.bin", __DIR__),
    args: ~w(static/**/* ../priv/static),
    cd: Path.expand("../assets", __DIR__)
  ]

Make sure the "assets" directory from priv/static is listed in the :only option for Plug.Static in your lib/my_app_web/endpoint.ex

For development, we want to enable watch mode. So find the watchers configuration in your config/dev.exs and add:

  cmder: {Cmder, :run, [:tailwindcss, ~w(--watch)]}

License

Original based on [esbuild|https://github.com/phoenixframework/esbuild] which is

Copyright (c) 2021 Wojtek Mach, José Valim.

cmder source code is licensed under the MIT License.