Skip to content
This repository has been archived by the owner on Aug 23, 2018. It is now read-only.

Lift restriction on multiple main modules now that the compiler supports it #11

Closed
rehno-lindeque opened this issue Jan 8, 2015 · 7 comments

Comments

@rehno-lindeque
Copy link

Given that the compiler can now generate javascript with multiple main modules it may be possible to lift the restriction over here.

I noticed that the code checks whether modules are "public modules" before allowing them to pass the check, so I thought maybe these were "exposed-modules" in the elm-package.json.

At the moment we still need to compile this way:

elm_modules=`printf "\
      \nsrc/A/Main.elm
      \nsrc/B/Main.elm\
      \nsrc/C/Main.elm\
      \nsrc/D/Main.elm\
      \nsrc/E/Main.elm"`
elm-make $elm_modules --output elm-components.js --yes

Alternatively, perhaps the elm-package.json needs "main-modules" or something similar?

@evancz
Copy link
Contributor

evancz commented Jan 8, 2015

I don't understand the premise. "Given that the compiler can now generate javascript with multiple main modules, ..." What does that mean exactly? Is it true?

What is the root problem you are trying to resolve?

@rehno-lindeque
Copy link
Author

Sorry I might be unclear. We're currently using this to build...

elm_modules=`printf "\
      \nsrc/A/Main.elm
      \nsrc/B/Main.elm\
      \nsrc/C/Main.elm\
      \nsrc/D/Main.elm\
      \nsrc/E/Main.elm"`
elm-make $elm_modules --output elm-components.js --yes

...which works fine but has some maintenance burden (each of these modules is the main entry point to an embedded widget).

Today I tried to use the package.json instead like so...

{
    "version": "1.0.0",
    "summary": "My app",
    "repository": "https://github.com/...",
    "license": "Copyright",
    "source-directories": [
        "src"
    ],
    "exposed-modules": [
        "A.Main",
        "B.Main",
        "C.Main",
        "D.Main"
    ],
    "dependencies": { ... }
}

and then build without explicitly list the modules...

$ elm-make --output elm-components.js --yes

Error in ././src/A/Main.elm:

Port Error: ports may only appear in the main module. We do not want ports
    appearing in library code where it adds a non-modular dependency. If I
    import it twice, what does that really mean? This restriction may be
    lifted later.

I hope that's more clear...

@evancz
Copy link
Contributor

evancz commented Jan 8, 2015

Yeah, that helps a lot!

Here is my understanding. You would like to use elm-package.json as a way to fully specify your build for generating code to deploy.

I think of elm-package.json as the minimal set of information to define a package that can be published to the package repo. These packages should not even have a main, because they will always be used as imports.

My feeling is that it makes the most sense to specify builds with some separate thing rather than trying to jam it all into elm-package.json. I have the same problem as you with elm-lang.org and package.elm-lang.org where there are tons of Main modules floating around. In the former case, I need to crawl directories to find all the files. In the latter, it is a small set that I list explicitly. Both seem like valid cases to me. None of these problems seem related to package management, and it is complex enough that no perfect solution jumps into my mind.

Maybe there could be something like elm-make.json but I don't really know what should go in it. Module names is weird because you need source-directories. In the case of elm-lang.org, everything is named Main with no prefixes and directory structure is the only thing that differentiates things.

Do you agree with the reasoning here?

@rehno-lindeque
Copy link
Author

TLDR; My reply is sloppy - see my comment at the bottom :)


That does make sense to me, actually I hadn't even thought about it this way because I'm so used to .cabal and npm's package.json being used for builds and package management simultaneously.

I don't know the correct thing here, but for the sake of progress I'll try and argue the opposite. Is it possible "exposed-modules" could be used for performing dead-code elimination? (I feel this is probably a tenuous argument from me).

Something else I could try and bring up is that many tools like coffeescript, grunt and bower are published directly to npm. That's not to say this is a good idea. What are your thoughts on console tools built in elm?

Maybe there could be something like elm-make.json but I don't really know what should go in it.

Well, one thing I will mention is that there tends to be a lot of asset processing and install hooks that tend to go into this sort of thing (and JSON is absolutely horrendous for that sort of business). I suppose it is better to recommend shell / cake / grunt / gulp after all. I guess it comes down to whether you see package.elm-lang.org as a repository for tools as well as libraries. It seems like this is would be a discussion for the mailing list instead... Perhaps tools built in elm actually want to live on https://www.npmjs.org/ with an npm package.json instead?

EDIT: in this case the build command would essentially be npm build which in turn runs your favourite asset compilation script, which in turn runs elm-make with the relevant source files which could possibly be stored in the npm package.json also? I don't know, I take your point!

In the case of elm-lang.org, everything is named Main with no prefixes and directory structure is the only thing that differentiates things.

So I assume you don't compile these into a single Javascript file though? It would be impossible to distinguish between different Main modules after all. I wonder if you wouldn't want to build this into a single .js if there is a lot of shared code...? That is, it is quite common to package all application code into a single .js these days.


In any case... how about we shelve this issue for now? It doesn't seem like something that deserves a lot of attention right now, I'm happy to polish up our build script slightly instead!

@evancz
Copy link
Contributor

evancz commented Jan 9, 2015

I'm hesitant to put command line stuff in the package repo because I wouldn't say that command line stuff is explicitly supported, or that there is a "nice solution" for that case that everyone should be using. I think things will look different when that comes into existence.

I'm okay to shelve things, but I'd say keep the general problem in mind as you work on your build script! I think we are pushing the frontiers of Elm so anything you learn or any patterns you notice should be super valuable. I think the more data we have the better decisions we can make when we do a general solution.

Also, @rtfeldman made a grunt plugin for Elm which may be helpful for you?

@rehno-lindeque
Copy link
Author

Also, @rtfeldman made a grunt plugin for Elm which may be helpful for you?

That does looks useful, thank you. We're using gulp so maybe we'll port the plugin to that. I'll let you know if we do something interesting for this, but I highly doubt it. I think I'm likely to simply extract the list of A.Main ... E.Main modules into a \n-separated file for now. I'd much rather hound you for language features at this point ;)

@evancz
Copy link
Contributor

evancz commented Sep 17, 2015

I believe the idea in #49 covers this in a nicer way, so I am going to close this issue for now. Please open a new issue if you are looking for something else.

@evancz evancz closed this as completed Sep 17, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants