Webpack Dynamic Import inject into <body> instead of <head>

Viewed 263

I have a project where I use turbolinks in conjunction with Webpack's dynamic imports.

What I have is that the initial javascript file is as small as possible and then for each page, I load the relevant javascript code:

document.addEventListener('turbolinks:load', () => {
  const moduleName = document.body.dataset.route;
  if (!moduleName) return;

  const chunkName = moduleName.replace('.', '/');
  import(/* webpackChunkName: "js/pages/[request]" */ `@pages/${chunkName}`)
    .catch((e) => {console.error(e);});
});

Webpack's dynamic imports are injected into the <head> portion of the page which is great for any other use case where you want to load 3rd party packages. However, since I want to load a page specific script, I need the script to re-run on every page change.

Since I'm using Turbolinks, there is no page refresh. What Turbolinks does is it hijacks the request, and perform the request as an XHR request. Then, it replaces the <body> tag and merges the <head> tag.

Now the issue is that whenever Turbolinks merges the head, it will keep the per-page loaded script causing the script to not re-run on subsequent requests to that same page (remember, no page refresh occurred).

The best way I can think of solving this issue is to tell webpack to inject certain scripts (such as page-specific scripts) into the <body> tag as it gets completely replaced on each page (visit). In fact, this is what Turbolinks mentions in their docs to do when you have per-page specific scripts.

I tried to find out how to do it but was unable to find any resource about it.

There is actually another solution and that is to export a default function from every page-specific page and simply call that function after the import:

import(/* webpackChunkName: "js/pages/[request]" */ `@pages/${chunkName}`)
  .then(p => p.default())

The only downside to this is that I have to remember to export a default function for each page module and my module code is always nested (due to being inside a function).

0 Answers
Related