2016-11-10 11:33:52 +00:00
'use strict'
2016-11-24 00:47:11 +00:00
const debug = require ( 'debug' ) ( 'nuxt:generate' )
2017-01-11 19:14:59 +00:00
import fs from 'fs-extra'
import co from 'co'
import pify from 'pify'
import pathToRegexp from 'path-to-regexp'
import _ from 'lodash'
import { resolve , join , dirname , sep } from 'path'
import { promisifyRouteParams } from './utils'
import { minify } from 'html-minifier'
2016-11-10 12:24:20 +00:00
const copy = pify ( fs . copy )
const remove = pify ( fs . remove )
const writeFile = pify ( fs . writeFile )
2016-11-10 13:51:40 +00:00
const mkdirp = pify ( fs . mkdirp )
2016-11-10 11:33:52 +00:00
const defaults = {
dir : 'dist' ,
routeParams : { }
}
2017-01-11 19:14:59 +00:00
export default function ( ) {
2016-12-08 17:07:14 +00:00
const s = Date . now ( )
2016-11-10 18:34:59 +00:00
/ *
2016-11-10 11:33:52 +00:00
* * Set variables
* /
this . options . generate = _ . defaultsDeep ( this . options . generate , defaults )
2016-11-10 18:34:59 +00:00
var self = this
2016-12-08 06:45:40 +00:00
var srcStaticPath = resolve ( this . srcDir , 'static' )
2016-11-10 11:33:52 +00:00
var srcBuiltPath = resolve ( this . dir , '.nuxt' , 'dist' )
var distPath = resolve ( this . dir , this . options . generate . dir )
2017-02-16 17:16:00 +00:00
var distNuxtPath = join ( distPath , ( this . options . build . publicPath . indexOf ( 'http' ) === 0 ? '_nuxt' : this . options . build . publicPath ) )
2016-11-10 13:46:16 +00:00
return co ( function * ( ) {
2016-11-10 18:34:59 +00:00
/ *
* * Launch build process
* /
yield self . build ( )
2016-11-10 12:24:20 +00:00
/ *
* * Clean destination folder
* /
try {
yield remove ( distPath )
debug ( 'Destination folder cleaned' )
} catch ( e ) { }
/ *
* * Copy static and built files
* /
2016-11-10 14:09:10 +00:00
if ( fs . existsSync ( srcStaticPath ) ) {
yield copy ( srcStaticPath , distPath )
}
yield copy ( srcBuiltPath , distNuxtPath )
2016-11-10 12:24:20 +00:00
debug ( 'Static & build files copied' )
2016-11-10 11:33:52 +00:00
} )
2016-11-24 00:47:11 +00:00
. then ( ( ) => {
// Resolve config.generate.routesParams promises before generating the routes
return resolveRouteParams ( this . options . generate . routeParams )
} )
2016-11-10 12:24:20 +00:00
. then ( ( ) => {
/ *
* * Generate html files from routes
* /
2016-12-08 17:07:14 +00:00
let routes = [ ]
2016-11-10 13:46:16 +00:00
this . routes . forEach ( ( route ) => {
2016-12-12 20:54:02 +00:00
if ( route . includes ( ':' ) || route . includes ( '*' ) ) {
const routeParams = this . options . generate . routeParams [ route ]
2016-11-24 00:47:11 +00:00
if ( ! routeParams ) {
2016-12-12 20:54:02 +00:00
console . error ( ` Could not generate the dynamic route ${ route } , please add the mapping params in nuxt.config.js (generate.routeParams). ` ) // eslint-disable-line no-console
2016-11-24 00:47:11 +00:00
return process . exit ( 1 )
}
2017-02-22 17:13:23 +00:00
const toPathRegexp = pathToRegexp . compile ( route )
2016-12-08 17:07:14 +00:00
routes = routes . concat ( routeParams . map ( ( params ) => {
2017-02-22 17:13:23 +00:00
return toPathRegexp ( params )
2016-12-08 17:07:14 +00:00
} ) )
2016-11-24 00:47:11 +00:00
} else {
2016-12-08 17:07:14 +00:00
routes . push ( route )
2016-11-24 00:47:11 +00:00
}
2016-12-08 17:07:14 +00:00
} )
return co ( function * ( ) {
while ( routes . length ) {
yield routes . splice ( 0 , 500 ) . map ( ( route ) => {
2016-11-24 00:47:11 +00:00
return co ( function * ( ) {
2016-12-21 14:03:23 +00:00
var { html } = yield self . renderRoute ( route , { _generate : true } )
2016-12-12 22:09:08 +00:00
html = minify ( html , {
2016-12-12 22:15:54 +00:00
collapseBooleanAttributes : true ,
collapseWhitespace : true ,
decodeEntities : true ,
minifyCSS : true ,
minifyJS : true ,
processConditionalComments : true ,
2016-12-21 14:03:23 +00:00
removeAttributeQuotes : false ,
removeComments : false ,
2016-12-12 22:15:54 +00:00
removeEmptyAttributes : true ,
removeOptionalTags : true ,
removeRedundantAttributes : true ,
removeScriptTypeAttributes : true ,
removeStyleLinkTypeAttributes : true ,
removeTagWhitespace : true ,
sortAttributes : true ,
sortClassName : true ,
trimCustomFragments : true ,
useShortDoctype : true
2016-12-12 22:09:08 +00:00
} )
2016-12-12 20:54:02 +00:00
var path = join ( route , sep , 'index.html' ) // /about -> /about/index.html
2016-12-08 17:07:14 +00:00
debug ( 'Generate file: ' + path )
path = join ( distPath , path )
// Make sure the sub folders are created
2016-11-24 00:47:11 +00:00
yield mkdirp ( dirname ( path ) )
yield writeFile ( path , html , 'utf8' )
} )
2016-11-10 13:51:40 +00:00
} )
2016-12-08 17:07:14 +00:00
}
2016-11-10 11:33:52 +00:00
} )
2016-11-10 12:24:20 +00:00
} )
. then ( ( pages ) => {
2016-11-27 17:11:41 +00:00
// Add .nojekyll file to let Github Pages add the _nuxt/ folder
// https://help.github.com/articles/files-that-start-with-an-underscore-are-missing/
const nojekyllPath = resolve ( distPath , '.nojekyll' )
2016-11-27 17:45:50 +00:00
return writeFile ( nojekyllPath , '' )
2016-11-27 17:11:41 +00:00
} )
. then ( ( ) => {
2016-12-08 17:07:14 +00:00
const duration = Math . round ( ( Date . now ( ) - s ) / 100 ) / 10
debug ( ` HTML Files generated in ${ duration } s ` )
return this
2016-11-10 11:33:52 +00:00
} )
}
2016-11-24 00:47:11 +00:00
function resolveRouteParams ( routeParams ) {
let promises = [ ]
Object . keys ( routeParams ) . forEach ( function ( routePath ) {
let promise = promisifyRouteParams ( routeParams [ routePath ] )
2016-12-21 19:50:46 +00:00
promise . then ( ( routeParamsData ) => {
2016-11-24 00:47:11 +00:00
routeParams [ routePath ] = routeParamsData
} )
. catch ( ( e ) => {
2016-12-08 15:41:20 +00:00
console . error ( ` Could not resolve routeParams[ ${ routePath } ] ` ) // eslint-disable-line no-console
console . error ( e ) // eslint-disable-line no-console
2016-11-24 00:47:11 +00:00
process . exit ( 1 )
} )
promises . push ( promise )
} )
return Promise . all ( promises )
}