Skip to content

Commit

Permalink
feat: add next preset to webpack-dev-server-fresh (#21069)
Browse files Browse the repository at this point in the history
Co-authored-by: Tim Griesser <tgriesser10@gmail.com>
  • Loading branch information
ZachJW34 and tgriesser authored Apr 19, 2022
1 parent 48ebe64 commit ccfee1e
Show file tree
Hide file tree
Showing 34 changed files with 6,633 additions and 216 deletions.
74 changes: 74 additions & 0 deletions npm/webpack-dev-server-fresh/cypress/e2e/next.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// <reference types="cypress" />
/// <reference path="../support/e2e.ts" />
import type { ProjectFixtureDir } from '@tooling/system-tests/lib/fixtureDirs'

const WEBPACK_REACT: ProjectFixtureDir[] = ['next-11', 'next-12', 'next-11-webpack-4']

// Add to this list to focus on a particular permutation
const ONLY_PROJECTS: ProjectFixtureDir[] = []

for (const project of WEBPACK_REACT) {
if (ONLY_PROJECTS.length && !ONLY_PROJECTS.includes(project)) {
continue
}

describe(`Working with ${project}`, () => {
beforeEach(() => {
cy.scaffoldProject(project)
cy.openProject(project)
cy.startAppServer('component')
})

it('should mount a passing test', () => {
cy.visitApp()
cy.contains('index.cy.js').click()
cy.get('.passed > .num').should('contain', 1)
})

it('should live-reload on src changes', () => {
cy.visitApp()

cy.contains('index.cy.js').click()
cy.get('.passed > .num').should('contain', 1)

cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('pages', 'index.js')

await ctx.actions.file.writeFileInProject(
indexPath,
(await ctx.file.readFileInProject(indexPath)).replace('Welcome to', 'Hello from'),
)
})

cy.get('.failed > .num', { timeout: 10000 }).should('contain', 1)

cy.withCtx(async (ctx) => {
const indexTestPath = ctx.path.join('pages', 'index.cy.js')

await ctx.actions.file.writeFileInProject(
indexTestPath,
(await ctx.file.readFileInProject(indexTestPath)).replace('Welcome to', 'Hello from'),
)
})

cy.get('.passed > .num').should('contain', 1)
})

it('should detect new spec', () => {
cy.visitApp()

cy.withCtx(async (ctx) => {
const newTestPath = ctx.path.join('pages', 'New.cy.js')
const indexTestPath = ctx.path.join('pages', 'index.cy.js')

await ctx.actions.file.writeFileInProject(
newTestPath,
await ctx.file.readFileInProject(indexTestPath),
)
})

cy.contains('New.cy.js').click()
cy.get('.passed > .num').should('contain', 1)
})
})
}
54 changes: 29 additions & 25 deletions npm/webpack-dev-server-fresh/src/devServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import type WebpackDevServer from 'webpack-dev-server'
import type { Compiler, Configuration } from 'webpack'

import { createWebpackDevServer } from './createWebpackDevServer'
import { sourceRelativeWebpackModules } from './helpers/sourceRelativeWebpackModules'
import type { AddressInfo } from 'net'
import debugLib from 'debug'
import type { Server } from 'http'
import { vueCliHandler } from './helpers/vueCliHandler'
import { nuxtHandler } from './helpers/nuxtHandler'
import { createReactAppHandler } from './helpers/createReactAppHandler'
import { nextHandler } from './helpers/nextHandler'
import { sourceDefaultWebpackDependencies, SourceRelativeWebpackResult } from './helpers/sourceRelativeWebpackModules'

const debug = debugLib('cypress:webpack-dev-server-fresh:devServer')

Expand All @@ -23,7 +24,7 @@ export type WebpackDevServerConfig = {
webpackConfig?: unknown // Derived from the user's webpack
}

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

