Skip to content

Commit cd66b05

Browse files
author
Barthélémy Ledoux
authored
fix: make vite dev server open on a free port (#15756)
1 parent 7314d66 commit cd66b05

File tree

5 files changed

+42
-53
lines changed

5 files changed

+42
-53
lines changed

npm/vite-dev-server/cypress.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"pluginsFile": "cypress/plugins.js",
3+
"video": false,
34
"testFiles": "**/*.spec.*",
45
"componentFolder": "cypress/components",
56
"supportFile": "cypress/support/support.js"

npm/vite-dev-server/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"watch": "tsc -w"
1313
},
1414
"dependencies": {
15-
"debug": "4.3.2"
15+
"debug": "^4.3.2",
16+
"get-port": "^5.1.1"
1617
},
1718
"devDependencies": {
1819
"@cypress/react": "0.0.0-development",
@@ -27,7 +28,7 @@
2728
"vue": "3.0.9"
2829
},
2930
"peerDependencies": {
30-
"vite": ">= 2"
31+
"vite": ">= 2.1.3"
3132
},
3233
"files": [
3334
"dist",

npm/vite-dev-server/src/index.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
1-
import { EventEmitter } from 'events'
21
import { debug as debugFn } from 'debug'
3-
import { start as createDevServer } from './startServer'
4-
import { UserConfig } from 'vite'
52
import { Server } from 'http'
3+
import { start as createDevServer, StartDevServer } from './startServer'
64
const debug = debugFn('cypress:vite-dev-server:vite')
75

8-
interface Options {
9-
specs: any[] // Cypress.Cypress['spec'][] // Why isn't this working? It works for webpack-dev-server
10-
config: Record<string, string>
11-
devServerEvents: EventEmitter
12-
[key: string]: unknown
13-
}
14-
15-
export interface StartDevServer {
16-
/* this is the Cypress options object */
17-
options: Options
18-
/* support passing a path to the user's webpack config */
19-
viteConfig?: UserConfig // TODO: implement taking in the user's vite configuration. Right now we don't
20-
}
6+
export { StartDevServer }
217

228
export interface ResolvedDevServerConfig {
239
port: number

npm/vite-dev-server/src/makeCypressPlugin.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { EventEmitter } from 'events'
21
import { resolve } from 'path'
32
import { readFile } from 'fs'
43
import { promisify } from 'util'
@@ -24,7 +23,7 @@ export const makeCypressPlugin = (
2423
if (env) {
2524
return {
2625
define: {
27-
'import.meta.env.__cypress_supportPath': JSON.stringify(resolve(projectRoot, supportFilePath)),
26+
'import.meta.env.__cypress_supportPath': JSON.stringify(supportFilePath ? resolve(projectRoot, supportFilePath) : undefined),
2827
'import.meta.env.__cypress_originAutUrl': JSON.stringify('__cypress/iframes/'),
2928
},
3029
}
Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,49 @@
11
import Debug from 'debug'
2-
import { StartDevServer } from '.'
3-
import { createServer, ViteDevServer, InlineConfig } from 'vite'
2+
import { createServer, ViteDevServer, InlineConfig, UserConfig } from 'vite'
43
import { dirname, resolve } from 'path'
4+
import getPort from 'get-port'
55
import { makeCypressPlugin } from './makeCypressPlugin'
6-
import { EventEmitter } from 'events'
76

87
const debug = Debug('cypress:vite-dev-server:start')
98

10-
// TODO: Pull in types for Options so we can infer these
11-
const serverConfig = (projectRoot: string, supportFilePath: string, devServerEvents: EventEmitter): InlineConfig => {
12-
return {
13-
root: resolve(__dirname, projectRoot),
14-
base: '/__cypress/src/',
15-
plugins: [makeCypressPlugin(projectRoot, supportFilePath, devServerEvents)],
16-
server: {
17-
port: 0,
18-
},
19-
resolve: {
20-
alias: {
21-
// Necessary to avoid a "prefixIdentifiers" issue from slots mounting
22-
// Could be resolved in test-utils
23-
'@vue/compiler-core': resolve(dirname(require.resolve('@vue/compiler-core')), 'dist', 'compiler-core.cjs.js'),
24-
},
25-
},
26-
}
9+
interface Options {
10+
specs: Cypress.Cypress['spec'][]
11+
config: Record<string, string>
12+
devServerEvents: EventEmitter
13+
[key: string]: unknown
14+
}
15+
16+
export interface StartDevServer {
17+
/* this is the Cypress options object */
18+
options: Options
19+
/* support passing a path to the user's webpack config */
20+
viteConfig?: UserConfig // TODO: implement taking in the user's vite configuration. Right now we don't
2721
}
2822

29-
const resolveServerConfig = ({ viteConfig, options }: StartDevServer) => {
30-
const defaultServerConfig = serverConfig(
31-
options.config.projectRoot,
32-
options.config.supportFile,
33-
options.devServerEvents,
34-
)
23+
const resolveServerConfig = async ({ viteConfig, options }: StartDevServer): Promise<InlineConfig> => {
24+
const { projectRoot, supportFile } = options.config
3525

36-
const requiredOptions = {
37-
base: defaultServerConfig.base,
38-
root: defaultServerConfig.root,
26+
const requiredOptions: InlineConfig = {
27+
base: '/__cypress/src/',
28+
root: projectRoot,
3929
}
4030

41-
const finalConfig = { ...defaultServerConfig, ...viteConfig, ...requiredOptions }
31+
const finalConfig: InlineConfig = { ...viteConfig, ...requiredOptions }
32+
33+
finalConfig.plugins = [...(viteConfig.plugins || []), makeCypressPlugin(projectRoot, supportFile, options.devServerEvents)]
34+
35+
// This alias is necessary to avoid a "prefixIdentifiers" issue from slots mounting
36+
// only cjs compiler-core accepts using prefixIdentifiers in slots which vue test utils use.
37+
// Could we resolve this usage in test-utils?
38+
finalConfig.resolve = finalConfig.resolve || {}
39+
finalConfig.resolve.alias = {
40+
...finalConfig.resolve.alias,
41+
'@vue/compiler-core': resolve(dirname(require.resolve('@vue/compiler-core')), 'dist', 'compiler-core.cjs.js'),
42+
},
43+
44+
finalConfig.server = finalConfig.server || {}
4245

43-
finalConfig.plugins = [...(viteConfig.plugins || []), defaultServerConfig.plugins[0]]
44-
finalConfig.server.port = defaultServerConfig.server.port
46+
finalConfig.server.port = await getPort({ port: 3000, host: 'localhost' }),
4547

4648
debug(`the resolved server config is ${JSON.stringify(finalConfig, null, 2)}`)
4749

@@ -55,7 +57,7 @@ export async function start (devServerOptions: StartDevServer): Promise<ViteDevS
5557
}
5658

5759
debug('starting vite dev server')
58-
const resolvedConfig = resolveServerConfig(devServerOptions)
60+
const resolvedConfig = await resolveServerConfig(devServerOptions)
5961

6062
return createServer(resolvedConfig)
6163
}

0 commit comments

Comments
 (0)