-
Notifications
You must be signed in to change notification settings - Fork 26.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't require source files to be writeable in dev mode
Currently, hot reloading is broken when running dev mode in systems like Bazel, where the source files are marked as read-only. The dev server will not render pages, and the browser's request will hang when trying to load a page. This is caused by a check in the hot reloader to see if a file exists, which is currently done by seeing if the file is writeable. The goal of the check is merely to see if a file exists, so checking for read permissions should be sufficient.
- Loading branch information
Evan Bradley
committed
Nov 2, 2021
1 parent
d5d1bc0
commit 0b70497
Showing
5 changed files
with
148 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
onDemandEntries: { | ||
// Make sure entries are not getting disposed. | ||
maxInactiveAge: 1000 * 60 * 60, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const Hello = () => <p>Hello World</p> | ||
|
||
export default Hello |
117 changes: 117 additions & 0 deletions
117
test/integration/read-only-source-hmr/test/index.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* eslint-env jest */ | ||
|
||
import fs from 'fs-extra' | ||
import { | ||
check, | ||
findPort, | ||
getBrowserBodyText, | ||
killApp, | ||
launchApp, | ||
} from 'next-test-utils' | ||
import webdriver from 'next-webdriver' | ||
import { join } from 'path' | ||
|
||
const READ_ONLY_PERMISSIONS = 0o444 | ||
const READ_WRITE_PERMISSIONS = 0o644 | ||
|
||
const appDir = join(__dirname, '..') | ||
const pagePath = join(appDir, 'pages/hello.js') | ||
|
||
let appPort | ||
let app | ||
|
||
async function writeReadOnlyFile(path, content) { | ||
await fs.chmod(pagePath, READ_WRITE_PERMISSIONS) | ||
await fs.writeFile(path, content, 'utf8') | ||
await fs.chmod(pagePath, READ_ONLY_PERMISSIONS) | ||
} | ||
|
||
describe('Read-only source HMR', () => { | ||
beforeAll(async () => { | ||
await fs.chmod(pagePath, READ_ONLY_PERMISSIONS) | ||
|
||
appPort = await findPort() | ||
app = await launchApp(appDir, appPort, { | ||
env: { | ||
__NEXT_TEST_WITH_DEVTOOL: 1, | ||
// Events can be finicky in CI. This switches to a more reliable | ||
// polling method. | ||
CHOKIDAR_USEPOLLING: 'true', | ||
CHOKIDAR_INTERVAL: 500, | ||
}, | ||
}) | ||
}) | ||
|
||
afterAll(async () => { | ||
await fs.chmod(pagePath, READ_WRITE_PERMISSIONS) | ||
await killApp(app) | ||
}) | ||
|
||
it('should detect changes to a page', async () => { | ||
let browser | ||
|
||
try { | ||
browser = await webdriver(appPort, '/hello') | ||
await check(() => getBrowserBodyText(browser), /Hello World/) | ||
|
||
const originalContent = await fs.readFile(pagePath, 'utf8') | ||
const editedContent = originalContent.replace('Hello World', 'COOL page') | ||
|
||
await writeReadOnlyFile(pagePath, editedContent) | ||
await check(() => getBrowserBodyText(browser), /COOL page/) | ||
|
||
await writeReadOnlyFile(pagePath, originalContent) | ||
await check(() => getBrowserBodyText(browser), /Hello World/) | ||
} finally { | ||
if (browser) { | ||
await browser.close() | ||
} | ||
} | ||
}) | ||
|
||
it('should handle page deletion and subsequent recreation', async () => { | ||
let browser | ||
|
||
try { | ||
browser = await webdriver(appPort, '/hello') | ||
await check(() => getBrowserBodyText(browser), /Hello World/) | ||
|
||
const originalContent = await fs.readFile(pagePath, 'utf8') | ||
|
||
await fs.remove(pagePath) | ||
|
||
await fs.writeFile(pagePath, originalContent, { | ||
mode: READ_ONLY_PERMISSIONS, | ||
}) | ||
await check(() => getBrowserBodyText(browser), /Hello World/) | ||
} finally { | ||
if (browser) { | ||
await browser.close() | ||
} | ||
} | ||
}) | ||
|
||
it('should detect a new page', async () => { | ||
let browser | ||
const newPagePath = join(appDir, 'pages/new.js') | ||
|
||
await writeReadOnlyFile( | ||
newPagePath, | ||
` | ||
const New = () => <p>New page</p> | ||
export default New | ||
` | ||
) | ||
|
||
try { | ||
browser = await webdriver(appPort, '/new') | ||
await check(() => getBrowserBodyText(browser), /New page/) | ||
} finally { | ||
if (browser) { | ||
await browser.close() | ||
} | ||
await fs.remove(newPagePath) | ||
} | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"compilerOptions": { | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"jsx": "preserve", | ||
"target": "es5", | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"noEmit": true, | ||
"incremental": true, | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true | ||
}, | ||
"exclude": ["node_modules"], | ||
"include": ["next-env.d.ts", "pages"] | ||
} |