madsflensted / elm-brunch

Brunch plugin to compile Elm code
MIT License
74 stars 31 forks source link

Handle dependencies of main modules #14

Closed joakimk closed 7 years ago

joakimk commented 8 years ago

This adds a feature to define dependencies of a main module which will be compiled at the same time as the main module.

If either the main module or the dependencies are changed, the entire set is compiled.

Essentially this allows you to split an .elm file into multiple files and still have the compilation work.

What do you think? Anything I missed, or anything I should change?

joakimk commented 8 years ago

About the line "elm make handles all elm dependencies (required)", how does that work? I've tried in different ways to make it auto-require the files containing the modules I want to import, but it does not seem to do that.

If that worked, then this feature would not be needed.

madsflensted commented 8 years ago

@joakimk great that you are in the contributing mode!

As for elm make, if you have a main module that imports other modules, it is sufficient to tell elm make to compile the main module, all dependencies will get recompiled if necessary. Because elm make is fast and good at detecting when to re-compile, just running the compiler for the main modules is quite efficient, and you avoid the double book keeping of dependencies.

E.g. I just tried timing the compiling of https://github.com/ravichugh/sketch-n-sketch (src/ folder, with 20 elm files) Initial run (after compiling downloaded packages) was around 20 sec, where as a recompile with no changes took 0.5 sec.

Both runs were simply:

time elm-make Main.elm --output ../build/out/sns.js

So considering extra book keeping and code complexity, I am not sure that it is a good idea at the moment.

If you are want to look at other things, #9 is in the same ball park, does your code cover that scenario?

joakimk commented 8 years ago

About, https://github.com/madsflensted/elm-brunch/issues/9, I think defaulting to building all main files to a single output file would make sense to not duplicate the runtime? One possible way to do that without changing elm-brunch could be to have one Main.elm that imports all other main module files :)

I suppose if auto-require works this plugin could just build the main files when any elm file changes.

Will get back to you when I have time to look at this.

joakimk commented 8 years ago

Tried a new concept for fun, what do you think: https://github.com/madsflensted/elm-brunch/commit/872e642f41b2eae2471181b4eecba91afab0a7e4

See the commit comment first.

It works really well for my purposes, but there may be use cases where it would not work? Could also be against some brunch way of doing things.

A slightly less automatic variant of that would be to list all main files in config, but still keep the bundling of all mains into a single output file.

joakimk commented 8 years ago

In any case, would it make sense to always compile all main elm files into a single output file or can you think of any reason to make that configurable?

joakimk commented 8 years ago

Maybe making it possible to export to different files, even when joining some of them would be good.

One possible idea for a config syntax that works like brunch "joinTo", https://github.com/brunch/brunch/blob/master/docs/config.md#files.

    elmBrunch: {
      elmFolder: "web/elm",
      mainModules: [ "Comments.elm", "Search.elm", "Stats.elm" ],
      // outputTo: "combined.js",
      outputTo: {
        "../assets/js/public-elm.js": /Comments|Form/,
        "../assets/js/admin-elm.js": /Stats/
      }
    }

I'll (probably) wait with implementing anything more until you get a chance to give feedback. I can use my current version or even the regular one for now.

madsflensted commented 8 years ago

Great idea with the auto detection of main modules. I had a similar thought, but never got around to it. I guess it could be possible to detect the elmFolder as well, just finding the elm-package.json. It could be great if it was possible get started with zero config. And then you could use the outputTo config if you wanted to get more fancy.

I will try to give it a spin over the weekend, and also build up some example projects in the repo so it is easier to try out in different scenarios.

joakimk commented 8 years ago

Auto detection of main modules seems to have one major drawback that might make it unpractical. There is no way to know when brunch has called "compile" with all possible files, so we have to compile each time a main file turns up at boot. This could lead to long compile times for larger projects.

madsflensted commented 8 years ago

Yes - would be good if brunch send out "new file" and "changed file" events - so we could distinguish.

new file -> 
  is it a main file? 
    yes -> register and compile
    no -> register
changed file ->
  is main file?
    yes -> compile
    no -> compile dedicated main (outputTo) or all registered main files
delete file ->
  unregister

Problem here would be the "merge to single js" file I guess

joakimk commented 8 years ago

That would still not fix the issue that we ideally would only like to compile once at boot, every main file to a single output file.

brunch would have to have some kind of "beforeCompile(files)" API so we can register all possible files before "compile" is called.