Skip to content

Commit 0bc2aeb

Browse files
committed
chore: merge dev
2 parents 4d0b690 + ebffdf0 commit 0bc2aeb

File tree

19 files changed

+440
-12335
lines changed

19 files changed

+440
-12335
lines changed

packages/@vue/cli-plugin-babel/__tests__/transpileDependencies.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ beforeAll(async () => {
4242
test('dep from node_modules should not been transpiled', async () => {
4343
const { stdout } = await project.run('vue-cli-service build')
4444

45-
let $vendorjs = stdout.match(/(js\/vendors~app\.[^.]+\.js)/)[1]
45+
let $vendorjs = stdout.match(/(js\/chunk-vendors\.[^.]+\.js)/)[1]
4646

4747
$vendorjs = `dist/${$vendorjs}`
4848
$vendorjs = await project.read($vendorjs)
@@ -58,7 +58,7 @@ test('dep from node_modules should been transpiled', async () => {
5858

5959
const { stdout } = await project.run('vue-cli-service build')
6060

61-
let $vendorjs = stdout.match(/(js\/vendors~app\.[^.]+\.js)/)[1]
61+
let $vendorjs = stdout.match(/(js\/chunk-vendors\.[^.]+\.js)/)[1]
6262

6363
$vendorjs = `dist/${$vendorjs}`
6464
$vendorjs = await project.read($vendorjs)
Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
1-
module.exports = (api, { lintOnSave }) => {
2-
if (lintOnSave) {
1+
module.exports = (api, options) => {
2+
if (options.lintOnSave) {
33
const extensions = require('./eslintOptions').extensions(api)
4-
const cacheIdentifier = genCacheIdentifier(api.resolve('.'))
4+
5+
// eslint-loader doesn't bust cache when eslint config changes
6+
// so we have to manually generate a cache identifier that takes the config
7+
// into account.
8+
const { genCacheConfig } = require('@vue/cli-shared-utils')
9+
const { cacheIdentifier } = genCacheConfig(
10+
api,
11+
options,
12+
[
13+
'eslint-loader',
14+
'eslint'
15+
],
16+
[
17+
'.eslintrc.js',
18+
'.eslintrc.yaml',
19+
'.eslintrc.yml',
20+
'.eslintrc.json',
21+
'.eslintrc',
22+
'package.json'
23+
]
24+
)
525

626
api.chainWebpack(webpackConfig => {
727
webpackConfig.module
@@ -18,7 +38,7 @@ module.exports = (api, { lintOnSave }) => {
1838
extensions,
1939
cache: true,
2040
cacheIdentifier,
21-
emitWarning: lintOnSave !== 'error',
41+
emitWarning: options.lintOnSave !== 'error',
2242
formatter: require('eslint/lib/formatters/codeframe')
2343
})
2444
})
@@ -38,33 +58,3 @@ module.exports = (api, { lintOnSave }) => {
3858
require('./lint')(args, api)
3959
})
4060
}
41-
42-
// eslint-loader doesn't bust cache when eslint config changes
43-
// so we have to manually generate a cache identifier that takes the config
44-
// into account.
45-
function genCacheIdentifier (context) {
46-
const fs = require('fs')
47-
const path = require('path')
48-
const files = [
49-
'.eslintrc.js',
50-
'.eslintrc.yaml',
51-
'.eslintrc.yml',
52-
'.eslintrc.json',
53-
'.eslintrc',
54-
'package.json'
55-
]
56-
57-
const configTimeStamp = (() => {
58-
for (const file of files) {
59-
if (fs.existsSync(path.join(context, file))) {
60-
return fs.statSync(file).mtimeMs
61-
}
62-
}
63-
})()
64-
65-
return JSON.stringify({
66-
'eslint-loader': require('eslint-loader/package.json').version,
67-
'eslint': require('eslint/package.json').version,
68-
'config': configTimeStamp
69-
})
70-
}

packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ test('pwa', async () => {
3131

3232
// should split and preload app.js & vendor.js
3333
expect(index).toMatch(/<link [^>]+js\/app[^>]+\.js rel=preload>/)
34-
expect(index).toMatch(/<link [^>]+js\/vendors~app[^>]+\.js rel=preload>/)
34+
expect(index).toMatch(/<link [^>]+js\/chunk-vendors[^>]+\.js rel=preload>/)
3535
// should preload css
3636
expect(index).toMatch(/<link [^>]+app[^>]+\.css rel=preload>/)
3737

packages/@vue/cli-plugin-typescript/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module.exports = (api, options) => {
4141
loader: 'ts-loader',
4242
options: {
4343
transpileOnly: true,
44-
appendTsSuffixTo: [/\.vue$/],
44+
appendTsSuffixTo: ['\\.vue$'],
4545
// https://github.com/TypeStrong/ts-loader#happypackmode-boolean-defaultfalse
4646
happyPackMode: useThreads
4747
}
@@ -50,7 +50,7 @@ module.exports = (api, options) => {
5050
tsxRule.use('ts-loader').loader('ts-loader').tap(options => {
5151
options = Object.assign({}, options)
5252
delete options.appendTsSuffixTo
53-
options.appendTsxSuffixTo = [/\.vue$/]
53+
options.appendTsxSuffixTo = ['\\.vue$']
5454
return options
5555
})
5656

packages/@vue/cli-service/__tests__/build.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ test('build', async () => {
2626
const index = await project.read('dist/index.html')
2727
// should split and preload app.js & vendor.js
2828
expect(index).toMatch(/<link [^>]+js\/app[^>]+\.js rel=preload>/)
29-
expect(index).toMatch(/<link [^>]+js\/vendors~app[^>]+\.js rel=preload>/)
29+
expect(index).toMatch(/<link [^>]+js\/chunk-vendors[^>]+\.js rel=preload>/)
3030
// should preload css
3131
expect(index).toMatch(/<link [^>]+app[^>]+\.css rel=preload>/)
3232

packages/@vue/cli-service/__tests__/css.spec.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@ const genConfig = (pkg = {}, env) => {
2222
return config
2323
}
2424

25-
const findRule = (config, lang, index = 2) => {
25+
const findRule = (config, lang, index = 3) => {
2626
const baseRule = config.module.rules.find(rule => {
2727
return rule.test.test(`.${lang}`)
2828
})
29-
// all CSS rules have oneOf with two child rules, one for <style lang="module">
30-
// and one for normal imports
29+
// all CSS rules have 4 oneOf rules:
30+
// - <style lang="module"> in Vue files
31+
// - <style> in Vue files
32+
// - *.modules.css imports from JS
33+
// - *.css imports from JS
3134
return baseRule.oneOf[index]
3235
}
3336

@@ -76,7 +79,13 @@ test('production defaults', () => {
7679
})
7780

7881
test('CSS Modules rules', () => {
79-
const config = genConfig()
82+
const config = genConfig({
83+
vue: {
84+
css: {
85+
modules: true
86+
}
87+
}
88+
})
8089
LANGS.forEach(lang => {
8190
const expected = {
8291
importLoaders: lang === 'css' ? 1 : 2, // no postcss-loader
@@ -85,10 +94,12 @@ test('CSS Modules rules', () => {
8594
sourceMap: false,
8695
modules: true
8796
}
88-
// module-query rules
97+
// vue-modules rules
8998
expect(findOptions(config, lang, 'css', 0)).toEqual(expected)
90-
// module-ext rules
91-
expect(findOptions(config, lang, 'css', 1)).toEqual(expected)
99+
// normal-modules rules
100+
expect(findOptions(config, lang, 'css', 2)).toEqual(expected)
101+
// normal rules
102+
expect(findOptions(config, lang, 'css', 3)).toEqual(expected)
92103
})
93104
})
94105

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
jest.setTimeout(30000)
2+
3+
const path = require('path')
4+
const portfinder = require('portfinder')
5+
const { defaultPreset } = require('@vue/cli/lib/options')
6+
const { createServer } = require('http-server')
7+
const create = require('@vue/cli-test-utils/createTestProject')
8+
const serve = require('@vue/cli-test-utils/serveWithPuppeteer')
9+
const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
10+
11+
async function makeProjectMultiPage (project) {
12+
await project.write('vue.config.js', `
13+
module.exports = {
14+
pages: {
15+
index: { entry: 'src/main.js' },
16+
foo: { entry: 'src/foo.js' },
17+
bar: { entry: 'src/bar.js' }
18+
},
19+
chainWebpack: config => {
20+
const splitOptions = config.optimization.get('splitChunks')
21+
config.optimization.splitChunks(Object.assign({}, splitOptions, {
22+
minSize: 10000
23+
}))
24+
}
25+
}
26+
`)
27+
await project.write('src/foo.js', `
28+
import Vue from 'vue'
29+
new Vue({
30+
el: '#app',
31+
render: h => h('h1', 'Foo')
32+
})
33+
`)
34+
await project.write('src/bar.js', `
35+
import Vue from 'vue'
36+
import App from './App.vue'
37+
new Vue({
38+
el: '#app',
39+
render: h => h(App)
40+
})
41+
`)
42+
const app = await project.read('src/App.vue')
43+
await project.write('src/App.vue', app.replace(
44+
`import HelloWorld from './components/HelloWorld.vue'`,
45+
`const HelloWorld = () => import('./components/HelloWorld.vue')`
46+
))
47+
}
48+
49+
test('serve w/ multi page', async () => {
50+
const project = await create('e2e-multi-page-serve', defaultPreset)
51+
52+
await makeProjectMultiPage(project)
53+
54+
await serve(
55+
() => project.run('vue-cli-service serve'),
56+
async ({ page, url, helpers }) => {
57+
expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
58+
59+
await page.goto(`${url}/foo.html`)
60+
expect(await helpers.getText('h1')).toMatch(`Foo`)
61+
62+
await page.goto(`${url}/bar.html`)
63+
expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
64+
}
65+
)
66+
})
67+
68+
let server, browser, page
69+
test('build w/ multi page', async () => {
70+
const project = await create('e2e-multi-page-build', defaultPreset)
71+
72+
await makeProjectMultiPage(project)
73+
74+
const { stdout } = await project.run('vue-cli-service build')
75+
expect(stdout).toMatch('Build complete.')
76+
77+
// should generate the HTML pages
78+
expect(project.has('dist/index.html')).toBe(true)
79+
expect(project.has('dist/foo.html')).toBe(true)
80+
expect(project.has('dist/bar.html')).toBe(true)
81+
82+
const assertSharedAssets = file => {
83+
// should split and preload vendor chunk
84+
expect(file).toMatch(/<link [^>]+js\/chunk-vendors[^>]+\.js rel=preload>/)
85+
// should split and preload common js and css
86+
expect(file).toMatch(/<link [^>]+js\/chunk-common[^>]+\.js rel=preload>/)
87+
expect(file).toMatch(/<link [^>]+chunk-common[^>]+\.css rel=preload>/)
88+
// should load common css
89+
expect(file).toMatch(/<link href=\/css\/chunk-common\.\w+\.css rel=stylesheet>/)
90+
// should load common js
91+
expect(file).toMatch(/<script [^>]+src=\/js\/chunk-vendors\.\w+\.js>/)
92+
expect(file).toMatch(/<script [^>]+src=\/js\/chunk-common\.\w+\.js>/)
93+
}
94+
95+
const index = await project.read('dist/index.html')
96+
assertSharedAssets(index)
97+
// should preload correct page file
98+
expect(index).toMatch(/<link [^>]+js\/index[^>]+\.js rel=preload>/)
99+
expect(index).not.toMatch(/<link [^>]+js\/foo[^>]+\.js rel=preload>/)
100+
expect(index).not.toMatch(/<link [^>]+js\/bar[^>]+\.js rel=preload>/)
101+
// should prefetch async chunk js and css
102+
expect(index).toMatch(/<link [^>]+css\/0\.\w+\.css rel=prefetch>/)
103+
expect(index).toMatch(/<link [^>]+js\/0\.\w+\.js rel=prefetch>/)
104+
// should load correct page js
105+
expect(index).toMatch(/<script [^>]+src=\/js\/index\.\w+\.js>/)
106+
expect(index).not.toMatch(/<script [^>]+src=\/js\/foo\.\w+\.js>/)
107+
expect(index).not.toMatch(/<script [^>]+src=\/js\/bar\.\w+\.js>/)
108+
109+
const foo = await project.read('dist/foo.html')
110+
assertSharedAssets(foo)
111+
// should preload correct page file
112+
expect(foo).not.toMatch(/<link [^>]+js\/index[^>]+\.js rel=preload>/)
113+
expect(foo).toMatch(/<link [^>]+js\/foo[^>]+\.js rel=preload>/)
114+
expect(foo).not.toMatch(/<link [^>]+js\/bar[^>]+\.js rel=preload>/)
115+
// should not prefetch async chunk js and css because it's not used by
116+
// this entry
117+
expect(foo).not.toMatch(/<link [^>]+css\/0\.\w+\.css rel=prefetch>/)
118+
expect(foo).not.toMatch(/<link [^>]+js\/0\.\w+\.js rel=prefetch>/)
119+
// should load correct page js
120+
expect(foo).not.toMatch(/<script [^>]+src=\/js\/index\.\w+\.js>/)
121+
expect(foo).toMatch(/<script [^>]+src=\/js\/foo\.\w+\.js>/)
122+
expect(foo).not.toMatch(/<script [^>]+src=\/js\/bar\.\w+\.js>/)
123+
124+
const bar = await project.read('dist/bar.html')
125+
assertSharedAssets(bar)
126+
// should preload correct page file
127+
expect(bar).not.toMatch(/<link [^>]+js\/index[^>]+\.js rel=preload>/)
128+
expect(bar).not.toMatch(/<link [^>]+js\/foo[^>]+\.js rel=preload>/)
129+
expect(bar).toMatch(/<link [^>]+js\/bar[^>]+\.js rel=preload>/)
130+
// should prefetch async chunk js and css
131+
expect(bar).toMatch(/<link [^>]+css\/0\.\w+\.css rel=prefetch>/)
132+
expect(bar).toMatch(/<link [^>]+js\/0\.\w+\.js rel=prefetch>/)
133+
// should load correct page js
134+
expect(bar).not.toMatch(/<script [^>]+src=\/js\/index\.\w+\.js>/)
135+
expect(bar).not.toMatch(/<script [^>]+src=\/js\/foo\.\w+\.js>/)
136+
expect(bar).toMatch(/<script [^>]+src=\/js\/bar\.\w+\.js>/)
137+
138+
// assert pages work
139+
const port = await portfinder.getPortPromise()
140+
server = createServer({ root: path.join(project.dir, 'dist') })
141+
142+
await new Promise((resolve, reject) => {
143+
server.listen(port, err => {
144+
if (err) return reject(err)
145+
resolve()
146+
})
147+
})
148+
149+
const url = `http://localhost:${port}/`
150+
const launched = await launchPuppeteer(url)
151+
browser = launched.browser
152+
page = launched.page
153+
154+
const getH1Text = async () => page.evaluate(() => {
155+
return document.querySelector('h1').textContent
156+
})
157+
158+
expect(await getH1Text()).toMatch('Welcome to Your Vue.js App')
159+
160+
await page.goto(`${url}foo.html`)
161+
expect(await getH1Text()).toMatch('Foo')
162+
163+
await page.goto(`${url}bar.html`)
164+
expect(await getH1Text()).toMatch('Welcome to Your Vue.js App')
165+
})
166+
167+
afterAll(async () => {
168+
await browser.close()
169+
server.close()
170+
})

packages/@vue/cli-service/__tests__/serve.spec.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
jest.setTimeout(45000)
1+
jest.setTimeout(60000)
22

3+
const path = require('path')
4+
const fs = require('fs-extra')
35
const { defaultPreset } = require('@vue/cli/lib/options')
46
const create = require('@vue/cli-test-utils/createTestProject')
57
const serve = require('@vue/cli-test-utils/serveWithPuppeteer')
@@ -50,8 +52,6 @@ test('serve with router', async () => {
5052
test('serve with inline entry', async () => {
5153
const project = await create('e2e-serve-inline-entry', defaultPreset)
5254

53-
const path = require('path')
54-
const fs = require('fs-extra')
5555
await fs.move(
5656
path.resolve(project.dir, 'src/main.js'),
5757
path.resolve(project.dir, 'src/index.js')
@@ -72,3 +72,24 @@ test('serve with inline entry', async () => {
7272
}
7373
)
7474
})
75+
76+
test('serve with no public dir', async () => {
77+
const project = await create('e2e-serve-no-public', defaultPreset)
78+
79+
await fs.remove(path.resolve(project.dir, 'public'))
80+
81+
await serve(
82+
() => project.run('vue-cli-service serve'),
83+
async ({ nextUpdate, helpers }) => {
84+
const msg = `Welcome to Your Vue.js App`
85+
expect(await helpers.getText('h1')).toMatch(msg)
86+
87+
// test hot reload
88+
const file = await project.read(`src/App.vue`)
89+
project.write(`src/App.vue`, file.replace(msg, `Updated`))
90+
await nextUpdate() // wait for child stdout update signal
91+
await sleep(1000) // give the client time to update
92+
expect(await helpers.getText('h1')).toMatch(`Updated`)
93+
}
94+
)
95+
})

0 commit comments

Comments
 (0)