You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to explore support for importing json, similar to how Node.js currently support require('./some.json')
Expected behavior:
imported json would export an object or array with the content from the provided json file.
Why:
Currently the was to get JSON is via fetch + import.meta.url... and requires a bit of back and forth... the eventual result is a promise to resolve to the json object. Being able to statically import and parse json would allow us to import specific symbols, export symbols, and asynchronously get resources during the fetch phase.
What are the next steps?:
I'm assuming a spec change in the HTML spec, but unsure what else we would need to do. Thoughts?
So concretely, for those not familiar with Node.js's support here, this would mean that if you import something with a JSON mime type, you would get back the result as if JSON.parse were applied to the files contents (decoded as UTF-8). If it doesn't parse as JSON, then the module ends up in the error state, similar to JavaScript parse errors.
As for next steps, the main one is implementer interest. /cc @whatwg/modules; does this seem like a reasonable addition?
Reacted by Jordan Harband, Duarte Cunha Leão, Andrea Giammarchi, JC and Lonnie Best
I think it is reasonable, but would note that this is for static data, whereas fetch() would get new data each time it is used; import() will not get new modules for each use. As long as this is well understood it seems good for a variety of usages that we see in bundler usages.
Reacted by Jordan Harband, Duarte Cunha Leão and Fred K. Schott
I'm happy with certain well-known and commonly-used content-types getting good module support, even if it's just a "trivial" wrapper around a constructor or function call. JSON, CSS, etc are all good.
This came up at the last W3C TPAC too, I raised WICG/webcomponents#770 at the time. If the complexity is indeed branching on a JSON MIME type and then using parse JSON from bytes I think Mozilla would be supportive. If we also want to advertise support to servers in some manner the discussion might become a little more involved. (It seems apart from an object or array this could also return a primitive, by the way.)
I don't know if it matters to the standards process, but there is some discussion of the topic already. If you look at the answers on that SO question (and at linked/related questions), you'll see there is some confusion as well. Because many (most?) people writing in ES6 or later end up transpiling via Babel -- which means using a module loader provided by the transpiler, rather than the browser-native one -- they can write import { x } from "foo.json" today, and as far as they are concerned, it works. Presumably this is because the Babel runtime loader is actually more advanced than the browser native implementation.
There are some complexities if we are wishing to exactly match tooling as it exists today.
To note, tools supporting JSON as an importable module type do allow both named and default exports. The JSON provided always assigns the result value to the default and then "picks" the relevant Object properties to expose as named exports e.g.
{"x": {}}
~=
exportdefault{x: {}}// export x = default.x //
This kind of aliasing where updating default.x updates x isn't available to Source Text Module Records, but that is probably fine.
Additionally, for non-Identifier properties, the only way to access values would be through the default export due to being unable to import non-Identifier bindings.
Conceptually a json file is a single thing; that babel allows named imports from it is merely a product of it conflating destructuring with named imports. I definitely agree json should be confined to default import.
Reacted by Fred K. Schott, Rob Palmer, Mattias Buelens, Sindre Sorhus, Niklas Mischkulnig and ExE Boss
Implementer interest would be ideal, otherwise spec text might be wasted effort. But, you could start spec and test work ahead of implementer interest, if you're OK taking the risk.
I'm happy to mentor on spec/test work when you're ready; let's discuss in a more high-bandwidth medium like IRC or offline.
Conceptually a json file is a single thing; that babel allows named imports from it is merely a product of it conflating destructuring with named imports. I definitely agree json should be confined to default import.
As background information why this complexity was introduced: aliasing the top-level JSON keys to named exports makes the JSON file tree-shakable on the first level. So if only x is used in the application, the rest can be removed. This can make a notable difference if the JSON file is big enough.
Reacted by James Bromwell, cybai (Haku), Daniel Ehrenberg, Marvin Hagemeister, Damian Senn, Alexey Berezin, The web walker, Victor Magalhães, xlaywan, Domenic Denicola and 12 more
Once someone takes the time to resolve WICG/webcomponents#839 I'm sure the conversation will find its way back to this repository somehow. Not sure we need a new tracking issue or reopen this one.
Seems like treating JSON file content as a default export is the only way to have consistency across all JSON features.
With JSON files containing content other than objects, for example
true
null
"foo"
123
[1, "2", true]
named imports don't work (obviously).
The only way to keep usage consistent with JSON features is a default export, then in their code people can choose to detect whether the import is a boolean, an object, or something else, or what properties they want to pluck from the default import in case it is an object.
If we don't mind being less consistent across JSON features, then the next best option is for default to work as above, but with named imports also available from JSON files that have object values (the same as @Jessidhia last mentioned).
But the question is, is consistency across the JSON features important? Most JSON values are objects, and most keys in those objects are valid identifiers.
Activity
domenic commentedon Jan 22, 2019
So concretely, for those not familiar with Node.js's support here, this would mean that if you
importsomething with a JSON mime type, you would get back the result as ifJSON.parsewere applied to the files contents (decoded as UTF-8). If it doesn't parse as JSON, then the module ends up in the error state, similar to JavaScript parse errors.As for next steps, the main one is implementer interest. /cc @whatwg/modules; does this seem like a reasonable addition?
bmeck commentedon Jan 22, 2019
I think it is reasonable, but would note that this is for static data, whereas
fetch()would get new data each time it is used;import()will not get new modules for each use. As long as this is well understood it seems good for a variety of usages that we see in bundler usages.tabatkins commentedon Jan 22, 2019
I'm happy with certain well-known and commonly-used content-types getting good module support, even if it's just a "trivial" wrapper around a constructor or function call. JSON, CSS, etc are all good.
annevk commentedon Jan 23, 2019
This came up at the last W3C TPAC too, I raised WICG/webcomponents#770 at the time. If the complexity is indeed branching on a JSON MIME type and then using parse JSON from bytes I think Mozilla would be supportive. If we also want to advertise support to servers in some manner the discussion might become a little more involved. (It seems apart from an object or array this could also return a primitive, by the way.)
thw0rted commentedon Jan 23, 2019
I don't know if it matters to the standards process, but there is some discussion of the topic already. If you look at the answers on that SO question (and at linked/related questions), you'll see there is some confusion as well. Because many (most?) people writing in ES6 or later end up transpiling via Babel -- which means using a module loader provided by the transpiler, rather than the browser-native one -- they can write
import { x } from "foo.json"today, and as far as they are concerned, it works. Presumably this is because the Babel runtime loader is actually more advanced than the browser native implementation.bmeck commentedon Jan 23, 2019
There are some complexities if we are wishing to exactly match tooling as it exists today.
To note, tools supporting JSON as an importable module type do allow both named and default exports. The JSON provided always assigns the result value to the
defaultand then "picks" the relevant Object properties to expose as named exports e.g.{"x": {}}~=
This kind of aliasing where updating
default.xupdatesxisn't available to Source Text Module Records, but that is probably fine.Additionally, for non-Identifier properties, the only way to access values would be through the default export due to being unable to import non-Identifier bindings.
I think the simplest solution of not supporting named exports would be fine for now and encourage a more uniform usage.
ljharb commentedon Jan 23, 2019
Conceptually a json file is a single thing; that babel allows named imports from it is merely a product of it conflating destructuring with named imports. I definitely agree json should be confined to default import.
MylesBorins commentedon Jan 23, 2019
What are the next steps for getting this off the ground? Spec Text? Implementor interest?
I'm happy to help drive this but need some mentorship on the process
domenic commentedon Jan 23, 2019
Implementer interest would be ideal, otherwise spec text might be wasted effort. But, you could start spec and test work ahead of implementer interest, if you're OK taking the risk.
I'm happy to mentor on spec/test work when you're ready; let's discuss in a more high-bandwidth medium like IRC or offline.
MylesBorins commentedon Jan 23, 2019
jhnns commentedon Feb 4, 2019
As background information why this complexity was introduced: aliasing the top-level JSON keys to named exports makes the JSON file tree-shakable on the first level. So if only
xis used in the application, the rest can be removed. This can make a notable difference if the JSON file is big enough.95 remaining items
annevk commentedon May 6, 2019
Mozilla is interested.
dandclark commentedon May 6, 2019
Microsoft is on board for implementing this in Blink.
[WIP] JSON module support
A few more things
A few more things
JSON module support
[WIP] Add style sheet module scripts
TimvdLippe commentedon Nov 7, 2019
Should this issue be reopened since #4943 reverted #4407 which closed this issue?
annevk commentedon Nov 7, 2019
Once someone takes the time to resolve WICG/webcomponents#839 I'm sure the conversation will find its way back to this repository somehow. Not sure we need a new tracking issue or reopen this one.
trusktr commentedon Mar 21, 2020
Seems like treating JSON file content as a
defaultexport is the only way to have consistency across all JSON features.With JSON files containing content other than objects, for example
truenull"foo"123named imports don't work (obviously).
The only way to keep usage consistent with JSON features is a default export, then in their code people can choose to detect whether the import is a boolean, an object, or something else, or what properties they want to pluck from the default import in case it is an object.
If we don't mind being less consistent across JSON features, then the next best option is for
defaultto work as above, but with named imports also available from JSON files that have object values (the same as @Jessidhia last mentioned).But the question is, is consistency across the JSON features important? Most JSON values are objects, and most keys in those objects are valid identifiers.
Rename ".json" -> ".json.js"
Re-add JSON module scripts
Re-add JSON module scripts