stealjs / rfcs

A place to discuss higher level changes to Steal
MIT License
2 stars 0 forks source link

Remove automatic main loading #7

Closed matthewp closed 6 years ago

matthewp commented 7 years ago

tldr; Remove automatic loading of a project's main module, and instead require the user to explicitly specify the main.

This was discussed on a recent live stream (39:34) and at a contributors meeting (1:08:10)

The Problem

Because Steal automatically loads a main (usually the package.json "main") it leads to confusion and forces developers to understand Steal internals that shouldn't be needed.

This stems from the different ways developers typically use Steal. I see 3 primary uses:

Application's index.html

In the application's main HTML file you will add a line like:

<script src="node_modules/steal/steal.js"></script>

test.html

In any test page the dev will need to add something like:

<script src="node_modules/steal/steal.js" main="components/foo/foo_test"></script>

demo.html

In any demo pages the developer will usually add something like:

<script src="node_modules/steal/steal.js" main="@empty">
  import foo from 'foo';

  foo.bar();
</script>

So with the 3 primary cases, one of them you do not need to add a main, one of them you do need to add a main, and the last you do need to add a main which is really just a way to do a noop.

Given that the latter 2 cases account for the majority of the times you actually use Steal, it seems deeply wrong to me that Steal optimizes for the first, less common case, in order to make that case smaller.

Removing the automatic loading of the main would mean that users always need to use the main if they want to automatically load something, otherwise it will only load the configuration, so the demo case doesn't require the knowledge of the @empty noop.

The Solution

Require that the main be specified, either in the steal script tag or in a type=steal-module script tag.

Also allow for a special ~ module specifier that loads the root package's main. So instead of writing:

<script src="node_modules/steal/steal.js"></script>

You would write:

<script src="node_modules/steal/steal.js" main="~"></script>

Which might look worse to you, but consider that in demo pages instead of being:

<script src="node_modules/steal/steal.js" main="@empty"></script>
<script type="steal-module">
  import foo from 'foo';

  foo.bar();
</script>

it is more simply:

<script src="node_modules/steal/steal.js"></script>
<script type="steal-module">
  import foo from 'foo';

  foo.bar();
</script>

Tasks

Risks

This could be annoying to some people, so we need to teach the benefits.

Additionally this would require a semver major version bump, so we should only do this if there are other semver changes that people would be willing to upgrade for.

justinbmeyer commented 6 years ago

deeply wrong

It optimizes for the case a typical developer encounters first ... loading their main module. Though I still think it makes @empty confusing.

Could we make it easy for people to load the main module listed in package.json then? Something like: <script src="steal.js" main="~">

matthewp commented 6 years ago

Having ~ as an alias for the packageName sounds reasonable to me.

I would probably get rid of the main attribute in the steal script tag altogether and instead add that to the steal-module scripts. It might work like:

<script src="./node_modules/steal/steal.js"></script>
<script type="steal-module" name="~"></script>

The reason is that the steal-module type already is used to run demo code that expects the config to be loaded such as:

<script type="steal-module">
  import can from "can";
  ...
</script>

I think this is better because:

  1. You can add more than 1 <script type="steal-module"> to the page to load multiple entry point modules.
  2. This is parallel to how you can use <script type="module"> (except that steal-module takes a name attribute rather than a src, could maybe support both).
matthewp commented 6 years ago

Issue moved to stealjs/steal #1400 via ZenHub