Skip to content

Commit

Permalink
Fix Typescript HMR (#4689)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
timneutkens authored Jun 28, 2018
1 parent 810705a commit 17e410a
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 7 deletions.
9 changes: 9 additions & 0 deletions bin/next
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
2 changes: 1 addition & 1 deletion build/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion test/integration/app-aspath/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion test/integration/app-document/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion test/integration/babel/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion test/integration/basic/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion test/integration/config/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
6 changes: 6 additions & 0 deletions test/integration/page-extensions/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
]
}
7 changes: 7 additions & 0 deletions test/integration/page-extensions/next.config.js
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions test/integration/page-extensions/pages/hmr/some-page.tsx
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions test/integration/page-extensions/test/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"presets": [
["next/babel", {
"preset-env": {
"modules": "commonjs"
}
}]
]
}
40 changes: 40 additions & 0 deletions test/integration/page-extensions/test/hmr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* global describe, it, expect */
import webdriver from 'next-webdriver'

This comment has been minimized.

Copy link
@codinronan

codinronan Jun 29, 2018

Wow this.. this is some hardcore work Tim. 💪

This comment has been minimized.

Copy link
@timneutkens

timneutkens Jun 29, 2018

Author Member

We test most HMR features, just didn’t do it for typescript yet 😄 check test/integration/basic/test/hmr

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 changes: 30 additions & 0 deletions test/integration/page-extensions/test/index.test.js
Original file line number Diff line number Diff line change
@@ -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))
})
2 changes: 1 addition & 1 deletion test/lib/next-test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
26 changes: 26 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,12 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.42"

"@babel/[email protected]":
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/[email protected]":
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"
Expand Down Expand Up @@ -571,6 +577,13 @@
dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.42"

"@babel/[email protected]":
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/[email protected]":
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"
Expand Down Expand Up @@ -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/[email protected]":
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/[email protected]":
version "7.0.0-beta.42"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f"
Expand Down Expand Up @@ -751,6 +771,12 @@
postcss-loader "^2.0.10"
style-loader "^0.19.1"

"@zeit/[email protected]":
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"
Expand Down

0 comments on commit 17e410a

Please sign in to comment.