Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to import JSON #1048

Closed
kitsonk opened this issue Oct 21, 2018 · 10 comments · Fixed by #1065
Closed

Ability to import JSON #1048

kitsonk opened this issue Oct 21, 2018 · 10 comments · Fixed by #1065

Comments

@kitsonk
Copy link
Contributor

kitsonk commented Oct 21, 2018

TypeScript with the --resolveJsonModule compiler option allows constructs like:

import * as foo from "./foo.json";

Where the imported foo namespace will match the structure of the ./foo.json and ensure that the JSON is consumed in a type safe way. TypeScript simply re-emit the JSON though and not actually make it importable. In order to make usable within a Deno program we would have to create a AMD module something like this I would expect:

define([], function() {
  return JSON.parse(/* fetched source code */);
});
@ry
Copy link
Member

ry commented Oct 22, 2018

Sure - I’m for it. There’s a larger question about other file types and being able to import them as ArrayBuffers - but I think json isn’t so controversial.

@benjamingr
Copy link
Contributor

I think in general allowing specifying a Loader object (like Node does in https://nodejs.org/api/esm.html#esm_loader_hooks ) makes some sense.

@EduardoRFS
Copy link

I think about making explicit loaders like webpack import x from 'y!ds that allow us to create compatibility with the browser using some hacks

@kitsonk
Copy link
Contributor Author

kitsonk commented Oct 25, 2018

@EduardoRFS at this point, I don't think we want to consider a pluggable loader. I think we need to see how the larger ecosystem plays out, and it is a contentious issue. The SystemJS and AMD plugins are essentially incompatible and the WHATWG loader spec has essentially been abandoned.

If we implemented it people will depend upon a behaviour that might not be supportable long term. With JSON we are taking advantage of features that are already present in TypeScript to bring type safety to JSON imported as modules, and while the TypeScript team never intended to have it apply for anything other than CommonJS, they indicated that they left it "broken" for too long so it is now there for the long term.

While TypeScript can model loaders, I think we need a really compelling use case, and one where it isn't easily solved in user land. Other things that loader plugins are traditionally used for are loading other types of non JavaScript resources, like text, CSS, internationalisation string bundles, etc. All of these are pretty trivial to do in Deno from the user land, but something that was more difficult to do in a browser, ergo the benefit of a loader plugin.

@EduardoRFS
Copy link

From the browser point of view, it is basically a script named 'y!ds', a server can read it and render a script who make the load. Isn't necessarily some browser implementation standard, it's user land.

Yeah what i'm arguing about it's making a standard spec compatible with browsers(using just plain old render) and with a server side. It's a trick, but it works. We can't do it on server native because calling an HTTP GET it's different than reading from disk.

@EduardoRFS
Copy link

Ops for work with web we needs loader on the end, ./potato.json!jsonsee the example on the browser https://github.com/EduardoRFS/koa-web-loaders

And on the deno we just have some hook to loader who can replace the 'json'. If it's implemented it gonna work today on deno and on browse exactly identical

@kitsonk
Copy link
Contributor Author

kitsonk commented Oct 25, 2018

From the browser point of view, it is basically a script named 'y!ds', a server can read it and render a script who make the load. Isn't necessarily some browser implementation standard, it's user land.

I am not sure you actually understand how loader plugins work. With both AMD and SystemJS, that logic is baked into the loader that analysis and module identifiers that are required, it then passes to another module that conforms to the loader plugin API for that loader the information about the module, which allows the plugin to "replace" some of the standard loader functionality and eventually return a valid module that conforms to the loaders module specification. With bundlers like webpack and Rollup, all of the processing is done statically during the bundling process, so what ends up being written into the bundle is a post-processed module after the plugin has processed it. So it does similar work to what is done in the browser, just does it in advanced.

The proposed WHATWG loader plugin model, which was based of of SystemJS was to actually hook the browser loader to be able to augment how modules were loaded. The browser vendors were really really adverse to that low level of integration.

Ops for work with web we needs loader on the end, ./potato.json!json see the example on the browser https://github.com/EduardoRFS/koa-web-loaders

That requires special services which are choosing to support server side module loaders. This requires specially configured servers and is not part of any specification. In particular moduleSpecifier!plugin is the AMD convention while plugin!moduleSpecifier is the SystemJS. Neither one of them are part of any official standard and may not be supportable in the future. It would be ill advised to adopt that.

Just because you can configure are server mimic conventions of module loaders and bundlers:

https://github.com/EduardoRFS/koa-web-loaders/blob/ca2707a264b9d3b2df7ec6fb01f2564fba948792/index.js#L16-L26

Doesn't mean that it is a good idea to implement.

@EduardoRFS
Copy link

EduardoRFS commented Oct 26, 2018

it then passes to another module that conforms to the loader plugin API

I'm not proposing an API, i'm proposing only a way to detect a loader, who can be detected by a server and sended to browser without need to compile it and change the actual source. The API is another question

So it does similar work to what is done in the browser, just does it in advanced.

No it doesn't because you can't use ESM import to import an AMD / SystemJS module. That's the main point here, it's possible with some server side tricks to make it compatible with actual implementations of ESM ìmportand export

This requires specially configured servers and is not part of any specification.

Yes, exactly like all technologies used today, we use bundlers everywhere, the simple difference it's that you don't need to compile it to work with a browser, if you think, you don't need even a sourcemap for most of situations in that case, because the actual module isn't compiled, of course in production you gonna need a bundle but for a compatibility and a test, creating a way to run same code on both browser and server, it's really cool.

And every option that is gonna be chosen isn't part of a "official" standard, because that standard didn't exists. Browsers didn't read extensions, so making an extension based loader it's just making it less compatible with what is run today on the web.

That requires special services which are choosing to support server side module loaders

Yes, but it's completely compatible with browsers and gonna continue to be, because WHATWG didn't gonna change what is allowed as a character on URL. Both of them probably gonna continues to work for a long time.

Doesn't mean that it is a good idea to implement.

The reason why you said isn't a good idea, it's basically isn't a "oficial spec", "may not be supportable in the future". I don't know any "official spec" who allow use of native ESM and loaders, and it will keep working, isn't gonna happen in near future that ! became a specific usage char in a URL

And isn't about module loaders and bundlers, it's about being compatible with the actual spec of ESM

@kitsonk
Copy link
Contributor Author

kitsonk commented Oct 26, 2018

And isn't about module loaders and bundlers, it's about being compatible with the actual spec of ESM

Module loaders are not part of the ESM spec. So I am not sure how your solution makes anything compatible.

Browsers didn't read extensions, so making an extension based loader it's just making it less compatible with what is run today on the web.

Correct, browsers read media types, and the PR respects media types for remote modules, just as much as a browser does. So one could argue it is "more" compliant and compatible.

@EduardoRFS
Copy link

Module loaders are not part of the ESM spec. So I am not sure how your solution makes anything compatible.

It isn't incompatible, don't exists anything that don't allow that. The spec didn't say anything about that, so everything who works on top of the actual spec isn't incompatible. It's so true, that in 10min it's possible to test and see "hey it works". But AMD and SystemJS don't work on top of the actual spec. Even with a server, you cannot make a simple import

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants