mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +00:00
map static to /
v0.3.0
This commit is contained in:
parent
4fd3a8c131
commit
d88948bdea
11
README.md
11
README.md
@ -49,7 +49,7 @@ So far, we get:
|
|||||||
- Automatic transpilation and bundling (with webpack and babel)
|
- Automatic transpilation and bundling (with webpack and babel)
|
||||||
- Hot code reloading
|
- Hot code reloading
|
||||||
- Server rendering and indexing of `./pages`
|
- Server rendering and indexing of `./pages`
|
||||||
- Static file serving. `./static/` is mapped to `/static/`
|
- Static file serving. `./static/` is mapped to `/`
|
||||||
- Config file `nuxt.config.js`
|
- Config file `nuxt.config.js`
|
||||||
- Code splitting via webpack
|
- Code splitting via webpack
|
||||||
|
|
||||||
@ -97,8 +97,13 @@ This is mostly used for tests purpose but who knows!
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
nuxt.renderRoute('/about', context)
|
nuxt.renderRoute('/about', context)
|
||||||
.then(function (html) {
|
.then(function ({ html, error }) {
|
||||||
// HTML
|
// You can check error to know if your app displayed the error page for this route
|
||||||
|
// Useful to set the correct status status code if an error appended:
|
||||||
|
if (error) {
|
||||||
|
return res.status(error.statusCode || 500).send(html)
|
||||||
|
}
|
||||||
|
res.send(html)
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
// And error appended while rendering the route
|
// And error appended while rendering the route
|
||||||
|
@ -23,5 +23,5 @@ new Nuxt(options)
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
process.exit()
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
@ -15,6 +15,8 @@ if (typeof options.rootDir !== 'string') {
|
|||||||
options.rootDir = rootDir
|
options.rootDir = rootDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.dev = true // Add hot reloading and watching changes
|
||||||
|
|
||||||
new Nuxt(options)
|
new Nuxt(options)
|
||||||
.then((nuxt) => {
|
.then((nuxt) => {
|
||||||
new Server(nuxt)
|
new Server(nuxt)
|
||||||
@ -22,5 +24,5 @@ new Nuxt(options)
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
process.exit()
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
@ -25,5 +25,5 @@ new Nuxt(options)
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
process.exit()
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
@ -1,15 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<img src="/static/nuxt.png" />
|
<img src="/nuxt-square.png" />
|
||||||
<h2>About</h2>
|
<h2>Thank you for testing nuxt.js</h2>
|
||||||
<p><router-link to="/">Home</router-link></p>
|
<p><router-link to="/">Back home</router-link></p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.container {
|
.container {
|
||||||
font-family: serif;
|
position: absolute;
|
||||||
margin-top: 200px;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
font-family: "Lucida Console", Monaco, monospace;
|
||||||
|
padding-top: 130px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
a {
|
||||||
|
color: silver;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<img src="/static/nuxt.png" />
|
<img src="/nuxt.png" />
|
||||||
<h2>Hello World.</h2>
|
<h2>Hello World.</h2>
|
||||||
<p><router-link to="/about">About</router-link></p>
|
<p><router-link to="/about">About</router-link></p>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
examples/hello-world/static/nuxt-square.png
Normal file
BIN
examples/hello-world/static/nuxt-square.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
@ -40,6 +40,13 @@ async function renderAndGetWindow (route) {
|
|||||||
},
|
},
|
||||||
done (err, window) {
|
done (err, window) {
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
|
// If Nuxt could not be loaded (error from the server-side)
|
||||||
|
if (!window.__NUXT__) {
|
||||||
|
return reject({
|
||||||
|
message: 'Could not load the nuxt app',
|
||||||
|
body: window.document.getElementsByTagName('body')[0].innerHTML
|
||||||
|
})
|
||||||
|
}
|
||||||
// Used by nuxt.js to say when the components are loaded and the app ready
|
// Used by nuxt.js to say when the components are loaded and the app ready
|
||||||
window.onNuxtReady = function () {
|
window.onNuxtReady = function () {
|
||||||
resolve(window)
|
resolve(window)
|
||||||
@ -54,7 +61,7 @@ async function renderAndGetWindow (route) {
|
|||||||
*/
|
*/
|
||||||
test('Route / exits and render HTML', async t => {
|
test('Route / exits and render HTML', async t => {
|
||||||
let context = {}
|
let context = {}
|
||||||
const html = await nuxt.renderRoute('/', context)
|
const { html } = await nuxt.renderRoute('/', context)
|
||||||
t.true(html.includes('<p class="red-color">Hello world!</p>'))
|
t.true(html.includes('<p class="red-color">Hello world!</p>'))
|
||||||
t.is(context.nuxt.error, null)
|
t.is(context.nuxt.error, null)
|
||||||
t.is(context.nuxt.data[0].name, 'world')
|
t.is(context.nuxt.data[0].name, 'world')
|
||||||
|
@ -52,6 +52,10 @@ module.exports = function * () {
|
|||||||
if (noBuild) {
|
if (noBuild) {
|
||||||
const serverConfig = getWebpackServerConfig.call(this)
|
const serverConfig = getWebpackServerConfig.call(this)
|
||||||
const bundlePath = join(serverConfig.output.path, serverConfig.output.filename)
|
const bundlePath = join(serverConfig.output.path, serverConfig.output.filename)
|
||||||
|
if (!fs.existsSync(bundlePath)) {
|
||||||
|
console.error('> No build files found, please run `nuxt build` before launching `nuxt start`')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
createRenderer.call(this, fs.readFileSync(bundlePath, 'utf8'))
|
createRenderer.call(this, fs.readFileSync(bundlePath, 'utf8'))
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
@ -64,15 +68,15 @@ module.exports = function * () {
|
|||||||
} else {
|
} else {
|
||||||
console.error('> Couldn\'t find a `pages` directory. Please create one under the project root')
|
console.error('> Couldn\'t find a `pages` directory. Please create one under the project root')
|
||||||
}
|
}
|
||||||
process.exit()
|
process.exit(1)
|
||||||
}
|
}
|
||||||
if (this.options.store && !fs.existsSync(join(this.dir, 'store'))) {
|
if (this.options.store && !fs.existsSync(join(this.dir, 'store'))) {
|
||||||
console.error('> No `store` directory found (store option activated). Please create on under the project root')
|
console.error('> No `store` directory found (store option activated). Please create on under the project root')
|
||||||
process.exit()
|
process.exit(1)
|
||||||
}
|
}
|
||||||
if (this.options.store && !fs.existsSync(join(this.dir, 'store', 'index.js'))) {
|
if (this.options.store && !fs.existsSync(join(this.dir, 'store', 'index.js'))) {
|
||||||
console.error('> No `store/index.js` file found (store option activated). Please create the file.')
|
console.error('> No `store/index.js` file found (store option activated). Please create the file.')
|
||||||
process.exit()
|
process.exit(1)
|
||||||
}
|
}
|
||||||
debug(`App root: ${this.dir}`)
|
debug(`App root: ${this.dir}`)
|
||||||
debug('Generating .nuxt/ files...')
|
debug('Generating .nuxt/ files...')
|
||||||
|
31
lib/nuxt.js
31
lib/nuxt.js
@ -44,8 +44,11 @@ class Nuxt {
|
|||||||
})
|
})
|
||||||
// renderer used by Vue.js (via createBundleRenderer)
|
// renderer used by Vue.js (via createBundleRenderer)
|
||||||
this.renderer = null
|
this.renderer = null
|
||||||
|
// For serving static/ files to /
|
||||||
|
this.serveStatic = pify(serveStatic(resolve(this.dir, 'static')))
|
||||||
// For serving .nuxt/dist/ files
|
// For serving .nuxt/dist/ files
|
||||||
this.serveStatic = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
|
this._nuxtRegexp = /^\/_nuxt\//
|
||||||
|
this.serveStaticNuxt = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
|
||||||
// Add this.build
|
// Add this.build
|
||||||
this.build = build.bind(this)
|
this.build = build.bind(this)
|
||||||
// Launch build and set this.renderer
|
// Launch build and set this.renderer
|
||||||
@ -74,25 +77,27 @@ class Nuxt {
|
|||||||
// Call webpack middlewares only in development
|
// Call webpack middlewares only in development
|
||||||
yield self.webpackDevMiddleware(req, res)
|
yield self.webpackDevMiddleware(req, res)
|
||||||
yield self.webpackHotMiddleware(req, res)
|
yield self.webpackHotMiddleware(req, res)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if (req.url.includes('/_nuxt/')) {
|
// Serve static/ files
|
||||||
|
yield self.serveStatic(req, res)
|
||||||
|
// Serve .nuxt/dist/ files (only for production)
|
||||||
|
if (!self.dev && self._nuxtRegexp.test(req.url)) {
|
||||||
const url = req.url
|
const url = req.url
|
||||||
req.url = req.url.replace('/_nuxt/', '/')
|
req.url = req.url.replace(self._nuxtRegexp, '/')
|
||||||
yield self.serveStatic(req, res)
|
yield self.serveStaticNuxt(req, res)
|
||||||
req.url = url
|
req.url = url
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (this.dev && req.url.includes('/_nuxt/') && req.url.includes('.hot-update.json')) {
|
if (this.dev && this._nuxtRegexp.test(req.url) && req.url.includes('.hot-update.json')) {
|
||||||
res.statusCode = 404
|
res.statusCode = 404
|
||||||
return res.end()
|
return res.end()
|
||||||
}
|
}
|
||||||
return this.renderRoute(req.url, context)
|
return this.renderRoute(req.url, context)
|
||||||
})
|
})
|
||||||
.then((html) => {
|
.then(({ html, error }) => {
|
||||||
if (context.nuxt.error && context.nuxt.error.statusCode) {
|
if (error) {
|
||||||
res.statusCode = context.nuxt.error.statusCode
|
res.statusCode = context.nuxt.error.statusCode || 500
|
||||||
}
|
}
|
||||||
res.end(html, 'utf8')
|
res.end(html, 'utf8')
|
||||||
})
|
})
|
||||||
@ -110,13 +115,13 @@ class Nuxt {
|
|||||||
// Call rendertoSting from the bundleRenderer and generate the HTML (will update the context as well)
|
// Call rendertoSting from the bundleRenderer and generate the HTML (will update the context as well)
|
||||||
const self = this
|
const self = this
|
||||||
return co(function * () {
|
return co(function * () {
|
||||||
const html = yield self.renderToString(context)
|
const app = yield self.renderToString(context)
|
||||||
if (context.nuxt && context.nuxt.error instanceof Error) {
|
if (context.nuxt && context.nuxt.error instanceof Error) {
|
||||||
context.nuxt.error = { statusCode: 500, message: context.nuxt.error.message }
|
context.nuxt.error = { statusCode: 500, message: context.nuxt.error.message }
|
||||||
}
|
}
|
||||||
const app = self.appTemplate({
|
const html = self.appTemplate({
|
||||||
dev: self.dev, // Use to add the extracted CSS <link> in production
|
dev: self.dev, // Use to add the extracted CSS <link> in production
|
||||||
APP: html,
|
APP: app,
|
||||||
context: context,
|
context: context,
|
||||||
files: {
|
files: {
|
||||||
css: join('/_nuxt/', self.options.build.filenames.css),
|
css: join('/_nuxt/', self.options.build.filenames.css),
|
||||||
@ -124,7 +129,7 @@ class Nuxt {
|
|||||||
app: join('/_nuxt/', self.options.build.filenames.app)
|
app: join('/_nuxt/', self.options.build.filenames.app)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return app
|
return { html, error: context.nuxt.error }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,41 +1,14 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const http = require('http')
|
const http = require('http')
|
||||||
const co = require('co')
|
|
||||||
const pify = require('pify')
|
|
||||||
const serveStatic = require('serve-static')
|
|
||||||
const { resolve } = require('path')
|
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
|
|
||||||
constructor (nuxt) {
|
constructor (nuxt) {
|
||||||
this.server = http.createServer(this.handle.bind(this))
|
this.server = http.createServer(nuxt.render.bind(nuxt))
|
||||||
this.serveStatic = pify(serveStatic(resolve(nuxt.dir, 'static')))
|
|
||||||
this.nuxt = nuxt
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
handle (req, res) {
|
|
||||||
const method = req.method.toUpperCase()
|
|
||||||
const self = this
|
|
||||||
|
|
||||||
if (method !== 'GET' && method !== 'HEAD') {
|
|
||||||
return this.nuxt.render(req, res)
|
|
||||||
}
|
|
||||||
co(function * () {
|
|
||||||
if (req.url.includes('/static/')) {
|
|
||||||
const url = req.url
|
|
||||||
req.url = req.url.replace('/static/', '/')
|
|
||||||
yield self.serveStatic(req, res)
|
|
||||||
req.url = url
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// File not found
|
|
||||||
this.nuxt.render(req, res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
listen (port, host) {
|
listen (port, host) {
|
||||||
host = host || 'localhost'
|
host = host || 'localhost'
|
||||||
port = port || 3000
|
port = port || 3000
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nuxt",
|
"name": "nuxt",
|
||||||
"version": "0.2.6",
|
"version": "0.3.0",
|
||||||
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
|
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
Loading…
Reference in New Issue
Block a user