James Browning (2018-03-05T10:50:12.000Z)
Just as a follow up to these ideas, the first proposal I suggested can be
*entirely* resolved with the [top level await proposal](https://github.com/
MylesBorins/proposal-top-level-await
<https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2FMylesBorins%2Fproposal-top-level-await&sa=D&sntz=1&usg=AFQjCNH6cX0EEz4qrvCogYL9cc7jcguWdQ>).
As a consequence the **Module Arguments** idea is acceptably resolvable
within Node/Browsers anyway by using url parameters (as unique url
parameters will trigger multiple module instances) so the dictionary
example could be written as:

```
// dictionary.js
...

const language = new URL(import.meta.url).searchParams.get("lang") ||
"en-US";
const languageData = await loadData(new URL(`../langs/${ language }.js`,
import.meta.url)

export default makeDictionary(languageData)

// main.js
import englishDict from "./dictionary.js"
import spanishDict from "./dictionary.js?lang=es-ES"
```

The only downside to this approach is that there might be redundancy in
presence of multiple such args as `import foo from
"./foo.js?bar=12&cats=13"` would be different from `...
"./foo.js?cats=13&bar=12"` but I think it's relatively unimportant as I
can't actually think of a concrete example of multiple arguments.

---

Although I actually think in the presence of top-level-await that the
**Lazy-Export from** proposal would be even better, as even in the presence
of tree-shaking build tools those tools may not be able to determine where
a side-effect is actually important or not to the exported values. e.g.
Consider the above code, can a tree-shaker viably detect that the above
file is (pseudo) side-effect free? With complex usage this may become in
general too difficult.

Whereas given a static form a tree-shaking tool need not even consider
`static export { someExport } from "./someModule.js"` if `someExport` is
never actually imported in the receiving code. For example consider the
following code:

```
// audioTools.js

export { default as audioContext } from "./audioContext.js"
export { default as simpleBeat } from "./simpleBeat.js"
...

// audioContext.js
export default new AudioContext()

// main.js
import { simpleBeat } from "./audioTools.js"

/* Create own OfflineAudioContext */
const ctx = new OfflineAudioContext()

...

simpleBeat.connect(ctx,destination)
ctx.startRendering().then(...)
```

