vue-hot-reload-api icon indicating copy to clipboard operation
vue-hot-reload-api copied to clipboard

It should actually do a full reload when it's required, not just reporting a need

Open nskazki opened this issue 3 years ago • 0 comments
trafficstars

I think it should actually do a full reload when it's required, not just reporting a need because it's really simple to miss the report among other HMR/app's messages. If making it a default behaviour is too much, an option would suffice.

https://github.com/vuejs/vue-hot-reload-api/blob/45936fbfcb1c4c3ffc5702f4bb7101a9aee6dd43/src/index.js#L122-L125 https://github.com/vuejs/vue-hot-reload-api/blob/45936fbfcb1c4c3ffc5702f4bb7101a9aee6dd43/src/index.js#L246-L248

To anyone who also think so, you can use this snippet until the option is introduce or the default behaviour is changed:

// webpack.config.js
const VueReload = require('../plugins/vue-reload')

module.exports = {
  plugins: [new VueReload()]
}

// vue-reload.js
module.exports = class VueReloadPlugin {
  apply(compiler) {
    compiler.hooks.compilation.tap('VueReloadPlugin', compilation => {
      compilation.hooks.processAssets.tap({ name: 'VueReloadPlugin', stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS  }, () => {
        const patched = []

        for (const chunk of compilation.chunks) {
          const anyVueModules = chunk.getModules().some((module) => /\.vue/.test(module.resource))
          if (!anyVueModules) {
            continue
          }

          for (const file of chunk.files) {
            const isJSFile = /\.js/.test(file)
            if (!isJSFile) {
              continue
            }

            compilation.updateAsset(file, (input) => {
              // the \\n part is necessary in case the source code is turned into an eval string
              const re = /(console\.warn\([\s\\n]*['"](?:Something went wrong during Vue component hot-reload.|Root or manually mounted instance modified.) Full reload required.['"][\s\\n]*\))/g
              const matches = Array.from(input.source().matchAll(re))
              if (matches.length === 0) {
                return input
              }

              const output = new ReplaceSource(input)
              for (const match of matches) {
                const position = match.index + match[1].length
                output.insert(position, ';window.location.reload();')
              }

              patched.push(file)
              return output
            })
          }
        }

        if (patched.length !== 0) {
          console.info('vue-reload-plugin: patched', patched.join(', '))
        }
      })
    })
  }
}

nskazki avatar Feb 13 '22 22:02 nskazki