diff --git a/packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js b/packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js
index 56054308cc..5a91c18f21 100644
--- a/packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js
+++ b/packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js
@@ -14,6 +14,33 @@ test('pwa', async () => {
   const project = await create('pwa-build', defaultPreset)
   expect(project.has('src/registerServiceWorker.js')).toBe(true)
 
+  await project.write(
+    'my-service-worker.js',
+    `var manifest = self.__WB_MANIFEST; console.log('some string value')`
+  )
+  await project.write(
+    'vue.config.js',
+    `module.exports = {
+  pwa: {
+    name: 'NAME',
+    themeColor: '#123456',
+    msTileColor: '#234567',
+    workboxPluginMode: 'InjectManifest',
+    workboxOptions: {
+      swSrc: './my-service-worker.js',
+      swDest: 'sw.js'
+    },
+    iconPaths: {
+      favicon32: 'path/to/favicon32.png',
+      favicon16: 'path/to/favicon16.png',
+      appleTouchIcon: 'path/to/apple-touch-icon.png',
+      maskIcon: 'path/to/safari-pinned-tab.svg',
+      msTileImage: 'path/to/mstile.png'
+    }
+  }
+}`
+  )
+
   const { stdout } = await project.run('vue-cli-service build')
   expect(stdout).toMatch('Build complete.')
 
@@ -26,6 +53,11 @@ test('pwa', async () => {
   expect(project.has('dist/manifest.json')).toBe(true)
   expect(project.has('dist/img/icons/android-chrome-512x512.png')).toBe(true)
 
+  // PWA service worker files
+  expect(project.has('dist/sw.js')).toBe(true)
+  const sw = await project.read('dist/sw.js')
+  expect(sw).toMatch(`some string value`)
+
   // Make sure the base preload/prefetch are not affected
   const index = await project.read('dist/index.html')
 
@@ -40,6 +72,22 @@ test('pwa', async () => {
   // favicon is not minified because it's technically a comment
   expect(index).toMatch(``)
   expect(index).toMatch(``)
+  // check custom meta tags
+  expect(index).toMatch(``)
+  expect(index).toMatch(``)
+  expect(index).toMatch(``)
+  expect(index).toMatch(``)
+  expect(index).toMatch(``)
+  expect(index).toMatch(``)
+
+  // PWA generated manifest
+  expect(project.has('dist/manifest.json')).toBe(true)
+  const manifest = JSON.parse(await project.read('dist/manifest.json'))
+  expect(manifest).toMatchObject({
+    'name': 'NAME',
+    'short_name': 'NAME',
+    'theme_color': '#123456'
+  })
 
   // should import service worker script
   const main = await project.read('src/main.js')
diff --git a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js
index c49afc256a..1e6a2e2e9a 100644
--- a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js
+++ b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js
@@ -55,8 +55,7 @@ const defaultIconPaths = {
 module.exports = class HtmlPwaPlugin {
   constructor (options = {}) {
     const iconPaths = Object.assign({}, defaultIconPaths, options.iconPaths)
-    delete options.iconPaths
-    this.options = Object.assign({ iconPaths: iconPaths }, defaults, options)
+    this.options = Object.assign({}, defaults, options, { iconPaths: iconPaths })
   }
 
   apply (compiler) {