/**
* @internal
Expand Down Expand Up @@ -111,36 +112,39 @@ export function devServer (devServerConfig: WebpackDevServerConfig): Promise<Cyp
})
}

export type PresetHandlerResult = { frameworkConfig?: Configuration, sourceWebpackModulesResult: SourceRelativeWebpackResult }

async function getPreset (devServerConfig: WebpackDevServerConfig): Promise<PresetHandlerResult> {
switch (devServerConfig.framework) {
case 'create-react-app':
return createReactAppHandler(devServerConfig)
case 'nuxt':
return await nuxtHandler(devServerConfig)

case 'vue-cli':
return vueCliHandler(devServerConfig)

case 'next':
return await nextHandler(devServerConfig)

case 'react':
case 'vue':
case undefined:
return { sourceWebpackModulesResult: sourceDefaultWebpackDependencies(devServerConfig) }

default:
throw new Error(`Unexpected framework ${devServerConfig.framework}, expected one of ${ALL_FRAMEWORKS.join(', ')}`)
}
}

/**
* Synchronously create the webpack server instance, without starting.
* Useful for testing
*
* @internal
*/
devServer.create = async function (devServerConfig: WebpackDevServerConfig) {
const sourceWebpackModulesResult = sourceRelativeWebpackModules(devServerConfig)

let frameworkConfig: Configuration | undefined

// If we have a framework specified, source the associated config
if (typeof devServerConfig.framework === 'string') {
switch (devServerConfig.framework) {
case 'create-react-app':
frameworkConfig = createReactAppHandler({ devServerConfig, sourceWebpackModulesResult })
break
case 'react':
break
case 'nuxt':
frameworkConfig = await nuxtHandler({ devServerConfig, sourceWebpackModulesResult })
break

case 'vue-cli':
frameworkConfig = vueCliHandler({ devServerConfig, sourceWebpackModulesResult })
break
default:
throw new Error(`Unexpected framework ${devServerConfig.framework}, expected one of ${ALL_FRAMEWORKS.join(', ')}`)
}
}
const { frameworkConfig, sourceWebpackModulesResult } = await getPreset(devServerConfig)

const { server, compiler } = createWebpackDevServer({
devServerConfig,
Expand Down
18 changes: 10 additions & 8 deletions npm/webpack-dev-server-fresh/src/helpers/createReactAppHandler.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import type { CreateFinalWebpackConfig } from '../createWebpackDevServer'
import debugLib from 'debug'
import type { Configuration, ResolvePluginInstance, RuleSetRule } from 'webpack'
import path from 'path'

type PresetHandlerOptions = Omit<CreateFinalWebpackConfig, 'frameworkConfig'>
import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer'
import { sourceDefaultWebpackDependencies } from './sourceRelativeWebpackModules'

const debug = debugLib('cypress:webpack-dev-server-fresh:create-react-app')

/**
* Sourcing the config for create-react-app
*/
export function createReactAppHandler (presetHandler: PresetHandlerOptions) {
const { devServerConfig, sourceWebpackModulesResult } = presetHandler
export function createReactAppHandler (devServerConfig: WebpackDevServerConfig): PresetHandlerResult {
const sourceWebpackModulesResult = sourceDefaultWebpackDependencies(devServerConfig)

// this is required because
// 1) we use our own HMR and we don't need react-refresh transpiling overhead
// 2) it doesn't work with process.env=test @see https://github.com/cypress-io/cypress-realworld-app/pull/832
process.env.FAST_REFRESH = 'false'
const webpackConfig = loadWebpackConfig(presetHandler)
const webpackConfig = loadWebpackConfig(devServerConfig)

addCypressToWebpackEslintRulesInPlace(webpackConfig)

Expand All @@ -32,10 +31,13 @@ export function createReactAppHandler (presetHandler: PresetHandlerOptions) {
reactScriptsFiveModifications(webpackConfig)
}

return webpackConfig
return {
frameworkConfig: webpackConfig,
sourceWebpackModulesResult,
}
}

function loadWebpackConfig ({ devServerConfig }: PresetHandlerOptions): Configuration {
function loadWebpackConfig (devServerConfig: WebpackDevServerConfig): Configuration {
let webpackConfigPath: string

const envName = 'test'
Expand Down
Loading

2 comments on commit ccfee1e

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on ccfee1e Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/linux-x64/10.0-release-ccfee1ed13a3c9e4256a568270fca96d165cceaf/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on ccfee1e Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/darwin-x64/10.0-release-ccfee1ed13a3c9e4256a568270fca96d165cceaf/cypress.tgz

Please sign in to comment.