Skip to content

Commit 7e0de0b

Browse files
authored
fix: map framework name to dependency that contains webpack (#22774)
1 parent 97ec820 commit 7e0de0b

9 files changed

+94
-38
lines changed

npm/webpack-dev-server/src/devServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export type WebpackDevServerConfig = {
2525
webpackConfig?: unknown // Derived from the user's webpack
2626
}
2727

28-
const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react', 'vue-cli', 'next', 'vue'] as const
28+
export const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react', 'vue-cli', 'next', 'vue'] as const
2929

3030
/**
3131
* @internal

npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Module from 'module'
22
import path from 'path'
3-
import type { WebpackDevServerConfig } from '../devServer'
3+
import type { WebpackDevServerConfig, ALL_FRAMEWORKS } from '../devServer'
44
import debugFn from 'debug'
55

66
const debug = debugFn('cypress:webpack-dev-server:sourceRelativeWebpackModules')
@@ -56,7 +56,18 @@ export const cypressWebpackPath = (config: WebpackDevServerConfig) => {
5656
})
5757
}
5858

59-
// Source the users framework from the provided projectRoot. The framework, if available, will server
59+
type FrameworkWebpackMapper = { [Property in typeof ALL_FRAMEWORKS[number]]: string | undefined }
60+
61+
const frameworkWebpackMapper: FrameworkWebpackMapper = {
62+
'create-react-app': 'react-scripts',
63+
'vue-cli': '@vue/cli-service',
64+
'nuxt': '@nuxt/webpack',
65+
react: undefined,
66+
vue: undefined,
67+
next: 'next',
68+
}
69+
70+
// Source the users framework from the provided projectRoot. The framework, if available, will serve
6071
// as the resolve base for webpack dependency resolution.
6172
export function sourceFramework (config: WebpackDevServerConfig): SourcedDependency | null {
6273
debug('Framework: Attempting to source framework for %s', config.cypressConfig.projectRoot)
@@ -66,10 +77,18 @@ export function sourceFramework (config: WebpackDevServerConfig): SourcedDepende
6677
return null
6778
}
6879

80+
const sourceOfWebpack = frameworkWebpackMapper[config.framework]
81+
82+
if (!sourceOfWebpack) {
83+
debug('Not a higher-order framework so webpack dependencies should be resolvable from projectRoot')
84+
85+
return null
86+
}
87+
6988
const framework = { } as SourcedDependency
7089

7190
try {
72-
const frameworkJsonPath = require.resolve(`${config.framework}/package.json`, {
91+
const frameworkJsonPath = require.resolve(`${sourceOfWebpack}/package.json`, {
7392
paths: [config.cypressConfig.projectRoot],
7493
})
7594
const frameworkPathRoot = path.dirname(frameworkJsonPath)

npm/webpack-dev-server/test/handlers/createReactAppHandler.spec.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,45 +55,57 @@ describe('createReactAppHandler', function () {
5555

5656
process.chdir(projectRoot)
5757

58-
const { frameworkConfig: webpackConfig } = createReactAppHandler({
58+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = createReactAppHandler({
5959
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
60+
framework: 'create-react-app',
6061
} as WebpackDevServerConfig)
6162

6263
expect(webpackConfig.mode).eq('development')
6364
expectEslintModifications(webpackConfig)
6465
expectModuleSourceInPlaceModifications(webpackConfig, projectRoot)
6566
expectBabelRuleModifications(webpackConfig, projectRoot)
67+
68+
expect(sourceWebpackModulesResult.framework?.importPath).to.include('react-scripts')
69+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(4)
6670
})
6771

6872
it('sources the config from react-scripts v5', async () => {
6973
const projectRoot = await scaffoldMigrationProject('cra-5')
7074

7175
process.chdir(projectRoot)
7276

73-
const { frameworkConfig: webpackConfig } = createReactAppHandler({
77+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = createReactAppHandler({
7478
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
79+
framework: 'create-react-app',
7580
} as WebpackDevServerConfig)
7681

7782
expect(webpackConfig.mode).eq('development')
7883
expectEslintModifications(webpackConfig)
7984
expectModuleSourceInPlaceModifications(webpackConfig, projectRoot)
8085
expectBabelRuleModifications(webpackConfig, projectRoot)
8186
expectReactScriptsFiveModifications(webpackConfig)
87+
88+
expect(sourceWebpackModulesResult.framework?.importPath).to.include('react-scripts')
89+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(5)
8290
})
8391

8492
it('sources the config from ejected cra', async () => {
8593
const projectRoot = await scaffoldMigrationProject('cra-ejected')
8694

8795
process.chdir(projectRoot)
8896

89-
const { frameworkConfig: webpackConfig } = createReactAppHandler({
97+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = createReactAppHandler({
9098
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
99+
framework: 'create-react-app',
91100
} as WebpackDevServerConfig)
92101

93102
expect(webpackConfig.mode).eq('development')
94103
expectEslintModifications(webpackConfig)
95104
expectModuleSourceInPlaceModifications(webpackConfig, projectRoot)
96105
expectBabelRuleModifications(webpackConfig, projectRoot)
97106
expectReactScriptsFiveModifications(webpackConfig)
107+
108+
expect(sourceWebpackModulesResult.framework).to.be.null
109+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(5)
98110
})
99111
})

npm/webpack-dev-server/test/handlers/nextHandler.spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,53 @@ describe('nextHandler', function () {
3131

3232
process.chdir(projectRoot)
3333

34-
const { frameworkConfig: webpackConfig } = await nextHandler({
34+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await nextHandler({
3535
framework: 'next',
3636
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
3737
} as WebpackDevServerConfig)
3838

3939
expectWatchOverrides(webpackConfig)
4040
expectPagesDir(webpackConfig, projectRoot)
4141
expectWebpackSpan(webpackConfig)
42+
43+
expect(sourceWebpackModulesResult.webpack.importPath).to.include('next')
44+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(5)
4245
})
4346

4447
it('sources from a next-11 project', async () => {
4548
const projectRoot = await scaffoldMigrationProject('next-11')
4649

4750
process.chdir(projectRoot)
4851

49-
const { frameworkConfig: webpackConfig } = await nextHandler({
52+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await nextHandler({
5053
framework: 'next',
5154
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
5255
} as WebpackDevServerConfig)
5356

5457
expectWatchOverrides(webpackConfig)
5558
expectPagesDir(webpackConfig, projectRoot)
5659
expectWebpackSpan(webpackConfig)
60+
61+
expect(sourceWebpackModulesResult.webpack.importPath).to.include('next')
62+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(5)
63+
})
64+
65+
it('sources from a next-11-webpack-4 project', async () => {
66+
const projectRoot = await scaffoldMigrationProject('next-11-webpack-4')
67+
68+
process.chdir(projectRoot)
69+
70+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await nextHandler({
71+
framework: 'next',
72+
cypressConfig: { projectRoot, cypressBinaryRoot: __dirname } as Cypress.PluginConfigOptions,
73+
} as WebpackDevServerConfig)
74+
75+
expectWatchOverrides(webpackConfig)
76+
expectPagesDir(webpackConfig, projectRoot)
77+
expectWebpackSpan(webpackConfig)
78+
79+
expect(sourceWebpackModulesResult.webpack.importPath).to.include('next')
80+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(4)
5781
})
5882

5983
it('throws if nodeVersion is set to bundled', async () => {

npm/webpack-dev-server/test/handlers/nuxtHandler.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ describe('nuxtHandler', function () {
1313

1414
process.chdir(projectRoot)
1515

16-
const { frameworkConfig: webpackConfig } = await nuxtHandler({
16+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await nuxtHandler({
1717
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
18+
framework: 'nuxt',
1819
} as WebpackDevServerConfig)
1920

2021
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
2122
expect(webpackConfig.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
2223
expect(webpackConfig.performance).to.be.undefined
24+
25+
expect(sourceWebpackModulesResult.framework?.importPath).to.include('@nuxt/webpack')
26+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(4)
2327
})
2428
})

npm/webpack-dev-server/test/handlers/vueCliHandler.spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,32 @@ describe('vueCliHandler', function () {
1313

1414
process.chdir(projectRoot)
1515

16-
const { frameworkConfig: webpackConfig } = vueCliHandler({
16+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = vueCliHandler({
1717
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
18+
framework: 'vue-cli',
1819
} as WebpackDevServerConfig)
1920

2021
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
2122
expect(webpackConfig.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
23+
24+
expect(sourceWebpackModulesResult.framework?.importPath).to.include('@vue/cli-service')
25+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(5)
2226
})
2327

2428
it('sources from a @vue/[email protected] project with Vue 2', async () => {
2529
const projectRoot = await scaffoldMigrationProject('vuecli4-vue2')
2630

2731
process.chdir(projectRoot)
2832

29-
const { frameworkConfig: webpackConfig } = vueCliHandler({
33+
const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = vueCliHandler({
3034
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
35+
framework: 'vue-cli',
3136
} as WebpackDevServerConfig)
3237

3338
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
3439
expect(webpackConfig.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
40+
41+
expect(sourceWebpackModulesResult.framework?.importPath).to.include('@vue/cli-service')
42+
expect(sourceWebpackModulesResult.webpack.majorVersion).eq(4)
3543
})
3644
})

system-tests/__snapshots__/webpack_dev_server_fresh_spec.ts.js

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
exports['@cypress/webpack-dev-server react executes all of the tests for webpack4_wds3-react 1'] = `
2+
ℹ 「wds」: Project is running at http://localhost:xxxx/webpack-dev-server/
3+
ℹ 「wds」: webpack output is served from /__cypress/src
4+
ℹ 「wds」: Content not from webpack is served from /foo/bar/.projects/webpack4_wds3-react
25
36
====================================================================================================
47
@@ -16,18 +19,7 @@ exports['@cypress/webpack-dev-server react executes all of the tests for webpack
1619
────────────────────────────────────────────────────────────────────────────────────────────────────
1720
1821
Running: App.cy.jsx (1 of 4)
19-
48 modules
20-
21-
ERROR in ./src/AppCompilationError.cy.jsx
22-
Module build failed (from [..]):
23-
SyntaxError: /foo/bar/.projects/webpack4_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0)
24-
25-
7 | cy.get('h1').contains('Hello World')
26-
8 | }
27-
> 9 | })
28-
| ^
29-
10 |
30-
[stack trace lines]
22+
ℹ 「wdm」: Failed to compile.
3123
3224
3325
✓ renders hello world
@@ -459,6 +451,9 @@ When Cypress detects uncaught errors originating from your test code it will aut
459451
`
460452

461453
exports['@cypress/webpack-dev-server react executes all of the tests for webpack5_wds3-react 1'] = `
454+
ℹ 「wds」: Project is running at http://localhost:xxxx/webpack-dev-server/
455+
ℹ 「wds」: webpack output is served from /__cypress/src
456+
ℹ 「wds」: Content not from webpack is served from /foo/bar/.projects/webpack5_wds3-react
462457
463458
====================================================================================================
464459
@@ -476,18 +471,7 @@ exports['@cypress/webpack-dev-server react executes all of the tests for webpack
476471
────────────────────────────────────────────────────────────────────────────────────────────────────
477472
478473
Running: App.cy.jsx (1 of 4)
479-
48 modules
480-
481-
ERROR in ./src/AppCompilationError.cy.jsx
482-
Module build failed (from [..]):
483-
SyntaxError: /foo/bar/.projects/webpack5_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0)
484-
485-
7 | cy.get('h1').contains('Hello World')
486-
8 | }
487-
> 9 | })
488-
| ^
489-
10 |
490-
[stack trace lines]
474+
ℹ 「wdm」: Failed to compile.
491475
492476
493477
✓ renders hello world
@@ -706,7 +690,8 @@ exports['@cypress/webpack-dev-server react executes all of the tests for webpack
706690
────────────────────────────────────────────────────────────────────────────────────────────────────
707691
708692
Running: App.cy.jsx (1 of 4)
709-
48 modules
693+
10 assets
694+
58 modules
710695
711696
ERROR in ./src/AppCompilationError.cy.jsx
712697
Module build failed (from [..]):
@@ -719,6 +704,8 @@ SyntaxError: /foo/bar/.projects/webpack5_wds4-react/src/AppCompilationError.cy.j
719704
10 |
720705
[stack trace lines]
721706
707+
webpack x.x.x compiled with x errors in xxx ms
708+
722709
723710
✓ renders hello world
724711

system-tests/lib/system-tests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,8 @@ const systemTests = {
11281128
return stdout
11291129
.replace(/using description file: .* \(relative/g, 'using description file: [..] (relative')
11301130
.replace(/Module build failed \(from .*\)/g, 'Module build failed (from [..])')
1131+
.replace(/Project is running at http:\/\/localhost:\d+/g, 'Project is running at http://localhost:xxxx')
1132+
.replace(/webpack.*compiled with.*in \d+ ms/g, 'webpack x.x.x compiled with x errors in xxx ms')
11311133
},
11321134

11331135
normalizeRuns (runs) {

system-tests/test/webpack_dev_server_fresh_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('@cypress/webpack-dev-server', function () {
2020
snapshot: true,
2121
expectedExitCode: 3,
2222
onStdout: (stdout) => {
23-
return stripAnsi(systemTests.normalizeWebpackErrors(stdout))
23+
return systemTests.normalizeWebpackErrors(stripAnsi(stdout))
2424
},
2525
})
2626
})

0 commit comments

Comments
 (0)