Skip to content

Commit

Permalink
Fix Experimental Modern Mode with CSS (#10289)
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer committed Jan 27, 2020
1 parent ac6a7f9 commit abd69ec
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/next/build/webpack/plugins/build-manifest-plugin.ts
Expand Up @@ -33,7 +33,9 @@ const generateClientManifest = (
// Filter out dependencies in the _app entry, because those will have already
// been loaded by the client prior to a navigation event
const filteredDeps = dependencies.filter(
dep => !appDependencies.has(dep) && /\.module\.js$/.test(dep) === isModern
dep =>
!appDependencies.has(dep) &&
(!dep.endsWith('.js') || dep.endsWith('.module.js') === isModern)
)

// The manifest can omit the page if it has no requirements
Expand Down
156 changes: 156 additions & 0 deletions test/integration/css-client-nav/test/index.test.js
Expand Up @@ -171,3 +171,159 @@ describe('CSS Module client-side navigation in Production', () => {
}
})
})

describe('CSS Module client-side navigation in Production (Modern)', () => {
const appDir = join(fixturesDir, 'multi-module-modern')

beforeAll(async () => {
await remove(join(appDir, '.next'))
})

let appPort
let app
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
})

it('should be able to client-side navigate from red to blue', async () => {
let browser
try {
browser = await webdriver(appPort, '/red')

await browser.eval(`window.__did_not_ssr = 'make sure this is set'`)

const redColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-red')).color`
)
expect(redColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`)

await browser.elementByCss('#link-blue').click()

await browser.waitForElementByCss('#verify-blue')

const blueColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-blue')).color`
)
expect(blueColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`)

expect(await browser.eval(`window.__did_not_ssr`)).toMatchInlineSnapshot(
`"make sure this is set"`
)
} finally {
if (browser) {
await browser.close()
}
}
})

it('should be able to client-side navigate from blue to red', async () => {
const content = await renderViaHTTP(appPort, '/blue')
const $ = cheerio.load(content)

// Ensure only `/blue` page's CSS is preloaded
const serverCssPreloads = $('link[rel="preload"][as="style"]')
expect(serverCssPreloads.length).toBe(1)

const serverCssPrefetches = $('link[rel="prefetch"][as="style"]')
expect(serverCssPrefetches.length).toBe(0)

let browser
try {
browser = await webdriver(appPort, '/blue')
await browser.eval(`window.__did_not_ssr = 'make sure this is set'`)

const redColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-blue')).color`
)
expect(redColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`)

// Check that Red was preloaded
const result = await browser.eval(
`[].slice.call(document.querySelectorAll('link[rel="prefetch"][as="style"]')).map(e=>({href:e.href})).sort()`
)
expect(result.length).toBe(1)

// Check that CSS was not loaded as script
const cssPreloads = await browser.eval(
`[].slice.call(document.querySelectorAll('link[rel=preload][href*=".css"]')).map(e=>e.as)`
)
expect(cssPreloads.every(e => e === 'style')).toBe(true)
const cssPreloads2 = await browser.eval(
`[].slice.call(document.querySelectorAll('link[rel=prefetch][href*=".css"]')).map(e=>e.as)`
)
expect(cssPreloads2.every(e => e === 'style')).toBe(true)

await browser.elementByCss('#link-red').click()

await browser.waitForElementByCss('#verify-red')

const blueColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-red')).color`
)
expect(blueColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`)

expect(await browser.eval(`window.__did_not_ssr`)).toMatchInlineSnapshot(
`"make sure this is set"`
)
} finally {
if (browser) {
await browser.close()
}
}
})

it('should be able to client-side navigate from none to red', async () => {
let browser
try {
browser = await webdriver(appPort, '/none')

await browser.eval(`window.__did_not_ssr = 'make sure this is set'`)

await browser.elementByCss('#link-red').click()
await browser.waitForElementByCss('#verify-red')

const blueColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-red')).color`
)
expect(blueColor).toMatchInlineSnapshot(`"rgb(255, 0, 0)"`)

expect(await browser.eval(`window.__did_not_ssr`)).toMatchInlineSnapshot(
`"make sure this is set"`
)
} finally {
if (browser) {
await browser.close()
}
}
})

it('should be able to client-side navigate from none to blue', async () => {
let browser
try {
browser = await webdriver(appPort, '/none')

await browser.eval(`window.__did_not_ssr = 'make sure this is set'`)

await browser.elementByCss('#link-blue').click()
await browser.waitForElementByCss('#verify-blue')

const blueColor = await browser.eval(
`window.getComputedStyle(document.querySelector('#verify-blue')).color`
)
expect(blueColor).toMatchInlineSnapshot(`"rgb(0, 0, 255)"`)

expect(await browser.eval(`window.__did_not_ssr`)).toMatchInlineSnapshot(
`"make sure this is set"`
)
} finally {
if (browser) {
await browser.close()
}
}
})
})
@@ -0,0 +1,9 @@
const parent = require('../next.config')

module.exports = {
...parent,
experimental: {
...parent.experimental,
modern: true,
},
}
20 changes: 20 additions & 0 deletions test/integration/css-fixtures/multi-module-modern/pages/blue.js
@@ -0,0 +1,20 @@
import Link from 'next/link'
import { blueText } from './blue.module.css'

export default function Blue() {
return (
<>
<div id="verify-blue" className={blueText}>
This text should be blue.
</div>
<br />
<Link href="/red" prefetch>
<a id="link-red">Red</a>
</Link>
<br />
<Link href="/none" prefetch={false}>
<a id="link-none">None</a>
</Link>
</>
)
}
@@ -0,0 +1,3 @@
.blueText {
color: blue;
}
19 changes: 19 additions & 0 deletions test/integration/css-fixtures/multi-module-modern/pages/none.js
@@ -0,0 +1,19 @@
import Link from 'next/link'

export default function None() {
return (
<>
<div id="verify-black" style={{ color: 'black' }}>
This text should be black.
</div>
<br />
<Link href="/red" prefetch={false}>
<a id="link-red">Red</a>
</Link>
<br />
<Link href="/blue" prefetch={false}>
<a id="link-blue">Blue</a>
</Link>
</>
)
}
20 changes: 20 additions & 0 deletions test/integration/css-fixtures/multi-module-modern/pages/red.js
@@ -0,0 +1,20 @@
import Link from 'next/link'
import { redText } from './red.module.css'

export default function Red() {
return (
<>
<div id="verify-red" className={redText}>
This text should be red.
</div>
<br />
<Link href="/blue" prefetch={false}>
<a id="link-blue">Blue</a>
</Link>
<br />
<Link href="/none" prefetch={false}>
<a id="link-none">None</a>
</Link>
</>
)
}
@@ -0,0 +1,3 @@
.redText {
color: red;
}
9 changes: 9 additions & 0 deletions test/integration/css-fixtures/multi-module/next.config.js
@@ -0,0 +1,9 @@
const parent = require('../next.config')

module.exports = {
...parent,
experimental: {
...parent.experimental,
modern: false,
},
}

0 comments on commit abd69ec

Please sign in to comment.