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:
parent
bf4e6fb586
commit
327634eb24
4 changed files with 18 additions and 18 deletions
|
@ -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,
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export default function page() {
|
export default function page() {
|
||||||
return <>blog</>
|
return <div id="blog">this is blog</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export default function page() {
|
export default function page() {
|
||||||
return <>page</>
|
return <div id="home">this is home</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue