Fix windows slashes for app client entry (#44052)

Fixes #43854 , followup for #44011. Normalize the bundlePath so it works
in all cases

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
This commit is contained in:
Jiachi Liu 2022-12-15 19:34:02 +01:00 committed by GitHub
parent bf4e6fb586
commit 327634eb24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 18 deletions

View file

@ -24,6 +24,7 @@ import {
import { ASYNC_CLIENT_MODULES } from './flight-manifest-plugin' import { ASYNC_CLIENT_MODULES } from './flight-manifest-plugin'
import { isClientComponentModule, regexCSS } from '../loaders/utils' import { isClientComponentModule, regexCSS } from '../loaders/utils'
import { traverseModules } from '../utils' import { traverseModules } from '../utils'
import { normalizePathSep } from '../../../shared/lib/page-path/normalize-path-sep'
interface Options { interface Options {
dev: boolean dev: boolean
@ -96,9 +97,10 @@ export class FlightClientEntryPlugin {
// additional queries to make sure there's no conflict even using the `named` // additional queries to make sure there's no conflict even using the `named`
// module ID strategy. // module ID strategy.
let ssrNamedModuleId = path.relative(compiler.context, modResource) let ssrNamedModuleId = path.relative(compiler.context, modResource)
if (!ssrNamedModuleId.startsWith('.')) { if (!ssrNamedModuleId.startsWith('.')) {
// TODO use getModuleId instead // TODO use getModuleId instead
ssrNamedModuleId = `./${ssrNamedModuleId.replace(/\\/g, '/')}` ssrNamedModuleId = `./${normalizePathSep(ssrNamedModuleId)}`
} }
if (this.isEdgeServer) { if (this.isEdgeServer) {
@ -204,9 +206,9 @@ export class FlightClientEntryPlugin {
: entryRequest : entryRequest
// Replace file suffix as `.js` will be added. // Replace file suffix as `.js` will be added.
const bundlePath = relativeRequest const bundlePath = normalizePathSep(
.replace(/\.(js|ts)x?$/, '') relativeRequest.replace(/\.(js|ts)x?$/, '').replace(/^src[\\/]/, '')
.replace(/^src[\\/]/, '') )
promises.push( promises.push(
this.injectClientEntryAndSSRModules({ this.injectClientEntryAndSSRModules({
@ -509,10 +511,7 @@ export class FlightClientEntryPlugin {
// Add for the client compilation // Add for the client compilation
// Inject the entry to the client compiler. // Inject the entry to the client compiler.
if (this.dev) { if (this.dev) {
const pageKey = (COMPILER_NAMES.client + bundlePath).replace( const pageKey = COMPILER_NAMES.client + bundlePath
/\\/g,
path.posix.sep
)
if (!entries[pageKey]) { if (!entries[pageKey]) {
entries[pageKey] = { entries[pageKey] = {
type: EntryTypes.CHILD_ENTRY, type: EntryTypes.CHILD_ENTRY,

View file

@ -1,3 +1,3 @@
export default function page() { export default function page() {
return <>blog</> return <div id="blog">this is blog</div>
} }

View file

@ -1,3 +1,3 @@
export default function page() { export default function page() {
return <>page</> return <div id="home">this is home</div>
} }

View file

@ -1,6 +1,7 @@
/* eslint-env jest */ /* eslint-env jest */
import { join } from 'path' import { join } from 'path'
import cheerio from 'cheerio'
import { runDevSuite, runProdSuite, renderViaHTTP } from 'next-test-utils' import { runDevSuite, runProdSuite, renderViaHTTP } from 'next-test-utils'
import webdriver from 'next-webdriver' import webdriver from 'next-webdriver'
@ -9,22 +10,22 @@ const appDir = join(__dirname, '..')
function runTests(context, env) { function runTests(context, env) {
describe('App Dir Basic', () => { describe('App Dir Basic', () => {
it('should render html properly', async () => { it('should render html properly', async () => {
const indexHtml = await renderViaHTTP(context.appPort, '/') const $index = cheerio.load(await renderViaHTTP(context.appPort, '/'))
const blogHtml = await renderViaHTTP(context.appPort, '/blog') const $blog = cheerio.load(await renderViaHTTP(context.appPort, '/blog'))
expect(indexHtml).toContain('page') expect($index('#home').text()).toBe('this is home')
expect(blogHtml).toContain('blog') expect($blog('#blog').text()).toBe('this is blog')
}) })
it('should hydrate pages properly', async () => { it('should hydrate pages properly', async () => {
const browser = await webdriver(context.appPort, '/') const browser = await webdriver(context.appPort, '/')
const indexHtml = await browser.waitForElementByCss('body').text() const indexHtml = await browser.waitForElementByCss('#home').text()
const url = await browser.url() const url = await browser.url()
await browser.loadPage(url + 'blog') await browser.loadPage(url + 'blog')
const blogHtml = await browser.waitForElementByCss('body').text() const blogHtml = await browser.waitForElementByCss('#blog').text()
expect(indexHtml).toContain('page') expect(indexHtml).toBe('this is home')
expect(blogHtml).toContain('blog') expect(blogHtml).toBe('this is blog')
}) })
}) })
} }