denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
97.01k stars 5.36k forks source link

A dialog about import maps and loading of non-bundled modules using dynamic imports #7704

Closed dschissler closed 1 month ago

dschissler commented 4 years ago

It would be good if the bundle feature allowed for import path prefixes to be specified like --url-prefix=/import/path/prefix/here|/home/dschissler/src/build/javascript. I have no idea what the delineator would be so I just picked something. This would allow me to do a two-phase bundling where I first make the heavy framework bundles and then I reference them in a sane way throughout the second phase modules with absolute frontend paths (without "../../.." of varying depths). This combined with my next request would allow for a two-phase compilation stage that would allow for basic code splitting.

It would also be useful if I could tell the bundler to try to import the package during front end runtime (and to not include it in the bundle). This way I can build my framework modules and then reference them in my second phase without including them in every bundle. So then a sort of code splitting would occur due to the second phase bundling importing the first phase module (libraries).

So then just make the web server static paths match up with ES import path prefix. There aren't any variables there so its all valid script.

Here is my Vue bundle.

import Vue from 'https://unpkg.com/vue@2.6.11/dist/vue.esm.browser.js'

export default Vue

At the moment I'm just using Deno to avoid using Node. However, the current limitations of Deno make it so that I won't be able to have any sort of bundling done on my custom code since I don't want to include the heavy libraries in every bundle. Its easier but it could be without any serious downside if something along the lines of my suggestions were implemented.

kitsonk commented 4 years ago

I am a bit confused. How does --importmap not meet this need?

dschissler commented 4 years ago

@kitsonk The import map feature absolutely solves the first part of my problem. Now I need to read that spec to figure out if there is a way to not bundle something that is referred to so that it could instead be imported with standard ES import syntax in the browser.

kitsonk commented 4 years ago

Use dynamic import. deno bundle though is not intended to create bundles for a browser, it is a welcome side effect for certain workloads. Deno.bundle() on the other hand is intended to be more general purpose but we will be changing those APIs very soon (see: #4752) and potentially adding a feature to exclude code from the bundle and preserve it would be possible.

dschissler commented 4 years ago

@kitsonk Wow so Deno wouldn't cheat a dynamic import into the bundle? If so then that is just great and also very intuitive. If this is already a reality then the documentation should definitely be reflected that you could just perform a two-stage bundling with dynamic imports. By using a import map you could eliminate the library bundle stage to get up and going sooner. I've not been out of hipster Javascript for very long (I thought) and so these import maps caught me by surprise.

I'll try to play with this within the next week. I'm excited to think that the tooling might already be there.

dschissler commented 4 years ago

It seems that Deno is almost there but its still not usable. In my situation I need Deno to do less work by ignoring the dynamic import instead of bundling it.

// Doesn't work for me because it bundles this module.
// const {Vue} = await import('lib/lib.vue.js')

// So I have to do this because Deno's lack of optimization functions an escape valve.
const path = 'lib/lib.vue.js'
const {Vue} = await import(path)

[edit]

// For the moment, this hack is less annoying.
// I dream of a very lazy Deno dynamic import.
const {Vue} = await import('lib/lib.vue.js' + '')
nayeemrmn commented 4 years ago

Honestly, I also wonder if just ignoring all dynamic imports is better than the limited static analysis we do now. What will swc do for this?

dschissler commented 4 years ago

@nayeemrmn What does swc mean?

kitsonk commented 4 years ago

@dschissler swc is the Rust library we use for transpiling TypeScript, linting, doc generation, etc. (and will be using for bundling in the near future).

@nayeemrmn yeah, I need to look into that... I had a bit of a chat with @kdy1 about it... I think it does make sense though to just pass it through, though it would be breaking with current behaviour (though current behaviour is confusing and unreliable and causes all sorts of challenges). The one use case of static inclusion in bundles is runtime feature toggling, like you want two different modules for two different platforms/envs/etc. and you want to build that into the bundle instead of having to have that code hosted somewhere and having to do the additional fetch. The problem is there is no easy way to disambiguate that, and even local/remote could become problematic. It is likely best to just say "we don't bundle dynamic imports".

nayeemrmn commented 3 years ago

This issue seemed to have boiled down to:

It seems that Deno is almost there but its still not usable. In my situation I need Deno to do less work by ignoring the dynamic import instead of bundling it.

Fixed in #8023.

lucacasonato commented 1 month ago

deno bundle removed in Deno 2, so I am closing this.