In this example `audioContext.js` has *real* side-effects (as there can
only be up to 6 or so live audio contexts in most browsers and because the
module lifetime persists with the page it can't be garbage collected). But
yet `audioContext` is never actually used so it's a pointless side-effect.
Can a tree-shaking tool detect this? Maybe? But I'm skeptical that
tree-shaking tools can detect all of these what I'm referring to as pseudo
side-effects.

Note that while I'm arguing in the context of build tools, this also
applies outside of build tools as it still potentially saves many loads on
small sites where a build tool may not be necessary (e.g. dynamic blogs, or
so on). Especially in the case of hundreds of exports (e.g. `import {
util1, util2 } from "./lodash.js"` could just work only loading the three
files `lodash.js`, `lodash/util1.js`, `lodash/util2.js`) as it doesn't
actually need to construct the whole module record.

If there's any TC39 members that would actually be interested in
championing something like this I'd be happy to write some material and
draft spec-text to clarify the exact problems and solution I'm proposing in
this idea.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180305/7f3c2c95/attachment.html>
thejamesernator at gmail.com (2018-03-05T10:52:13.592Z)
Just as a follow up to these ideas, the first proposal I suggested can be
*entirely* resolved with the top level await proposal: https://github.com/MylesBorins/proposal-top-level-await.

As a consequence the **Module Arguments** idea is acceptably resolvable
within Node/Browsers anyway by using url parameters (as unique url
parameters will trigger multiple module instances) so the dictionary
example could be written as:

```
// dictionary.js
...

const language = new URL(import.meta.url).searchParams.get("lang") ||
"en-US";
const languageData = await loadData(new URL(`../langs/${ language }.js`,
import.meta.url)

export default makeDictionary(languageData)

// main.js
import englishDict from "./dictionary.js"
import spanishDict from "./dictionary.js?lang=es-ES"
```

The only downside to this approach is that there might be redundancy in
presence of multiple such args as `import foo from
"./foo.js?bar=12&cats=13"` would be different from `...
"./foo.js?cats=13&bar=12"` but I think it's relatively unimportant as I
can't actually think of a concrete example of multiple arguments.

---

Although I actually think in the presence of top-level-await that the
**Lazy-Export from** proposal would be even better, as even in the presence
of tree-shaking build tools those tools may not be able to determine where
a side-effect is actually important or not to the exported values. e.g.
Consider the above code, can a tree-shaker viably detect that the above
file is (pseudo) side-effect free? With complex usage this may become in
general too difficult.

Whereas given a static form a tree-shaking tool need not even consider
`static export { someExport } from "./someModule.js"` if `someExport` is
never actually imported in the receiving code. For example consider the
following code:

```
// audioTools.js

export { default as audioContext } from "./audioContext.js"
export { default as simpleBeat } from "./simpleBeat.js"
...

// audioContext.js
export default new AudioContext()

// main.js
import { simpleBeat } from "./audioTools.js"

/* Create own OfflineAudioContext */
const ctx = new OfflineAudioContext()

...

simpleBeat.connect(ctx,destination)
ctx.startRendering().then(...)
```

In this example `audioContext.js` has *real* side-effects (as there can
only be up to 6 or so live audio contexts in most browsers and because the
module lifetime persists with the page it can't be garbage collected). But
yet `audioContext` is never actually used so it's a pointless side-effect.
Can a tree-shaking tool detect this? Maybe? But I'm skeptical that
tree-shaking tools can detect all of these what I'm referring to as pseudo
side-effects.

Note that while I'm arguing in the context of build tools, this also
applies outside of build tools as it still potentially saves many loads on
small sites where a build tool may not be necessary (e.g. dynamic blogs, or
so on). Especially in the case of hundreds of exports (e.g. `import {
util1, util2 } from "./lodash.js"` could just work only loading the three
files `lodash.js`, `lodash/util1.js`, `lodash/util2.js`) as it doesn't
actually need to construct the whole module record.

If there's any TC39 members that would actually be interested in
championing something like this I'd be happy to write some material and
draft spec-text to clarify the exact problems and solution I'm proposing in
this idea.
thejamesernator at gmail.com (2018-03-05T10:51:59.779Z)
Just as a follow up to these ideas, the first proposal I suggested can be
*entirely* resolved with the top level await proposal: https://github.com/
MylesBorins/proposal-top-level-await.

As a consequence the **Module Arguments** idea is acceptably resolvable
within Node/Browsers anyway by using url parameters (as unique url
parameters will trigger multiple module instances) so the dictionary
example could be written as:

```
// dictionary.js
...

const language = new URL(import.meta.url).searchParams.get("lang") ||
"en-US";
const languageData = await loadData(new URL(`../langs/${ language }.js`,
import.meta.url)

export default makeDictionary(languageData)

// main.js
import englishDict from "./dictionary.js"
import spanishDict from "./dictionary.js?lang=es-ES"
```

The only downside to this approach is that there might be redundancy in
presence of multiple such args as `import foo from
"./foo.js?bar=12&cats=13"` would be different from `...
"./foo.js?cats=13&bar=12"` but I think it's relatively unimportant as I
can't actually think of a concrete example of multiple arguments.

---

Although I actually think in the presence of top-level-await that the
**Lazy-Export from** proposal would be even better, as even in the presence
of tree-shaking build tools those tools may not be able to determine where
a side-effect is actually important or not to the exported values. e.g.
Consider the above code, can a tree-shaker viably detect that the above
file is (pseudo) side-effect free? With complex usage this may become in
general too difficult.

Whereas given a static form a tree-shaking tool need not even consider
`static export { someExport } from "./someModule.js"` if `someExport` is
never actually imported in the receiving code. For example consider the
following code:

```
// audioTools.js

export { default as audioContext } from "./audioContext.js"
export { default as simpleBeat } from "./simpleBeat.js"
...

// audioContext.js
export default new AudioContext()

// main.js
import { simpleBeat } from "./audioTools.js"

/* Create own OfflineAudioContext */
const ctx = new OfflineAudioContext()

...

simpleBeat.connect(ctx,destination)
ctx.startRendering().then(...)
```

In this example `audioContext.js` has *real* side-effects (as there can
only be up to 6 or so live audio contexts in most browsers and because the
module lifetime persists with the page it can't be garbage collected). But
yet `audioContext` is never actually used so it's a pointless side-effect.
Can a tree-shaking tool detect this? Maybe? But I'm skeptical that
tree-shaking tools can detect all of these what I'm referring to as pseudo
side-effects.

Note that while I'm arguing in the context of build tools, this also
applies outside of build tools as it still potentially saves many loads on
small sites where a build tool may not be necessary (e.g. dynamic blogs, or
so on). Especially in the case of hundreds of exports (e.g. `import {
util1, util2 } from "./lodash.js"` could just work only loading the three
files `lodash.js`, `lodash/util1.js`, `lodash/util2.js`) as it doesn't
actually need to construct the whole module record.

If there's any TC39 members that would actually be interested in
championing something like this I'd be happy to write some material and
draft spec-text to clarify the exact problems and solution I'm proposing in
this idea.