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

Automatically bundle dynamic import() #1093

Open
frank-dspeed opened this Issue Sep 11, 2018 · 6 comments

Comments

Projects
None yet
4 participants
@frank-dspeed
Copy link
Contributor

frank-dspeed commented Sep 11, 2018

Steal should search for import() in ES6 code and bundle that stuff also

@roemhildtg

This comment has been minimized.

Copy link

roemhildtg commented Sep 13, 2018

Yeah, It would be super slick if steal would handle import similar to how webpack does. I think what webpack does is it scans files for import(...) and creates a "side-bundle". Its pretty capable too, like you can configure webpack to scan and bundle files matching a wildcard pattern in a directory. So for instance:

If I use

const config = route.data.configName;
import('config/${config}').then(config => {

});

webpack will automatically side bundle everything in config/....js as an individual bundle.

@justinbmeyer

This comment has been minimized.

Copy link
Contributor

justinbmeyer commented Sep 13, 2018

Just an FYI, wildcards are supported in the bundle config now.

@justinbmeyer

This comment has been minimized.

Copy link
Contributor

justinbmeyer commented Sep 13, 2018

To do this, you could probably search the ast for this and then update the bundle config.

@frank-dspeed

This comment has been minimized.

Copy link
Contributor

frank-dspeed commented Sep 23, 2018

i am also not sure how to do this justin's suggestion looks valid for me so this could get added to steal tools maybe to scan for imports and modify bundle config.

  • Algo 1 (Most best way)
    While bundling create a extra bundle per bundle with the bundlename-dynamic slug
  • Algo 2 (Easy to do)
    While bundling Modify the bundle Config via a hook.

@matthewp matthewp changed the title Handle Dynamic imports in bundels Automatically bundle dynamic import() Nov 15, 2018

@matthewp

This comment has been minimized.

Copy link
Member

matthewp commented Nov 15, 2018

We're going to turn this into a proposal.

tldr; Make it so that steal-tools will automatically detect uses of import() and steal.import() within JavaScript code and add those as bundles.

This was discussed on a recent live stream (19:28).

The Problem

If you are creating a progressively loaded app you will likely split it into separate "pages", where each page is a separate bundle. So code like this:

function switchPage(page) {
  if(page === "cart") {
    steal.import("~/cart/").then(mod => {
      document.body.appendChild(new mod.Cart());
    });
  }

  if(page === "home") {
    steal.import("~/home/").then(mod => {
      document.body.appendChild(new mod.Home());
    });
  }
}

You will need to remember to update the bundle configuration in package.json:

{
  "steal": {
    "bundle": [
      "~/cart/cart",
      "~/home/home"
    ]
  }
}

Let's say you later add a new page, product. If you forget to add this to bundle your build will succeed but when you go to production the app won't work correctly.

If you're using continuous deployment this becomes quite a big problem.

The Solution

The proposal is to add to steal-tools the ability to detect these steal.import() and likely import() calls through AST parsing and add these modules as bundles. This will prevent the need from manually setting the bundle configuration.

@matthewp matthewp transferred this issue from stealjs/steal Nov 15, 2018

@roemhildtg

This comment has been minimized.

Copy link

roemhildtg commented Nov 17, 2018

Also consider the following:

route.data.on('config', newConfig => {
    import(`~/config/${newConfig}`).then(configModule => {
        app.assign(configModule.default); 
    });
});

And the following directory structure:

app 
  /config
     /config1.js
     /config2.js
    /....

Steal might detect each of these config files and side bundle them.

Webpack does this sort of thing and it is surprisingly nice. For instance, webpack provides configuration in how to locate these modules by using special comments:

function loadConfig(path) {
    import(
        /*
            webpackMode: "lazy",
            webpackInclude: /[A-z]+\.js(on)?/
        */
        `./config/apps/${path}`
    ).then((config) => {
        config = config.default;

        const app = document.querySelector('dl-app');
        if (app) {
            document.body.removeChild(app);
        }
        document.body.appendChild(stache('<dl-app props="config" />')({config}));
    });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment