diff --git a/packages/@vue/babel-preset-app/index.js b/packages/@vue/babel-preset-app/index.js
index f2f712cc87..51b0865f62 100644
--- a/packages/@vue/babel-preset-app/index.js
+++ b/packages/@vue/babel-preset-app/index.js
@@ -43,14 +43,14 @@ function getIntersectionTargets (targets, constraintTargets) {
   return intersection
 }
 
-function getModernTargets (targets) {
-  const allModernTargets = getTargets(
+function getModuleTargets (targets) {
+  const allModuleTargets = getTargets(
     { esmodules: true },
     { ignoreBrowserslistConfig: true }
   )
 
   // use the intersection of modern mode browsers and user defined targets config
-  return getIntersectionTargets(targets, allModernTargets)
+  return getIntersectionTargets(targets, allModuleTargets)
 }
 
 function getWCTargets (targets) {
@@ -177,7 +177,7 @@ module.exports = (context, options = {}) => {
     targets = getWCTargets(targets)
   } else if (process.env.VUE_CLI_MODERN_BUILD) {
     // targeting browsers that at least support `)
 
   // `--no-unsafe-inline` option
@@ -130,6 +130,36 @@ test('--no-module', async () => {
   expect(files.some(f => /-legacy.js/.test(f))).toBe(false)
 })
 
+test('should use correct hash for fallback bundles', async () => {
+  const project = await create('legacy-hash', defaultPreset)
+
+  const { stdout } = await project.run('vue-cli-service build')
+  expect(stdout).toMatch('Build complete.')
+
+  const index = await project.read('dist/index.html')
+  const jsFiles = (await fs.readdir(path.join(project.dir, 'dist/js'))).filter(f => f.endsWith('.js'))
+  for (const f of jsFiles) {
+    expect(index).toMatch(`