11

I have the following function a file @/lang/index.js:

async function fetchMessages(locale) {
  const module = await import(/*
    webpackChunkName: "lang/[request]",
    webpackExclude: /index/
  */ `@/lang/${locale}`)

  return module.default
}

I would like to hot-reload the modules imported by this function. I've tried a several different variations of module.hot.accept() but without success.

Here's my hot reload code at the end of the same file that doesn't work:

if (process.env.NODE_ENV !== "production" && module.hot) {
  module.hot.accept(["./en-US"], () => {
    const { locale } = i18n
    fetchMessages(locale).then((strings) => {
      i18n.setLocaleMessage(locale, strings)
    })
  })
}

Any thoughts? I would like to hot-reload my language files when a change is detected.

Thanks!

matpie
  • 17,033
  • 9
  • 61
  • 82
  • I tracked down the root of the problem to `index.js` not being the direct parent to `en-US.js`. For each `import()` expression a new "module" is created. If I use Webpack's internal identifier for that module (`"./src/lang lazy recursive ^\\.\\/.*$ exclude: index"`) then it will work but the compiler will try to resolve that string to a module and throws an error. – matpie May 10 '19 at 23:47

1 Answers1

0

Webpack currently has an open issue for this "bug". I found Webpack#8637 after some searching.

Some workarounds from that page include:

  • Create a separate file which contains the import context, accept that separate file.
  • Use module.hot.accept(module.children[0].id, ...)

The solution I'm currently using is I found the generated identifier for the context, and saved it to a variable is passed in to module.hot.accept() like so:

const asyncChunkId = "./src/lang lazy recursive ^\\.\\/.*$ exclude: index"
module.hot.accept(asyncChunkId, () => { /* ... */ })

It's rather fragile, but does the job for now.

matpie
  • 17,033
  • 9
  • 61
  • 82