We could wirte a simpler parser just for the imports subset, given the simpler isolated grammar I don't think is that hard with parser combinators. Maybe it's a cool idea for a npm library that just points out the dependencies of a single file and then recursively scan the rest. From that is just hook some cache system to a node server and voi'la
I migh try it as a weekend toy project Em qui, 22 de out de 2020 23:26, J Decker <[email protected]> escreveu: > > > On Thu, Oct 22, 2020 at 2:23 PM #!/JoePea <[email protected]> wrote: > >> > It's caused me some headaches especially when dealing with >> inheritance/extends and in workers. >> >> Like, extending from a `Module` object? >> >> > Maybe someday we'll have a `modules` collection we can interrogate. >> >> That may be nice, to query which modules have already been imported, etc. >> >> It would also be great if we could unload modules. >> >> --- >> >> Skypack is making news rounds as an ESM server: http://skypack.dev/ >> >> It says it supports HTTP/2 and HTTP/3. But it isn't open source. >> >> Seems that there isn't any open source solution (otherwise I'm sure >> people would be using that over bundling if it works out better, at >> least alternatives to skypack would exist, f.e. well-know projects >> like React, Angular, Vue, Svelte, etc, could all have their own ES >> Module servers if it was viable). >> >> Seems that there hasn't been any free/open project to prove viability >> yet, and the existing ones are closed source. >> >> Seems that even http://jspm.dev is closed source. >> >> Looks like at this point in time people are aiming to make money from >> ESM servers, and there's no viable open source ESM server solution. >> >> Seems like it wouldn't be a LOT of work to take Acorn ( > https://www.npmjs.com/package/acorn ) and http server ( > https://www.npmjs.com/package/http ) and parse the pages loaded if > (*.[cm]+js) (something) > > Though my observation is that when the browser gets the first page, async > requests go out for more content even before it's actually interpreted/run > the script; and the requests are streamed over one or more http(s) > connections. this screenshot https://pasteboard.co/JwUnbAD.png of this > demo http://d3x0r.github.io/Voxelarium.js/ shows the network load time; > recently updated to imports and non-built scripts... though I do see a > gap where the html script loading ends and the imports in the scripts > actually go... but that could also be the pause setting up the opengl > surface... it's about 50ms. > > since 'import' is itself async I sort of expected a lot of overlap in the > requests; there's only a single network wire, so there's not a LOT to be > gained parallelizing things. > > If there was even some sort of manifest could make a background service > worker (which itself doesn't support import > https://bugs.chromium.org/p/chromium/issues/detail?id=680046 ) which can > behave like a offline storage/cache so the server can dump requests to the > client before it knows to ask for them... and then it doesn't have to ask > the server for anything at all later even; which sort of de-emphasizes all > the work put into the server in the first place :) > > J > > #!/JoePea >> >> On Sun, Oct 18, 2020 at 8:50 AM Randy Buchholz <[email protected]> >> wrote: >> > >> > Right, it's basically just doing what an import aware server might do >> and the type-tree is a hierarchal version of the scope imports. The rest is >> just extra stuff. Probably the biggest difference though is that it lets me >> isolate prototypes. From what I gather it seems that import stores a live >> "ghosted" version of the prototype that it checks before making additional >> requests for the item. The scope basically gets a reference to this >> prototype. If you do things like add a property with reflect in one scope >> that property shows up everywhere. And since it modified the "ghost" it >> persists after the scope goes away. It's caused me some headaches >> especially when dealing with inheritance/extends and in workers. >> > >> > Yeah, inspecting is in issue. I haven't found a way to inspect modules >> to see what they have in them. They're a strange beast. You can see their >> scope in the debugger and they look like an ES Object or IDL interface, but >> I don't know how to get a reference to them in code. But, they're new, so >> we'll see where they go. Maybe someday we'll have a `modules` collection we >> can interrogate. >> > >> > -----Original Message----- >> > From: #!/JoePea <[email protected]> >> > Sent: Saturday, October 17, 2020 10:35 PM >> > To: Randy Buchholz <[email protected]> >> > Cc: [email protected] >> > Subject: Re: Are ES6 modules in browsers going to get loaded >> level-by-level? >> > >> > That's neat, but it seems like the same work that a server would have >> to do with actual ES Module imports, right? And the "type tree" >> > equivalent is the modules that the JS engine stores as a map from >> import identifier to module scope instance. It seems that in the end, the >> `PUSH` approach should work with the same efficiency, right? >> > >> > Seems the only thing that makes it difficult is checking the map. In >> your special case, with `inject`, you can physically check the global >> namespaces to see if the module is available. But with ES Modules, we can't >> check if some module has already been lodade by its identifier, can we? So >> we have to make the request, because that's the only way to check. >> > >> > #!/JoePea >> > >> > On Sat, Oct 17, 2020 at 1:28 PM Randy Buchholz <[email protected]> >> wrote: >> > > >> > > I think some form of bundling will always be necessary. I use classes >> and took a name-spaced and typed approach to modules and classes, putting >> each class in its own module in a file hierarchy (namespace). This is an >> enterprise level LOB application with dozens of classes. Many classes are >> used cross-domain, limiting static/design-time bundling approaches. Also, >> an issue I encountered with static bundling is that classes aren't hoisted, >> so there are ordering concerns/issues with class bundles. >> > > >> > > >> > > >> > > I have multiple workers as background services that use these. Each >> class usually has a few imports for the classes it uses. Using normal >> imports, I was soon generating 100's of requests for the files. Even with >> caching, there is a lot of overhead. As classes are used more, this can >> become a real issue. >> > > >> > > >> > > >> > > I ended up with an approach where I added dependency metadata to each >> class to support bundling. The metadata helps with the "what to send" >> issue. When I need a class/type do an import for it. The server walks the >> dependencies, and bundles the request class with the full tree of >> dependencies. When the client receives the bundle it adds the new classes >> to a type library. It's designed for enterprise use where you have more >> control of things and can enforce standards. >> > > >> > > >> > > >> > > Class looks like this: >> > > >> > > >> > > >> > > // File Bar.cmjs >> > > >> > > ``` >> > > >> > > //::Requires: Foo.Package.Class1 Foo.Package.Class2 >> > > >> > > class Bar { >> > > >> > > const a = new Class1(); // Actually usually the qualified >> > > Foo.Package.Class1 >> > > >> > > ... >> > > >> > > } >> > > >> > > ``` >> > > >> > > // File /Foo/Package/Class1.cmjs >> > > >> > > ``` >> > > >> > > //::/Requires: Common.Util.Whatever >> > > >> > > class Class1{ >> > > >> > > >> > > >> > > } >> > > >> > > ``` >> > > >> > > >> > > >> > > The basic idea is that when the server gets a request it reads the >> "Requires" and gets those files, recursively reading requires. I keep a >> list of all files and the depth so I know if I already captured a required, >> and how to order the results. Once I have all of the files I write them to >> a single bundle. I don't need to parse the files (Requires is just a >> comment), but can if I want more control. The bundled file looks like: >> > > >> > > >> > > >> > > ``` >> > > >> > > class Whatever {...} >> > > >> > > >> > > >> > > class Class1 {...} >> > > >> > > >> > > >> > > class Class2 {...} >> > > >> > > >> > > >> > > class Bar {...} >> > > >> > > ``` >> > > >> > > >> > > >> > > It's more complex, because of name collisions and import scoping. >> What I do is process the bundle and promote the classes out of the scope. >> > > >> > > ``` >> > > >> > > globalThis >> > > >> > > .Foo >> > > >> > > .Package >> > > >> > > .Class1 = Class1; // (The "newable" class) >> > > >> > > .Class2 = Class2; >> > > >> > > .Common >> > > >> > > .Util >> > > >> > > .Whatever = Whatever; >> > > >> > > ``` >> > > >> > > >> > > >> > > Now I can just do `new Foo.Package.Class1()` anywhere in the context, >> not just in the import scope. On the client I use `inject` in many places >> instead of `import` - inject('A.B.Class'); const x = new A.B.Class();`. >> This checks for the type, and if it doesn't exist on the client it requests >> it from the server. The server creates a bundle for it and its >> dependencies. I add these to the type-tree. My server isn't really >> import-aware, I just use middleware to intercept the request. This is why I >> could use a way to identify "import requests". I know when I’m doing an >> ”import” through injection, but with a regular import I have to do some >> inspection of the fetch to know to initiate the process. >> > > >> > > _______________________________________________ >> > > es-discuss mailing list >> > > [email protected] >> > > https://mail.mozilla.org/listinfo/es-discuss >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

