Skip to content

Commit 3c88a3d

Browse files
authored
Merge pull request #31 from zeit/add/hot-reload
Hot code reloading
2 parents 142a6e3 + c697618 commit 3c88a3d

File tree

20 files changed

+327
-151
lines changed

20 files changed

+327
-151
lines changed

bin/next

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ const bin = resolve(__dirname, 'next-' + cmd)
2626
const proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] })
2727
proc.on('close', (code) => process.exit(code))
2828
proc.on('error', (err) => {
29-
console.log(err)
29+
console.error(err)
3030
process.exit(1)
3131
})

bin/next-dev

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { exec } from 'child_process'
33
import { resolve, join } from 'path'
44
import parseArgs from 'minimist'
55
import Server from '../server'
6-
import build from '../server/build'
6+
import HotReloader from '../server/hot-reloader'
7+
import webpack from '../server/build/webpack'
78
import { exists } from 'mz/fs'
89

910
const argv = parseArgs(process.argv.slice(2), {
@@ -25,9 +26,10 @@ const open = url => {
2526

2627
const dir = resolve(argv._[0] || '.')
2728

28-
build(dir)
29-
.then(async () => {
30-
const srv = new Server({ dir, dev: true })
29+
webpack(dir, { hotReload: true })
30+
.then(async (compiler) => {
31+
const hotReloader = new HotReloader(compiler)
32+
const srv = new Server({ dir, dev: true, hotReloader })
3133
await srv.start(argv.port)
3234
console.log('> Ready on http://localhost:%d', argv.port)
3335

client/next-dev.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
import './next'
1+
import 'react-hot-loader/patch'
2+
import 'webpack-dev-server/client?http://localhost:3030'
3+
import * as next from './next'
4+
5+
module.exports = next
6+
7+
window.next = next

client/next.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ const {
1313
const App = app ? evalScript(app).default : DefaultApp
1414
const Component = evalScript(component).default
1515

16-
const router = new Router(window.location.href, { Component })
16+
export const router = new Router(window.location.href, { Component })
17+
1718
const headManager = new HeadManager()
1819
const container = document.getElementById('__next')
1920
const appProps = { Component, props, router, headManager }
2021

2122
StyleSheet.rehydrate(classNames)
22-
render(createElement(App, { ...appProps }), container)
23+
render(createElement(App, appProps), container)

gulpfile.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ gulp.task('compile-test', () => {
6767
.pipe(notify('Compiled test files'))
6868
})
6969

70+
gulp.task('copy', [
71+
'copy-pages',
72+
'copy-test-fixtures'
73+
])
74+
75+
gulp.task('copy-pages', () => {
76+
return gulp.src('pages/**/*.js')
77+
.pipe(gulp.dest('dist/pages'))
78+
})
79+
7080
gulp.task('copy-test-fixtures', () => {
7181
return gulp.src('test/fixtures/**/*')
7282
.pipe(gulp.dest('dist/test/fixtures'))
@@ -98,7 +108,21 @@ gulp.task('build-dev-client', ['compile-lib', 'compile-client'], () => {
98108
.src('dist/client/next-dev.js')
99109
.pipe(webpack({
100110
quiet: true,
101-
output: { filename: 'next-dev.bundle.js' }
111+
output: { filename: 'next-dev.bundle.js' },
112+
module: {
113+
loaders: [
114+
{
115+
test: /eval-script\.js$/,
116+
exclude: /node_modules/,
117+
loader: 'babel',
118+
query: {
119+
plugins: [
120+
'babel-plugin-transform-remove-strict-mode'
121+
]
122+
}
123+
}
124+
]
125+
}
102126
}))
103127
.pipe(gulp.dest('dist/client'))
104128
.pipe(notify('Built dev client'))
@@ -117,7 +141,21 @@ gulp.task('build-release-client', ['compile-lib', 'compile-client'], () => {
117141
}
118142
}),
119143
new webpack.webpack.optimize.UglifyJsPlugin()
120-
]
144+
],
145+
module: {
146+
loaders: [
147+
{
148+
test: /eval-script\.js$/,
149+
exclude: /node_modules/,
150+
loader: 'babel',
151+
query: {
152+
plugins: [
153+
'babel-plugin-transform-remove-strict-mode'
154+
]
155+
}
156+
}
157+
]
158+
}
121159
}))
122160
.pipe(gulp.dest('dist/client'))
123161
.pipe(notify('Built release client'))
@@ -179,6 +217,7 @@ gulp.task('clean-test', () => {
179217
gulp.task('default', [
180218
'compile',
181219
'build',
220+
'copy',
182221
'test',
183222
'watch'
184223
])
@@ -187,6 +226,7 @@ gulp.task('release', (cb) => {
187226
sequence('clean', [
188227
'compile',
189228
'build-release',
229+
'copy',
190230
'test'
191231
], 'clean-test', cb)
192232
})

lib/app.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { Component, PropTypes } from 'react'
2+
import { AppContainer } from 'react-hot-loader'
23

34
export default class App extends Component {
45
static childContextTypes = {
@@ -51,7 +52,15 @@ export default class App extends Component {
5152

5253
render () {
5354
const { Component, props } = this.state
54-
return React.createElement(Component, { ...props })
55+
56+
if (typeof window === 'undefined') {
57+
// workaround for https://github.com/gaearon/react-hot-loader/issues/283
58+
return <Component {...props} />
59+
}
60+
61+
return <AppContainer>
62+
<Component {...props} />
63+
</AppContainer>
5564
}
5665
}
5766

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,25 @@
3333
"glob-promise": "1.0.6",
3434
"gulp-benchmark": "^1.1.1",
3535
"htmlescape": "1.1.1",
36+
"loader-utils": "0.2.16",
3637
"minimist": "1.2.0",
3738
"mkdirp-then": "1.2.0",
3839
"mz": "2.4.0",
3940
"path-match": "1.2.4",
4041
"react": "15.3.2",
4142
"react-dom": "15.3.2",
43+
"react-hot-loader": "3.0.0-beta.6",
4244
"resolve": "1.1.7",
4345
"run-sequence": "1.2.2",
4446
"send": "0.14.1",
4547
"url": "0.11.0",
46-
"webpack": "1.13.2"
48+
"webpack": "1.13.2",
49+
"webpack-dev-server": "1.16.2",
50+
"write-file-webpack-plugin": "3.3.0"
4751
},
4852
"devDependencies": {
4953
"babel-eslint": "^7.0.0",
54+
"babel-plugin-transform-remove-strict-mode": "0.0.2",
5055
"del": "2.2.2",
5156
"gulp": "3.9.1",
5257
"gulp-ava": "0.14.1",
File renamed without changes.

server/build/bundle.js

Lines changed: 0 additions & 53 deletions
This file was deleted.

server/build/index.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1-
import { resolve } from 'path'
2-
import glob from 'glob-promise'
3-
import transpile from './transpile'
4-
import bundle from './bundle'
1+
import webpack from './webpack'
52

63
export default async function build (dir) {
7-
const dstDir = resolve(dir, '.next')
8-
const templateDir = resolve(__dirname, '..', '..', 'lib', 'pages')
4+
const compiler = await webpack(dir)
95

10-
// create `.next/pages/_error.js`
11-
// which may be overwriten by the user script, `pages/_error.js`
12-
const templatPaths = await glob('**/*.js', { cwd: templateDir })
13-
await Promise.all(templatPaths.map(async (p) => {
14-
await transpile(resolve(templateDir, p), resolve(dstDir, 'pages', p))
15-
}))
6+
return new Promise((resolve, reject) => {
7+
compiler.run((err, stats) => {
8+
if (err) return reject(err)
169

17-
const paths = await glob('**/*.js', { cwd: dir, ignore: 'node_modules/**' })
18-
await Promise.all(paths.map(async (p) => {
19-
await transpile(resolve(dir, p), resolve(dstDir, p))
20-
}))
10+
const jsonStats = stats.toJson()
11+
if (jsonStats.errors.length > 0) {
12+
const error = new Error(jsonStats.errors[0])
13+
error.errors = jsonStats.errors
14+
error.warnings = jsonStats.warnings
15+
return reject(error)
16+
}
2117

22-
const pagePaths = await glob('pages/**/*.js', { cwd: dstDir })
23-
await Promise.all(pagePaths.map(async (p) => {
24-
await bundle(resolve(dstDir, p), resolve(dstDir, '_bundles', p))
25-
}))
18+
resolve()
19+
})
20+
})
2621
}

0 commit comments

Comments
 (0)