2016-11-10 11:33:52 +00:00
'use strict'
2016-11-24 00:47:11 +00:00
const debug = require ( 'debug' ) ( 'nuxt:generate' )
2016-11-10 12:24:20 +00:00
const fs = require ( 'fs-extra' )
const co = require ( 'co' )
const pify = require ( 'pify' )
2016-11-24 00:47:11 +00:00
const pathToRegexp = require ( 'path-to-regexp' )
2016-11-10 11:33:52 +00:00
const _ = require ( 'lodash' )
2016-11-10 18:34:59 +00:00
const { resolve , join , dirname , sep } = require ( 'path' )
2016-12-08 17:44:17 +00:00
const { promisifyRouteParams } = require ( './utils' )
2016-12-12 22:09:08 +00:00
const { minify } = require ( '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 : { }
}
2016-11-10 12:24:20 +00:00
module . exports = function ( ) {
2016-12-08 17:07:14 +00:00
const s = Date . now ( )
2016-11-10 18:34:59 +00:00
/ *
* * Update loaders config to add router . base path
* /
2016-12-08 17:44:17 +00:00
// this.options.build.loaders.forEach((config) => {
// if (['file', 'url', 'file-loader', 'url-loader'].includes(config.loader)) {
// config.query = config.query || {}
// config.query.publicPath = urlJoin(this.options.router.base, '/_nuxt/')
// }
// })
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 )
var distNuxtPath = resolve ( distPath , '_nuxt' )
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 )
}
2016-12-12 20:54:02 +00:00
const toPath = pathToRegexp . compile ( route )
2016-12-08 17:07:14 +00:00
routes = routes . concat ( routeParams . map ( ( params ) => {
2016-12-12 20:54:02 +00:00
return toPath ( 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 )
}