diff --git a/packages/@vue/cli-service/__tests__/build.spec.js b/packages/@vue/cli-service/__tests__/build.spec.js
index 34d469dddd..7728253305 100644
--- a/packages/@vue/cli-service/__tests__/build.spec.js
+++ b/packages/@vue/cli-service/__tests__/build.spec.js
@@ -26,7 +26,7 @@ test('build', async () => {
const index = await project.read('dist/index.html')
// should split and preload app.js & vendor.js
expect(index).toMatch(/]+js\/app[^>]+\.js rel=preload>/)
- expect(index).toMatch(/]+js\/vendors~app[^>]+\.js rel=preload>/)
+ expect(index).toMatch(/]+js\/chunk-vendors[^>]+\.js rel=preload>/)
// should preload css
expect(index).toMatch(/]+app[^>]+\.css rel=preload>/)
diff --git a/packages/@vue/cli-service/__tests__/multiPage.spec.js b/packages/@vue/cli-service/__tests__/multiPage.spec.js
new file mode 100644
index 0000000000..56918a09f4
--- /dev/null
+++ b/packages/@vue/cli-service/__tests__/multiPage.spec.js
@@ -0,0 +1,170 @@
+jest.setTimeout(30000)
+
+const path = require('path')
+const portfinder = require('portfinder')
+const { defaultPreset } = require('@vue/cli/lib/options')
+const { createServer } = require('http-server')
+const create = require('@vue/cli-test-utils/createTestProject')
+const serve = require('@vue/cli-test-utils/serveWithPuppeteer')
+const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
+
+async function makeProjectMultiPage (project) {
+ await project.write('vue.config.js', `
+ module.exports = {
+ pages: {
+ index: { entry: 'src/main.js' },
+ foo: { entry: 'src/foo.js' },
+ bar: { entry: 'src/bar.js' }
+ },
+ chainWebpack: config => {
+ const splitOptions = config.optimization.get('splitChunks')
+ config.optimization.splitChunks(Object.assign({}, splitOptions, {
+ minSize: 10000
+ }))
+ }
+ }
+ `)
+ await project.write('src/foo.js', `
+ import Vue from 'vue'
+ new Vue({
+ el: '#app',
+ render: h => h('h1', 'Foo')
+ })
+ `)
+ await project.write('src/bar.js', `
+ import Vue from 'vue'
+ import App from './App.vue'
+ new Vue({
+ el: '#app',
+ render: h => h(App)
+ })
+ `)
+ const app = await project.read('src/App.vue')
+ await project.write('src/App.vue', app.replace(
+ `import HelloWorld from './components/HelloWorld.vue'`,
+ `const HelloWorld = () => import('./components/HelloWorld.vue')`
+ ))
+}
+
+test('serve w/ multi page', async () => {
+ const project = await create('e2e-multi-page-serve', defaultPreset)
+
+ await makeProjectMultiPage(project)
+
+ await serve(
+ () => project.run('vue-cli-service serve'),
+ async ({ page, url, helpers }) => {
+ expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
+
+ await page.goto(`${url}/foo.html`)
+ expect(await helpers.getText('h1')).toMatch(`Foo`)
+
+ await page.goto(`${url}/bar.html`)
+ expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
+ }
+ )
+})
+
+let server, browser, page
+test('build w/ multi page', async () => {
+ const project = await create('e2e-multi-page-build', defaultPreset)
+
+ await makeProjectMultiPage(project)
+
+ const { stdout } = await project.run('vue-cli-service build')
+ expect(stdout).toMatch('Build complete.')
+
+ // should generate the HTML pages
+ expect(project.has('dist/index.html')).toBe(true)
+ expect(project.has('dist/foo.html')).toBe(true)
+ expect(project.has('dist/bar.html')).toBe(true)
+
+ const assertSharedAssets = file => {
+ // should split and preload vendor chunk
+ expect(file).toMatch(/]+js\/chunk-vendors[^>]+\.js rel=preload>/)
+ // should split and preload common js and css
+ expect(file).toMatch(/]+js\/chunk-common[^>]+\.js rel=preload>/)
+ expect(file).toMatch(/]+chunk-common[^>]+\.css rel=preload>/)
+ // should load common css
+ expect(file).toMatch(//)
+ // should load common js
+ expect(file).toMatch(/