mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Fix Typescript HMR (#4689)
Fixes #4686 Adds tests for @zeit/next-typescript so that we don't regress on this again. I've fixed an issue in the `next` CLI too which caused lingering processes when the process gets force killed, which is what we do in the test suite, so it kept running if there was no manual quit.
This commit is contained in:
parent
810705a076
commit
17e410a1d0
9
bin/next
9
bin/next
|
@ -88,6 +88,15 @@ const startProcess = () => {
|
|||
|
||||
let proc = startProcess()
|
||||
|
||||
const wrapper = () => {
|
||||
if (proc) {
|
||||
proc.kill()
|
||||
}
|
||||
}
|
||||
process.on('SIGINT', wrapper)
|
||||
process.on('SIGTERM', wrapper)
|
||||
process.on('exit', wrapper)
|
||||
|
||||
if (cmd === 'dev') {
|
||||
const {watchFile} = require('fs')
|
||||
watchFile(`${process.cwd()}/${CONFIG_FILE}`, (cur, prev) => {
|
||||
|
|
|
@ -137,7 +137,7 @@ export default async function getBaseWebpackConfig (dir: string, {dev = false, i
|
|||
module: {
|
||||
rules: [
|
||||
dev && !isServer && {
|
||||
test: /\.(js|jsx)$/,
|
||||
test: defaultLoaders.hotSelfAccept.options.extensions,
|
||||
include: defaultLoaders.hotSelfAccept.options.include,
|
||||
use: defaultLoaders.hotSelfAccept
|
||||
},
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
"@taskr/esnext": "1.1.0",
|
||||
"@taskr/watch": "1.1.0",
|
||||
"@zeit/next-css": "0.0.7",
|
||||
"@zeit/next-typescript": "1.1.0",
|
||||
"babel-eslint": "8.2.2",
|
||||
"babel-jest": "21.2.0",
|
||||
"babel-plugin-istanbul": "4.1.5",
|
||||
|
|
|
@ -18,7 +18,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
|||
describe('App asPath', () => {
|
||||
beforeAll(async () => {
|
||||
appPort = await findPort()
|
||||
server = await launchApp(join(__dirname, '../'), appPort, true)
|
||||
server = await launchApp(join(__dirname, '../'), appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
|
|
|
@ -19,7 +19,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
|||
describe('Document and App', () => {
|
||||
beforeAll(async () => {
|
||||
context.appPort = await findPort()
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort, true)
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
|
|
|
@ -18,7 +18,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
|||
describe('Babel', () => {
|
||||
beforeAll(async () => {
|
||||
context.appPort = await findPort()
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort, true)
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
|
|
|
@ -23,7 +23,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
|||
describe('Basic Features', () => {
|
||||
beforeAll(async () => {
|
||||
context.appPort = await findPort()
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort, true)
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
|
|
|
@ -19,7 +19,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
|||
describe('Configuration', () => {
|
||||
beforeAll(async () => {
|
||||
context.appPort = await findPort()
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort, true)
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
|
|
6
test/integration/page-extensions/.babelrc
Normal file
6
test/integration/page-extensions/.babelrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"presets": [
|
||||
"next/babel",
|
||||
"@zeit/next-typescript/babel"
|
||||
]
|
||||
}
|
7
test/integration/page-extensions/next.config.js
Normal file
7
test/integration/page-extensions/next.config.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
const withTypescript = require('@zeit/next-typescript')
|
||||
module.exports = withTypescript({
|
||||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
}
|
||||
})
|
23
test/integration/page-extensions/pages/hmr/some-page.tsx
Normal file
23
test/integration/page-extensions/pages/hmr/some-page.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
|
||||
if(typeof window !== 'undefined' && !window['HMR_RANDOM_NUMBER']) {
|
||||
window['HMR_RANDOM_NUMBER'] = Math.random()
|
||||
}
|
||||
|
||||
export default class Counter extends React.Component {
|
||||
state = { count: 0 }
|
||||
|
||||
incr () {
|
||||
const { count } = this.state
|
||||
this.setState({ count: count + 1 })
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<p>COUNT: {this.state.count}</p>
|
||||
<button onClick={() => this.incr()}>Increment</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
9
test/integration/page-extensions/test/.babelrc
Normal file
9
test/integration/page-extensions/test/.babelrc
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"presets": [
|
||||
["next/babel", {
|
||||
"preset-env": {
|
||||
"modules": "commonjs"
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
40
test/integration/page-extensions/test/hmr.js
Normal file
40
test/integration/page-extensions/test/hmr.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* global describe, it, expect */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { waitFor } from 'next-test-utils'
|
||||
|
||||
export default (context, renderViaHTTP) => {
|
||||
describe('Hot Module Reloading', () => {
|
||||
it('should reload typescript file without refresh', async () => {
|
||||
let browser
|
||||
const pagePath = join(__dirname, '../', 'pages', 'hmr', 'some-page.tsx')
|
||||
|
||||
const originalContent = readFileSync(pagePath, 'utf8')
|
||||
const editedContent = originalContent.replace('Increment', 'INCREMENT')
|
||||
try {
|
||||
browser = await webdriver(context.appPort, '/hmr/some-page')
|
||||
const randomNumber = await browser.eval('window.HMR_RANDOM_NUMBER')
|
||||
const originalButtonText = await browser.elementByCss('button').text()
|
||||
expect(originalButtonText).toBe('Increment')
|
||||
|
||||
// Change the about.js page
|
||||
writeFileSync(pagePath, editedContent, 'utf8')
|
||||
|
||||
// wait for 5 seconds
|
||||
await waitFor(5000)
|
||||
|
||||
const randomNumberAfterEdit = await browser.eval('window.HMR_RANDOM_NUMBER')
|
||||
expect(randomNumberAfterEdit).toBe(randomNumber)
|
||||
const updatedButtonText = await browser.elementByCss('button').text()
|
||||
expect(updatedButtonText).toBe('INCREMENT')
|
||||
} finally {
|
||||
// restore the about page content.
|
||||
writeFileSync(pagePath, originalContent, 'utf8')
|
||||
if (browser) {
|
||||
browser.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
30
test/integration/page-extensions/test/index.test.js
Normal file
30
test/integration/page-extensions/test/index.test.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* global jasmine, describe, beforeAll, afterAll */
|
||||
|
||||
import { join } from 'path'
|
||||
import {
|
||||
renderViaHTTP,
|
||||
findPort,
|
||||
launchApp,
|
||||
killApp
|
||||
} from 'next-test-utils'
|
||||
|
||||
// test suits
|
||||
import hmr from './hmr'
|
||||
|
||||
const context = {}
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
||||
|
||||
describe('Page Extensions', () => {
|
||||
beforeAll(async () => {
|
||||
context.appPort = await findPort()
|
||||
context.server = await launchApp(join(__dirname, '../'), context.appPort)
|
||||
|
||||
// pre-build all pages at the start
|
||||
await Promise.all([
|
||||
renderViaHTTP(context.appPort, '/hmr/some-page')
|
||||
])
|
||||
})
|
||||
afterAll(() => killApp(context.server))
|
||||
|
||||
hmr(context, (p, q) => renderViaHTTP(context.appPort, p, q))
|
||||
})
|
|
@ -113,7 +113,7 @@ export async function startApp (app) {
|
|||
return server
|
||||
}
|
||||
|
||||
export async function stopApp (app) {
|
||||
export async function stopApp (server) {
|
||||
if (server.__app) {
|
||||
await server.__app.close()
|
||||
}
|
||||
|
|
26
yarn.lock
26
yarn.lock
|
@ -349,6 +349,12 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "7.0.0-beta.42"
|
||||
|
||||
"@babel/plugin-syntax-typescript@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.42.tgz#ffc42945ca15e5ab369de6b9f5d9324499c623cf"
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "7.0.0-beta.42"
|
||||
|
||||
"@babel/plugin-transform-arrow-functions@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.42.tgz#b918eb8760c38d6503a1a9858fa073786b60ab2b"
|
||||
|
@ -571,6 +577,13 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "7.0.0-beta.42"
|
||||
|
||||
"@babel/plugin-transform-typescript@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.0.0-beta.42.tgz#e3a2d46014fd26e0729fd574b521fca4eb21144f"
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "7.0.0-beta.42"
|
||||
"@babel/plugin-syntax-typescript" "7.0.0-beta.42"
|
||||
|
||||
"@babel/plugin-transform-unicode-regex@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.42.tgz#1e7bdcf678d9a9066d06e6d334ab41ca11ca00ad"
|
||||
|
@ -641,6 +654,13 @@
|
|||
"@babel/plugin-transform-react-jsx-self" "7.0.0-beta.42"
|
||||
"@babel/plugin-transform-react-jsx-source" "7.0.0-beta.42"
|
||||
|
||||
"@babel/preset-typescript@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.0.0-beta.42.tgz#adb91d387a6eee7b45918de544d6c8fa122c2564"
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "7.0.0-beta.42"
|
||||
"@babel/plugin-transform-typescript" "7.0.0-beta.42"
|
||||
|
||||
"@babel/runtime@7.0.0-beta.42":
|
||||
version "7.0.0-beta.42"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f"
|
||||
|
@ -751,6 +771,12 @@
|
|||
postcss-loader "^2.0.10"
|
||||
style-loader "^0.19.1"
|
||||
|
||||
"@zeit/next-typescript@1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@zeit/next-typescript/-/next-typescript-1.1.0.tgz#57a45c85c336fee8d71c1bd966195565016932b2"
|
||||
dependencies:
|
||||
"@babel/preset-typescript" "7.0.0-beta.42"
|
||||
|
||||
abab@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
|
||||
|
|
Loading…
Reference in a new issue