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

Support for magic comments in import() #1240

Open
iamakulov opened this issue May 3, 2021 · 2 comments
Open

Support for magic comments in import() #1240

iamakulov opened this issue May 3, 2021 · 2 comments

Comments

@iamakulov
Copy link

iamakulov commented May 3, 2021

One feature that I’d love to see in esbuild is esbuild’s take on webpack’s magic import() comments.

webpack supports adding comments inside import() calls. These comments affect how webpack bundles a code-split chunk:

const module = import(/* webpackPrefetch: true */ "./some-module.js")
// → Generates a `<link rel="prefetch">` for the chunk

Webpack’s magic comments can do a lot, and there’s likely no need to copy all their features. However, there’re some particular things that I’d love to see supported:

  • /* webpackMode: 'eager' */ which code-splits a module but keeps it in the same chunk. In practice, this is an incredibly useful way to defer initializing an expensive module until it’s needed.

    Example

    Say, you have an expensive-button-component module. The module executes some top-level code which takes 100 ms to run.

    import Button from 'expensive-button-component'
    const Widget = () => {
      return <Button color="red" />;
    }
    // → This code would pay the 100 ms cost when Button is imported (= when the bundle
    // is being evaluated), even if Button is never used.
    
    const Widget = () => {
      const Button = require('expensive-button-component').default
      return <Button color="red" />;
    }
    // → This code would pay the 100 ms cost only when Widget is rendered. However,
    // frequently, you can’t use `require()` unless you convert the whole file
    // or the whole codebase into CommonJS.
    
    const Button = React.lazy(() => import(/* webpackMode: 'eager' */ 'expensive-button-component')
    const Widget = () => {
      return <Button color="red" />;
    }
    // → This allows to to achieve the same result in an esm-only environment.
    // 'expensive-button-component' will stay in the same bundle, so you won’t pay the network cost
    // when importing it. And the runtime cost will be deferred until `<Button>` is rendered.

    This is currently impossible to achieve with esbuild.

    I guess this could be implemented by transforming such import() into Promise.resolve(() => require()), like in Provide an option to transform dynamic import to Promise.resolve(() => require(...)) #1084.

  • /* webpackPrefetch: true */ & /* webpackPreload: true */ which insert a <link rel="prefetch"> or <link rel="preload"> for the code-split chunk.

    It’s currently possible to achieve this with esbuild, but doing this is rather complicated. (You have to generate a metafile, parse it, insert prefetches during HTML generation, etc.)

  • /* webpackIgnore: 'true' */ which allows to ignore an import() call (and keep the native import() function in the bundle).

    It’s currently possible and fairly easy to achieve the same with esbuild using try/catch (Dynamic import(): how to ignore an import that’s passed a variable? #574). But webpackIgnore is slightly more elegant, I guess? 😅

@lalo-mx
Copy link

lalo-mx commented Jan 9, 2024

We have an app that uses dynamic load of languages with JSON files. We have currently around 200 files. The magic comment webpackChunkName [1] allows to create bundle of languages so they are easily updated as small json files per component but loaded in a few imports instead of hundred of files.

[1] https://webpack.js.org/api/module-methods/#webpackchunkname

@Tobbe
Copy link

Tobbe commented Jun 7, 2024

Yes please! Something like /* webpackIgnore: 'true' */ would be very much appreciated 🙏

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

No branches or pull requests

3 participants