Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dynamically specifying output location #87

Open
BrianHicks opened this issue Feb 26, 2024 · 6 comments
Open

dynamically specifying output location #87

BrianHicks opened this issue Feb 26, 2024 · 6 comments

Comments

@BrianHicks
Copy link
Contributor

I'm setting up elm-watch at work. We have different parts of the frontend separated into different packages so Turbo can cache the JS/HTML/CSS/images/GraphQL code/etc all independently. This helps us keep builds fast, which is nice.

The convention is that each package has to define a build and package target, which output to build and dist respectively.

Then, in order to make hot reload actually work, I have to write to a third location where all the files get coalesced and served. I can set up a rule that says "when you see a change to this file, copy it into the build" but elm-watch reloads the browser too fast and picks up the old version of the file, so that doesn't work.

At any rate, I ended up with an elm-watch.json that looks structurally similar to this:

{
  "postprocess": ["elm-watch-node", "scripts/postprocess.mjs"],
  "targets": {
    "build": {
      "inputs": [
        "src/Main.elm"
      ],
      "output": "build/js/elm.js"
    },
    "package": {
      "inputs": [
        "src/Main.elm"
      ],
      "output": "dist/js/elm.js"
    },
    "frontend": {
      "inputs": [
        "src/Main.elm"
      ],
      "output": "../../big-frontend-package/build/js/elm.js"
    }
  }
}

It feels very silly to have three basically-identical targets with elm-watch when this is basically a non-issue with elm make. Is there a way to specify the output path dynamically? If not, could that be added? It'd help make this much less of a hack!

@lydell
Copy link
Owner

lydell commented Feb 27, 2024

Hi! I have read through your issue a couple of times now and … I must be missing something, because I just don’t get, like, much at all 😅 I don’t really get your setup, what it would look like with elm make, what you would like to be dynamic, and what is a hack.

Not sure if it makes sense for your case, but at work we generate elm-watch.json, and I’ve seen some other folks do that too when they’ve had complicated requirements.

@BrianHicks
Copy link
Contributor Author

Oh no! Sorry it wasn’t clear. Let me try to clarify.

When I run turbo build, I want a JS file to show up in the Elm output package under build. When I run turbo package, I want the same package but under dist to match the convention.

When I run the hot server, I need the output to end up in a totally different package so the hot reloads work properly.

So what I’d like to be dynamic: only the output location. What feels like a hack: the combination of duplicating target definitions and hardcoding a cross-package path.

I suppose we could generate an elm-watch file but that’s adding a lot of machinery to do something like this!

Regardless, I’m not blocked from using elm-watch and I super appreciate you making and releasing it! The DX is so great in the browser! I just wanted to raise this as something I had to work around.

@lydell
Copy link
Owner

lydell commented Feb 27, 2024

Does this mean that you call elm-watch make from turbo somehow? Btw, is it turborepo or turbopack? (I have never used those, just heard about them.)

@BrianHicks
Copy link
Contributor Author

BrianHicks commented Feb 27, 2024

yes, that's exactly it. Under the covers it's doing the equivalent of npm run build, but with caching and a build graph on top.

@lydell
Copy link
Owner

lydell commented Feb 27, 2024

I think I have a good idea now: The beta version already supports import:ing elm-watch (https://lydell.github.io/elm-watch/server/#custom-server). We could then support passing in the stuff from elm-watch.json as an argument instead of having elm-watch read it as a file.

You’d replace elm-watch make with node my-elm-watch.mjs:

// my-elm-watch.mjs
import elmWatch from "elm-watch";

elmWatch(["make"], {
    "elm-watch.json": {
        postprocess: ["elm-watch-node", "postprocess.js"],
        port: 9876,
        targets: {
            "My target name": {
                inputs: [
                    "src/Main.elm"
                ],
                output: "build/main.js"
            }
        }
    }
})
  .then((exitCode) => {
    process.exit(exitCode);
  })
  .catch((error) => {
    console.error("Unexpected elm-watch error:", error);
  });

@BrianHicks
Copy link
Contributor Author

ah, yeah, that'd work! Then output could be like process.argv[3] or use whatever arg parsing framework. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants