1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

write assets to disk

This commit is contained in:
nkzawa 2016-10-16 04:49:42 +09:00
parent e7ffb2c17d
commit 3032ade283
8 changed files with 57 additions and 61 deletions

View file

@ -3,7 +3,6 @@
import { resolve } from 'path'
import parseArgs from 'minimist'
import Server from '../server'
import build from '../server/build'
import HotReloader from '../server/hot-reloader'
import webpack from '../server/build/webpack'
@ -20,9 +19,8 @@ const argv = parseArgs(process.argv.slice(2), {
const dir = resolve(argv._[0] || '.')
build(dir)
.then(async () => {
const compiler = await webpack(dir, { hotReload: true })
webpack(dir, { hotReload: true })
.then(async (compiler) => {
const hotReloader = new HotReloader(compiler)
const srv = new Server({ dir, dev: true, hotReloader })
await srv.start(argv.port)

View file

@ -43,7 +43,8 @@
"send": "0.14.1",
"url": "0.11.0",
"webpack": "1.13.2",
"webpack-dev-server": "1.16.2"
"webpack-dev-server": "1.16.2",
"write-file-webpack-plugin": "3.3.0"
},
"devDependencies": {
"babel-plugin-transform-remove-strict-mode": "0.0.2",

View file

@ -1,6 +1,7 @@
import { resolve, join } from 'path'
import webpack from 'webpack'
import glob from 'glob-promise'
import WriteFilePlugin from 'write-file-webpack-plugin'
export default async function createCompiler(dir, { hotReload = false } = {}) {
dir = resolve(dir)
@ -20,6 +21,16 @@ export default async function createCompiler(dir, { hotReload = false } = {}) {
const nodeModulesDir = resolve(__dirname, '..', '..', '..', 'node_modules')
const plugins = hotReload ? [
new webpack.HotModuleReplacementPlugin(),
new WriteFilePlugin({ log: false })
] : [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
sourceMap: false
})
]
const babelRuntimePath = require.resolve('babel-runtime/package')
.replace(/[\\\/]package\.json$/, '');
@ -96,14 +107,7 @@ export default async function createCompiler(dir, { hotReload = false } = {}) {
resolve(__dirname, '..', 'loaders')
]
},
plugins: [
hotReload
? new webpack.HotModuleReplacementPlugin()
: new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
sourceMap: false
})
],
plugins,
module: {
preLoaders: [
{ test: /\.json$/, loader: 'json-loader' }

View file

@ -1,4 +1,5 @@
import WebpackDevServer from 'webpack-dev-server'
import read from './read'
export default class HotReloader {
constructor (compiler) {
@ -8,6 +9,17 @@ export default class HotReloader {
noInfo: true,
clientLogLevel: 'warning'
})
compiler.plugin('after-emit', (compilation, callback) => {
const { assets } = compilation
for (const f of Object.keys(assets)) {
const source = assets[f]
// delete updated file caches
delete require.cache[source.existsAt]
delete read.cache[source.existsAt]
}
callback()
})
}
async start () {

View file

@ -3,7 +3,6 @@ import { resolve } from 'path'
import send from 'send'
import Router from './router'
import { render, renderJSON } from './render'
import HotReloader from './hot-reloader'
export default class Server {
constructor ({ dir = '.', dev = false, hotReloader }) {
@ -63,11 +62,10 @@ export default class Server {
}
async render (req, res) {
const { dir, dev, hotReloader } = this
const mfs = hotReloader ? hotReloader.fileSystem : null
const { dir, dev } = this
let html
try {
html = await render(req.url, { req, res }, { dir, dev, mfs })
html = await render(req.url, { req, res }, { dir, dev })
} catch (err) {
if ('ENOENT' === err.code) {
res.statusCode = 404
@ -75,18 +73,17 @@ export default class Server {
console.error(err)
res.statusCode = 500
}
html = await render('/_error', { req, res, err }, { dir, dev, mfs })
html = await render('/_error', { req, res, err }, { dir, dev })
}
sendHTML(res, html)
}
async renderJSON (req, res) {
const { dir, hotReloader } = this
const mfs = hotReloader ? hotReloader.fileSystem : null
const { dir } = this
let json
try {
json = await renderJSON(req.url, { dir, mfs })
json = await renderJSON(req.url, { dir })
} catch (err) {
if ('ENOENT' === err.code) {
res.statusCode = 404
@ -94,7 +91,7 @@ export default class Server {
console.error(err)
res.statusCode = 500
}
json = await renderJSON('/_error.json', { dir, mfs })
json = await renderJSON('/_error.json', { dir })
}
const data = JSON.stringify(json)

View file

@ -1,42 +1,23 @@
import fs from 'mz/fs'
import resolve from './resolve'
const cache = {}
/**
* resolve a file like `require.resolve`,
* and read and cache the file content
*/
async function read (path, { mfs }) {
const f = await (mfs ? resolveFromMFS(path, mfs) : resolve(path))
if (mfs) {
return mfs.readFileSync(f, 'utf8')
} else {
let promise = cache[f]
if (!promise) {
promise = cache[f] = fs.readFile(f, 'utf8')
}
return promise
async function read (path, opts = {}) {
const f = await resolve(path)
if (cache.hasOwnProperty(f)) {
return cache[f]
}
const data = fs.readFile(f, 'utf8')
cache[f] = data
return data
}
function resolveFromMFS (path, mfs) {
const isFile = (file, cb) => {
if (!mfs.existsSync(file)) return cb(null, false)
export default read
export const cache = {}
let stat
try {
stat = mfs.statSync(file)
} catch (err) {
return cb(err)
}
cb(null, stat.isFile() || stat.isFIFO())
}
const readFile = mfs.readFile.bind(mfs)
return resolve(path, { isFile, readFile })
}
module.exports = read
exports.cache = cache
read.cache = cache

View file

@ -2,8 +2,7 @@ import { relative, resolve } from 'path'
import { parse } from 'url'
import { createElement } from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
import fs from 'mz/fs'
import requireResolve from './resolve'
import requireModule from './require'
import read from './read'
import Router from '../lib/router'
import Document from '../lib/document'
@ -14,16 +13,14 @@ import { StyleSheetServer } from '../lib/css'
export async function render (url, ctx = {}, {
dir = process.cwd(),
dev = false,
staticMarkup = false,
mfs
staticMarkup = false
} = {}) {
const path = getPath(url)
const p = await requireResolve(resolve(dir, '.next', 'pages', path))
const mod = require(p)
const mod = await requireModule(resolve(dir, '.next', 'pages', path))
const Component = mod.default || mod
const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {})
const component = await read(resolve(dir, '.next', '_bundles', 'pages', path), { mfs })
const component = await read(resolve(dir, '.next', '_bundles', 'pages', path))
const { html, css } = StyleSheetServer.renderStatic(() => {
const app = createElement(App, {
@ -54,9 +51,9 @@ export async function render (url, ctx = {}, {
return '<!DOCTYPE html>' + renderToStaticMarkup(doc)
}
export async function renderJSON (url, { dir = process.cwd(), mfs } = {}) {
export async function renderJSON (url, { dir = process.cwd() } = {}) {
const path = getPath(url)
const component = await read(resolve(dir, '.next', '_bundles', 'pages', path), { mfs })
const component = await read(resolve(dir, '.next', '_bundles', 'pages', path))
return { component }
}

6
server/require.js Normal file
View file

@ -0,0 +1,6 @@
import resolve from './resolve'
export default async function requireModule (path) {
const f = await resolve(path)
return require(f)
}