Compiler: Compiling a program with no "main" creates no output

Created on 21 Sep 2018  ยท  4Comments  ยท  Source: elm/compiler

With this program:

-- Main.elm
a = 1

and this command:

$ elm make Main.elm
Success! Compiled 1 module.

The compiler does not display any errors, and it does not output any files.

Ellie: https://ellie-app.com/3q2m6MNfFrna1

  • Elm version: 0.19
  • Browser: Chrome
  • OS: Windows

I've been trying to decide if this intentional. Probably not, but in any case beginners get very confused when it seems like nothing happens but there are no errors!

The 0.18 compiler also does not error, but it does output a file. However since there is no main, other code on the page has no way of accessing the variables defined in the program

Most helpful comment

It was pretty tricky to think of a design that made sense for all the different ways you can call elm make. Here is an overview of the current design:

Case 1: elm make src/Main.elm with main defined.

Success! Compiled 1 module.

    Main โ”€โ”€โ”€> index.html

Case 2: elm make src/Other.elm with no main defined.

Success! Compiled 1 module.

Case 3: elm make src/Main.elm src/Root.elm with main defined in both.

Success! Compiled 2 modules.

    Main โ”€โ”€โ”€โ”ฌโ”€โ”€> elm.js
    Root โ”€โ”€โ”€โ”˜

Case 4: elm make src/Main.elm src/Other.elm with only one main defined.

Success! Compiled 1 module.

    Main โ”€โ”€โ”€> index.html

Case 5: elm make src/Other.elm --output=elm.js with no main defined

Success! Compiled 1 module.
-- NO MAIN ---------------------------------------------------------------------

When producing a JS file, I require that the given file has a `main` value. That
way Elm.Root.init() is definitely defined in the resulting file!

Try adding a `main` value to your file? Or if you just want to verify that this
module compiles, switch to --output=/dev/null to skip the code gen phase
altogether.

Note: Adding a `main` value can be as brief as adding something like this:

import Html

main =
  Html.text "Hello!"

Or use https://package.elm-lang.org/packages/elm/core/latest/Platform#worker to
make a `main` with no user interface.

Etc.

The goals here are:

  1. Do something sensible for beginners just calling elm make and wanting to get a result. I think being explicit about saying "Hey, I generated a file!" is helpful for understanding what the compiler is doing.
  2. Be stricter when folks use --output=elm.js or --output=index.html. In that case, the compiler is going to give an error if you do not have a main defined or give a number of files that doesn't make sense.

I don't think it is perfect for detecting "nothing was output" but we ended up feeling like this new design of (1) being explicit and (2) being stricter when --output is specified was a good balance to address all the different perspectives of folks using Elm.

All 4 comments

Just want to echo the above.

Accidentally deleted my main and experienced this pain. It was pretty confusing.

Super appreciate the project. Especially the great error messages.

-Nic

I also find this very confusing and wasted a bit of time after upgrading from 0.18 to 0.19 and trying to build a skeleton Elm app.

$ elm make --debug --output=elm.js src/Main.elm
Success! Compiled 1 module.

$ cat elm.js
cat: elm.js: No such file or directory

It would probably better to generate an error rather than "Success" when an output file could not be generated due to missing main.

It was pretty tricky to think of a design that made sense for all the different ways you can call elm make. Here is an overview of the current design:

Case 1: elm make src/Main.elm with main defined.

Success! Compiled 1 module.

    Main โ”€โ”€โ”€> index.html

Case 2: elm make src/Other.elm with no main defined.

Success! Compiled 1 module.

Case 3: elm make src/Main.elm src/Root.elm with main defined in both.

Success! Compiled 2 modules.

    Main โ”€โ”€โ”€โ”ฌโ”€โ”€> elm.js
    Root โ”€โ”€โ”€โ”˜

Case 4: elm make src/Main.elm src/Other.elm with only one main defined.

Success! Compiled 1 module.

    Main โ”€โ”€โ”€> index.html

Case 5: elm make src/Other.elm --output=elm.js with no main defined

Success! Compiled 1 module.
-- NO MAIN ---------------------------------------------------------------------

When producing a JS file, I require that the given file has a `main` value. That
way Elm.Root.init() is definitely defined in the resulting file!

Try adding a `main` value to your file? Or if you just want to verify that this
module compiles, switch to --output=/dev/null to skip the code gen phase
altogether.

Note: Adding a `main` value can be as brief as adding something like this:

import Html

main =
  Html.text "Hello!"

Or use https://package.elm-lang.org/packages/elm/core/latest/Platform#worker to
make a `main` with no user interface.

Etc.

The goals here are:

  1. Do something sensible for beginners just calling elm make and wanting to get a result. I think being explicit about saying "Hey, I generated a file!" is helpful for understanding what the compiler is doing.
  2. Be stricter when folks use --output=elm.js or --output=index.html. In that case, the compiler is going to give an error if you do not have a main defined or give a number of files that doesn't make sense.

I don't think it is perfect for detecting "nothing was output" but we ended up feeling like this new design of (1) being explicit and (2) being stricter when --output is specified was a good balance to address all the different perspectives of folks using Elm.

This is great! Thanks for taking the time to really improve the user experience here @evancz!

Was this page helpful?
0 / 5 - 0 ratings