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:
parent
e7ffb2c17d
commit
3032ade283
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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' }
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
6
server/require.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import resolve from './resolve'
|
||||
|
||||
export default async function requireModule (path) {
|
||||
const f = await resolve(path)
|
||||
return require(f)
|
||||
}
|
Loading…
Reference in a new issue