feat: mode option

This commit is contained in:
Pooya Parsa 2017-07-11 04:54:39 +04:30
parent 3ef0d15f6b
commit a3be3cfe1b
4 changed files with 95 additions and 19 deletions

View File

@ -277,7 +277,9 @@ export default class Builder extends Tapable {
// Server
const serverConfig = serverWebpackConfig.call(this)
compilersOptions.push(serverConfig)
if (this.options.build.ssr) {
compilersOptions.push(serverConfig)
}
// Alias plugins to their real path
this.plugins.forEach(p => {

View File

@ -60,11 +60,23 @@ export default function webpackClientConfig () {
config.plugins = []
}
// Generate output HTML
// Generate output HTML for SSR
if (this.options.build.ssr) {
config.plugins.push(
new HTMLPlugin({
filename: 'index.ssr.html',
template: this.options.appTemplatePath,
inject: false // Resources will be injected using bundleRenderer
})
)
}
// Generate output HTML for SPA
config.plugins.push(
new HTMLPlugin({
filename: 'index.spa.html',
template: this.options.appTemplatePath,
inject: this.options.ssr === false,
inject: true,
chunksSortMode: 'dependency'
})
)

View File

@ -46,16 +46,57 @@ export default function Options (_options) {
options.store = true
}
// Resolve mode
let mode = options.mode
if (typeof mode === 'function') {
mode = mode()
}
if (typeof mode === 'string') {
mode = Modes[mode]
}
// Apply mode
_.defaultsDeep(options, mode)
return options
}
const Modes = {
universal: {
build: {
ssr: true
},
render: {
ssr: true
}
},
spa: {
build: {
ssr: false
},
render: {
ssr: false
}
},
static: {
build: {
ssr: true
},
render: {
ssr: 'static'
}
}
}
export const defaultOptions = {
dev: (process.env.NODE_ENV !== 'production'),
mode: 'universal',
dev: process.env.NODE_ENV !== 'production',
buildDir: '.nuxt',
nuxtAppDir: resolve(__dirname, '../lib/app/'), // Relative to dist
build: {
analyze: false,
extractCSS: false,
ssr: undefined,
publicPath: '/_nuxt/',
filenames: {
css: 'common.[chunkhash].css',
@ -133,10 +174,10 @@ export const defaultOptions = {
scrollBehavior: null,
fallback: false
},
ssr: true,
render: {
bundleRenderer: {},
resourceHints: true,
ssr: undefined,
http2: {
push: false
},

View File

@ -42,7 +42,8 @@ export default class Renderer extends Tapable {
this.resources = {
clientManifest: null,
serverBundle: null,
appTemplate: null,
ssrTemplate: null,
spaTemplate: null,
errorTemplate: parseTemplate('<pre>{{ stack }}</pre>') // Will be loaded on ready
}
@ -121,7 +122,18 @@ export default class Renderer extends Tapable {
}
get noSSR () {
return this.options.ssr === false
return this.options.render.ssr === false
}
get staticSSR () {
return this.options.render.ssr === 'static'
}
get isReady () {
if (this.noSSR) {
return this.resources.spaTemplate
}
return this.bundleRenderer && this.resources.ssrTemplate
}
createRenderer () {
@ -297,7 +309,7 @@ export default class Renderer extends Tapable {
async renderRoute (url, context = {}) {
/* istanbul ignore if */
if (!(this.noSSR || this.bundleRenderer) || !this.resources.appTemplate) {
if (!this.isReady) {
return new Promise(resolve => {
setTimeout(() => resolve(this.renderRoute(url, context)), 1000)
})
@ -315,7 +327,7 @@ export default class Renderer extends Tapable {
let APP = '<div id="__nuxt"></div>'
let HEAD = ''
let html = this.resources.appTemplate({
let html = this.resources.spaTemplate({
HTML_ATTRS: '',
BODY_ATTRS: '',
HEAD,
@ -340,15 +352,19 @@ export default class Renderer extends Tapable {
}
let resourceHints = ''
if (this.options.render.resourceHints) {
resourceHints = context.renderResourceHints()
HEAD += resourceHints
}
HEAD += context.renderStyles()
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })};</script>`
APP += context.renderScripts()
let html = this.resources.appTemplate({
if (!this.staticSSR) {
if (this.options.render.resourceHints) {
resourceHints = context.renderResourceHints()
HEAD += resourceHints
}
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })};</script>`
APP += context.renderScripts()
}
HEAD += context.renderStyles()
let html = this.resources.ssrTemplate({
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
BODY_ATTRS: m.bodyAttrs.text(),
HEAD,
@ -422,8 +438,13 @@ const resourceMap = [
transform: JSON.parse
},
{
key: 'appTemplate',
fileName: 'index.html',
key: 'ssrTemplate',
fileName: 'index.ssr.html',
transform: parseTemplate
},
{
key: 'spaTemplate',
fileName: 'index.spa.html',
transform: parseTemplate
}
]