diff --git a/jest.config.js b/jest.config.js
index 68e437d910..abda43df22 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -19,7 +19,8 @@ module.exports = {
// But its performance overhead is pretty bad (30+%).
// detectOpenHandles: true
- setupFilesAfterEnv: ['./test/utils/setup'],
+ setupFilesAfterEnv: ['./test/utils/setup-env'],
+ setupFiles: ['./test/utils/setup'],
coverageDirectory: './coverage',
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 608ee65593..1b6c34375c 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -20,10 +20,13 @@
"compression": "^1.7.4",
"connect": "^3.7.0",
"consola": "^2.14.0",
+ "crc": "^3.8.0",
+ "destr": "^1.0.0",
"esm": "^3.2.25",
"execa": "^3.4.0",
"exit": "^0.1.2",
"fs-extra": "^8.1.0",
+ "globby": "^11.0.1",
"hable": "^3.0.0",
"minimist": "^1.2.5",
"opener": "1.5.1",
diff --git a/packages/cli/src/commands/build.js b/packages/cli/src/commands/build.js
index 060c028a25..5224654c7c 100644
--- a/packages/cli/src/commands/build.js
+++ b/packages/cli/src/commands/build.js
@@ -85,7 +85,7 @@ export default {
const builder = await cmd.getBuilder(nuxt)
await builder.build()
- const nextCommand = nuxt.options.target === TARGETS.static ? 'nuxt export' : 'nuxt start'
+ const nextCommand = nuxt.options.target === TARGETS.static ? 'nuxt generate' : 'nuxt start'
consola.info('Ready to run `' + (nextCommand) + '`')
}
}
diff --git a/packages/cli/src/commands/export.js b/packages/cli/src/commands/export.js
index a77ebb6046..c1fd3656d2 100644
--- a/packages/cli/src/commands/export.js
+++ b/packages/cli/src/commands/export.js
@@ -1,50 +1,10 @@
-import path from 'path'
import consola from 'consola'
-import { TARGETS } from '@nuxt/utils'
-import { common, locking } from '../options'
-import { createLock } from '../utils'
+import generate from './generate'
export default {
- name: 'export',
- description: 'Export a static generated web application',
- usage: 'export
',
- options: {
- ...common,
- ...locking,
- 'fail-on-error': {
- type: 'boolean',
- default: false,
- description: 'Exit with non-zero status code if there are errors when exporting pages'
- }
- },
- async run (cmd) {
- const config = await cmd.getNuxtConfig({
- dev: false,
- target: TARGETS.static,
- _export: true
- })
- const nuxt = await cmd.getNuxt(config)
-
- if (cmd.argv.lock) {
- await cmd.setLock(await createLock({
- id: 'export',
- dir: nuxt.options.generate.dir,
- root: config.rootDir
- }))
- }
-
- const generator = await cmd.getGenerator(nuxt)
- await nuxt.server.listen(0)
-
- const { errors } = await generator.generate({
- init: true,
- build: false
- })
-
- await nuxt.close()
- if (cmd.argv['fail-on-error'] && errors.length > 0) {
- throw new Error('Error exporting pages, exiting with non-zero code')
- }
- consola.info('Ready to run `nuxt serve` or deploy `' + path.basename(nuxt.options.generate.dir) + '/` directory')
+ ...generate,
+ run (...args) {
+ consola.warn('`nuxt export` has been deprecated! Please use `nuxt generate`.')
+ return generate.run.call(this, ...args)
}
}
diff --git a/packages/cli/src/commands/generate.js b/packages/cli/src/commands/generate.js
index b77a8d09e7..68f248c1d0 100644
--- a/packages/cli/src/commands/generate.js
+++ b/packages/cli/src/commands/generate.js
@@ -1,6 +1,7 @@
import { TARGETS } from '@nuxt/utils'
import { common, locking } from '../options'
import { normalizeArg, createLock } from '../utils'
+import { ensureBuild, generate } from '../utils/generate'
export default {
name: 'generate',
@@ -54,23 +55,22 @@ export default {
}
},
async run (cmd) {
- const config = await cmd.getNuxtConfig({
- dev: false,
- _build: cmd.argv.build,
- _generate: true
- })
-
- if (config.target === TARGETS.static) {
- throw new Error("Please use `nuxt export` when using `target: 'static'`")
- }
-
- // Forcing static target anyway
- config.target = TARGETS.static
+ const config = await cmd.getNuxtConfig({ dev: false })
// Disable analyze if set by the nuxt config
config.build = config.build || {}
config.build.analyze = false
+ // Full static
+ if (config.target === TARGETS.static) {
+ await ensureBuild(cmd)
+ await generate(cmd)
+ return
+ }
+
+ // Forcing static target anyway
+ config.target = TARGETS.static
+
// Set flag to keep the prerendering behaviour
config._legacyGenerate = true
diff --git a/packages/cli/src/commands/serve.js b/packages/cli/src/commands/serve.js
index 6867898aea..864cfd54c7 100644
--- a/packages/cli/src/commands/serve.js
+++ b/packages/cli/src/commands/serve.js
@@ -1,84 +1,10 @@
-import { promises as fs } from 'fs'
-import { join, extname, basename } from 'path'
-import connect from 'connect'
-import serveStatic from 'serve-static'
-import compression from 'compression'
-import { getNuxtConfig } from '@nuxt/config'
-import { TARGETS } from '@nuxt/utils'
-import { common, server } from '../options'
-import { showBanner } from '../utils/banner'
-import * as imports from '../imports'
+import consola from 'consola'
+import start from './start'
export default {
- name: 'serve',
- description: 'Serve the exported static application (should be compiled with `nuxt build` and `nuxt export` first)',
- usage: 'serve ',
- options: {
- 'config-file': common['config-file'],
- version: common.version,
- help: common.help,
- ...server
- },
- async run (cmd) {
- let options = await cmd.getNuxtConfig({ dev: false })
- // add default options
- options = getNuxtConfig(options)
- try {
- // overwrites with build config
- const buildConfig = require(join(options.buildDir, 'nuxt/config.json'))
- options.target = buildConfig.target
- } catch (err) {}
-
- if (options.target === TARGETS.server) {
- throw new Error('You cannot use `nuxt serve` with ' + TARGETS.server + ' target, please use `nuxt start`')
- }
- const distStat = await fs.stat(options.generate.dir).catch(err => null) // eslint-disable-line handle-callback-err
- if (!distStat || !distStat.isDirectory()) {
- throw new Error('Output directory `' + basename(options.generate.dir) + '/` does not exists, please run `nuxt export` before `nuxt serve`.')
- }
- const app = connect()
- app.use(compression({ threshold: 0 }))
- app.use(
- options.router.base,
- serveStatic(options.generate.dir, {
- extensions: ['html']
- })
- )
- if (options.generate.fallback) {
- const fallbackFile = await fs.readFile(join(options.generate.dir, options.generate.fallback), 'utf-8')
- app.use((req, res, next) => {
- const ext = extname(req.url) || '.html'
-
- if (ext !== '.html') {
- return next()
- }
- res.writeHeader(200, {
- 'Content-Type': 'text/html'
- })
- res.write(fallbackFile)
- res.end()
- })
- }
-
- const { port, host, socket, https } = options.server
- const { Listener } = await imports.server()
- const listener = new Listener({
- port,
- host,
- socket,
- https,
- app,
- dev: true, // try another port if taken
- baseURL: options.router.base
- })
- await listener.listen()
- const { Nuxt } = await imports.core()
- showBanner({
- constructor: Nuxt,
- options,
- server: {
- listeners: [listener]
- }
- }, false)
+ ...start,
+ run (...args) {
+ consola.warn('`nuxt serve` has been deprecated! Please use `nuxt start`.')
+ return start.run.call(this, ...args)
}
}
diff --git a/packages/cli/src/commands/start.js b/packages/cli/src/commands/start.js
index e462b6207b..a120a405b1 100644
--- a/packages/cli/src/commands/start.js
+++ b/packages/cli/src/commands/start.js
@@ -1,6 +1,8 @@
import { TARGETS } from '@nuxt/utils'
+import consola from 'consola'
import { common, server } from '../options'
import { showBanner } from '../utils/banner'
+import { serve } from '../utils/serve'
export default {
name: 'start',
@@ -12,9 +14,12 @@ export default {
},
async run (cmd) {
const config = await cmd.getNuxtConfig({ dev: false, _start: true })
+
if (config.target === TARGETS.static) {
- throw new Error('You cannot use `nuxt start` with ' + TARGETS.static + ' target, please use `nuxt export` and `nuxt serve`')
+ consola.info('Serving static dist')
+ return serve(cmd)
}
+
const nuxt = await cmd.getNuxt(config)
// Listen and show ready banner
diff --git a/packages/cli/src/utils/generate.js b/packages/cli/src/utils/generate.js
new file mode 100644
index 0000000000..830cee85da
--- /dev/null
+++ b/packages/cli/src/utils/generate.js
@@ -0,0 +1,161 @@
+import fs from 'fs'
+import path, { relative } from 'path'
+import crc32 from 'crc/lib/crc32'
+import consola from 'consola'
+import globby from 'globby'
+import destr from 'destr'
+import { TARGETS } from '@nuxt/utils'
+
+export async function generate (cmd) {
+ const nuxt = await getNuxt({ server: true }, cmd)
+ const generator = await cmd.getGenerator(nuxt)
+
+ await nuxt.server.listen(0)
+ await generator.generate({ build: false })
+ await nuxt.close()
+}
+
+export async function ensureBuild (cmd) {
+ const nuxt = await getNuxt({ _build: true, server: false }, cmd)
+ const { options } = nuxt
+
+ if (options.generate.cache === false || process.env.NUXT_BUILD) {
+ const builder = await cmd.getBuilder(nuxt)
+ await builder.build()
+ await nuxt.close()
+ }
+
+ // Default build ignore files
+ const ignore = [
+ options.buildDir,
+ options.dir.static,
+ options.generate.dir,
+ 'node_modules',
+ '.**/*',
+ '.*',
+ 'README.md'
+ ]
+
+ // Extend ignore
+ const { generate } = options
+ if (generate.cache.ignore === 'function') {
+ generate.cache.ignore = generate.cache.ignore(ignore)
+ } else if (Array.isArray(generate.cache.ignore)) {
+ generate.cache.ignore = generate.cache.ignore.concat(ignore)
+ }
+ await nuxt.callHook('generate:cache:ignore', generate.cache.ignore)
+
+ // Take a snapshot of current project
+ const snapshotOptions = {
+ rootDir: nuxt.options.rootDir,
+ ignore: nuxt.options.generate.cache.ignore,
+ globbyOptions: nuxt.options.generate.cache.globbyOptions
+ }
+
+ const currentBuildSnapshot = await snapshot(snapshotOptions)
+
+ // Current build meta
+ const currentBuild = {
+ // @ts-ignore
+ nuxtVersion: nuxt.constructor.version,
+ ssr: nuxt.options.ssr,
+ target: nuxt.options.target,
+ snapshot: currentBuildSnapshot
+ }
+
+ // Check if build can be skipped
+ const nuxtBuildFile = path.resolve(nuxt.options.buildDir, 'build.json')
+ if (fs.existsSync(nuxtBuildFile)) {
+ const previousBuild = destr(fs.readFileSync(nuxtBuildFile, 'utf-8')) || {}
+
+ // Quick diff
+ const needBuild = false
+ for (const field of ['nuxtVersion', 'ssr', 'target']) {
+ if (previousBuild[field] !== currentBuild[field]) {
+ consola.info(`Doing webpack rebuild because ${field} changed`)
+ break
+ }
+ }
+
+ // Full snapshot diff
+ if (!needBuild) {
+ const changed = compareSnapshots(previousBuild.snapshot, currentBuild.snapshot)
+ if (!changed) {
+ consola.success('Skipping webpack build as no changes detected')
+ return
+ } else {
+ consola.info(`Doing webpack rebuild because ${changed} modified`)
+ }
+ }
+ }
+
+ // Webpack build
+ const builder = await cmd.getBuilder(nuxt)
+ await builder.build()
+
+ // Write build.json
+ fs.writeFileSync(nuxtBuildFile, JSON.stringify(currentBuild, null, 2), 'utf-8')
+
+ await nuxt.close()
+}
+
+async function getNuxt (args, cmd) {
+ const config = await cmd.getNuxtConfig({ dev: false, ...args })
+
+ if (config.target === TARGETS.static) {
+ config._export = true
+ } else {
+ config._legacyGenerate = true
+ }
+ config.buildDir = (config.static && config.static.cacheDir) || path.resolve(config.rootDir, 'node_modules/.cache/nuxt')
+ config.build = config.build || {}
+ config.build.transpile = config.build.transpile || []
+ config.build.transpile.push(config.buildDir)
+
+ const nuxt = await cmd.getNuxt(config)
+
+ return nuxt
+}
+
+export function compareSnapshots (from, to) {
+ const allKeys = Array.from(new Set([
+ ...Object.keys(from).sort(),
+ ...Object.keys(to).sort()
+ ]))
+
+ for (const key of allKeys) {
+ if (JSON.stringify(from[key]) !== JSON.stringify(to[key])) {
+ return key
+ }
+ }
+
+ return false
+}
+
+export async function snapshot ({ globbyOptions, ignore, rootDir }) {
+ const snapshot = {}
+
+ const files = await globby('**/*.*', {
+ ...globbyOptions,
+ ignore,
+ cwd: rootDir,
+ absolute: true
+ })
+
+ await Promise.all(files.map(async (p) => {
+ const key = relative(rootDir, p)
+ try {
+ const fileContent = await fs.readFile(p)
+ snapshot[key] = {
+ checksum: await crc32(fileContent).toString(16)
+ }
+ } catch (e) {
+ // TODO: Check for other errors like permission denied
+ snapshot[key] = {
+ exists: false
+ }
+ }
+ }))
+
+ return snapshot
+}
diff --git a/packages/cli/src/utils/serve.js b/packages/cli/src/utils/serve.js
new file mode 100644
index 0000000000..c272d7f4a4
--- /dev/null
+++ b/packages/cli/src/utils/serve.js
@@ -0,0 +1,73 @@
+import { promises as fs } from 'fs'
+import { join, extname, basename } from 'path'
+import connect from 'connect'
+import serveStatic from 'serve-static'
+import compression from 'compression'
+import { getNuxtConfig } from '@nuxt/config'
+import { showBanner } from '../utils/banner'
+import * as imports from '../imports'
+
+export async function serve (cmd) {
+ const _config = await cmd.getNuxtConfig({ dev: false })
+
+ // add default options
+ const options = getNuxtConfig(_config)
+
+ try {
+ // overwrites with build config
+ const buildConfig = require(join(options.buildDir, 'nuxt/config.json'))
+ options.target = buildConfig.target
+ } catch (err) { }
+
+ const distStat = await fs.stat(options.generate.dir).catch(err => null) // eslint-disable-line handle-callback-err
+ if (!distStat || !distStat.isDirectory()) {
+ throw new Error('Output directory `' + basename(options.generate.dir) + '/` does not exists, please use `nuxt generate` before `nuxt start` for static target.')
+ }
+ const app = connect()
+ app.use(compression({ threshold: 0 }))
+ app.use(
+ options.router.base,
+ serveStatic(options.generate.dir, {
+ extensions: ['html']
+ })
+ )
+ if (options.generate.fallback) {
+ const fallbackFile = await fs.readFile(join(options.generate.dir, options.generate.fallback), 'utf-8')
+ app.use((req, res, next) => {
+ const ext = extname(req.url) || '.html'
+
+ if (ext !== '.html') {
+ return next()
+ }
+ res.writeHeader(200, {
+ 'Content-Type': 'text/html'
+ })
+ res.write(fallbackFile)
+ res.end()
+ })
+ }
+
+ const { port, host, socket, https } = options.server
+ const { Listener } = await imports.server()
+ const listener = new Listener({
+ port,
+ host,
+ socket,
+ https,
+ app,
+ dev: true, // try another port if taken
+ baseURL: options.router.base
+ })
+
+ await listener.listen()
+
+ const { Nuxt } = await imports.core()
+
+ showBanner({
+ constructor: Nuxt,
+ options,
+ server: {
+ listeners: [listener]
+ }
+ }, false)
+}
diff --git a/packages/cli/test/unit/export.test.js b/packages/cli/test/unit/export.test.js
index 5651237b9f..c75b116c7c 100644
--- a/packages/cli/test/unit/export.test.js
+++ b/packages/cli/test/unit/export.test.js
@@ -29,29 +29,29 @@ describe('export', () => {
expect(generator).toHaveBeenCalled()
expect(generator.mock.calls[0][0].init).toBe(true)
- expect(generator.mock.calls[0][0].build).toBe(false)
+ // expect(generator.mock.calls[0][0].build).toBe(false)
})
test('force-exits by default', async () => {
mockGetNuxt({ generate: { dir: 'dist' } })
mockGetGenerator()
- const cmd = NuxtCommand.from(exportCommand, ['export', '.'])
+ const cmd = NuxtCommand.from(exportCommand, ['generate', '.'])
await cmd.run()
expect(utils.forceExit).toHaveBeenCalledTimes(1)
- expect(utils.forceExit).toHaveBeenCalledWith('export', 5)
+ expect(utils.forceExit).toHaveBeenCalledWith('generate', 5)
})
test('can set force exit explicitly', async () => {
mockGetNuxt({ generate: { dir: 'dist' } })
mockGetGenerator()
- const cmd = NuxtCommand.from(exportCommand, ['export', '.', '--force-exit'])
+ const cmd = NuxtCommand.from(exportCommand, ['generate', '.', '--force-exit'])
await cmd.run()
expect(utils.forceExit).toHaveBeenCalledTimes(1)
- expect(utils.forceExit).toHaveBeenCalledWith('export', false)
+ expect(utils.forceExit).toHaveBeenCalledWith('generate', false)
})
test('can disable force exit explicitly', async () => {
@@ -97,7 +97,7 @@ describe('export', () => {
mockGetGenerator(() => ({ errors: [{ type: 'dummy' }] }))
const cmd = NuxtCommand.from(exportCommand, ['export', '.', '--fail-on-error'])
- await expect(cmd.run()).rejects.toThrow('Error exporting pages, exiting with non-zero code')
+ await expect(cmd.run()).rejects.toThrow('Error generating pages, exiting with non-zero code')
})
test('do not throw an error when fail-on-error disabled and page errors', async () => {
diff --git a/packages/cli/test/unit/serve.test.js b/packages/cli/test/unit/serve.test.js
index 21f88f6823..c229113160 100644
--- a/packages/cli/test/unit/serve.test.js
+++ b/packages/cli/test/unit/serve.test.js
@@ -19,16 +19,10 @@ describe('serve', () => {
expect(typeof serve.run).toBe('function')
})
- test('error if starts with server target', () => {
- mockGetNuxtConfig({ target: TARGETS.server })
- const cmd = NuxtCommand.from(serve)
- expect(cmd.run()).rejects.toThrow(new Error('You cannot use `nuxt serve` with server target, please use `nuxt start`'))
- })
-
test('error if dist/ does not exists', () => {
mockGetNuxtConfig({ target: TARGETS.static })
const cmd = NuxtCommand.from(serve)
- expect(cmd.run()).rejects.toThrow(new Error('Output directory `dist/` does not exists, please run `nuxt export` before `nuxt serve`.'))
+ expect(cmd.run()).rejects.toThrow(new Error('Output directory `dist/` does not exists, please use `nuxt generate` before `nuxt start` for static target.'))
})
test('no error if dist/ dir exists', async () => {
diff --git a/packages/cli/test/unit/start.test.js b/packages/cli/test/unit/start.test.js
index f3781d921e..ce09f3b58b 100644
--- a/packages/cli/test/unit/start.test.js
+++ b/packages/cli/test/unit/start.test.js
@@ -1,5 +1,4 @@
import fs from 'fs-extra'
-import { TARGETS } from '@nuxt/utils'
import * as utils from '../../src/utils/'
import { consola, mockGetNuxtStart, mockGetNuxtConfig, NuxtCommand } from '../utils'
@@ -36,13 +35,6 @@ describe('start', () => {
expect(consola.fatal).not.toHaveBeenCalled()
})
- test('error if starts with static target', () => {
- mockGetNuxtStart()
- mockGetNuxtConfig({ target: TARGETS.static })
- const cmd = NuxtCommand.from(start)
- expect(cmd.run()).rejects.toThrow(new Error('You cannot use `nuxt start` with static target, please use `nuxt export` and `nuxt serve`'))
- })
-
test('start doesnt force-exit by default', async () => {
mockGetNuxtStart()
mockGetNuxtConfig()
diff --git a/packages/config/src/config/generate.js b/packages/config/src/config/generate.js
index 5ac7fe11ce..8177238e3d 100644
--- a/packages/config/src/config/generate.js
+++ b/packages/config/src/config/generate.js
@@ -1,4 +1,3 @@
-
export default () => ({
dir: 'dist',
routes: [],
@@ -8,6 +7,12 @@ export default () => ({
subFolders: true,
fallback: '200.html',
crawler: true,
+ cache: {
+ ignore: [],
+ globbyOptions: {
+ gitignore: true
+ }
+ },
staticAssets: {
base: undefined, // Default: "/_nuxt/static:
versionBase: undefined, // Default: "_nuxt/static/{version}""
diff --git a/packages/config/src/options.js b/packages/config/src/options.js
index 0697e16138..16953da53c 100644
--- a/packages/config/src/options.js
+++ b/packages/config/src/options.js
@@ -115,9 +115,9 @@ export function getNuxtConfig (_options) {
options.router.base += '/'
}
- // Alias export to generate
- // TODO: switch to export by default for nuxt3
+ // Legacy support for export
if (options.export) {
+ consola.warn('export option is deprecated and will be removed in a future version! Please switch to generate')
options.generate = defu(options.export, options.generate)
}
exports.export = options.generate
diff --git a/packages/config/test/__snapshots__/options.test.js.snap b/packages/config/test/__snapshots__/options.test.js.snap
index 1df80864a6..5872aa6c7a 100644
--- a/packages/config/test/__snapshots__/options.test.js.snap
+++ b/packages/config/test/__snapshots__/options.test.js.snap
@@ -196,6 +196,12 @@ Object {
"server": true,
},
"generate": Object {
+ "cache": Object {
+ "globbyOptions": Object {
+ "gitignore": true,
+ },
+ "ignore": Array [],
+ },
"concurrency": 500,
"crawler": true,
"dir": "/var/nuxt/test/dist",
diff --git a/packages/config/test/config/__snapshots__/index.test.js.snap b/packages/config/test/config/__snapshots__/index.test.js.snap
index 4b231057bb..8c12ed613a 100644
--- a/packages/config/test/config/__snapshots__/index.test.js.snap
+++ b/packages/config/test/config/__snapshots__/index.test.js.snap
@@ -175,6 +175,12 @@ Object {
"server": true,
},
"generate": Object {
+ "cache": Object {
+ "globbyOptions": Object {
+ "gitignore": true,
+ },
+ "ignore": Array [],
+ },
"concurrency": 500,
"crawler": true,
"dir": "dist",
@@ -548,6 +554,12 @@ Object {
"server": true,
},
"generate": Object {
+ "cache": Object {
+ "globbyOptions": Object {
+ "gitignore": true,
+ },
+ "ignore": Array [],
+ },
"concurrency": 500,
"crawler": true,
"dir": "dist",
diff --git a/packages/core/src/nuxt.js b/packages/core/src/nuxt.js
index 1d7c791d4e..6e55a6d998 100644
--- a/packages/core/src/nuxt.js
+++ b/packages/core/src/nuxt.js
@@ -35,7 +35,17 @@ export default class Nuxt extends Hookable {
to: '_render:context',
message: '`render:routeContext(nuxt)` is deprecated, Please use `vue-renderer:ssr:context(context)`'
},
- showReady: 'webpack:done'
+ showReady: 'webpack:done',
+ // Introduced in 2.13
+ 'export:done': 'generate:done',
+ 'export:before': 'generate:before',
+ 'export:extendRoutes': 'generate:extendRoutes',
+ 'export:distRemoved': 'generate:distRemoved',
+ 'export:distCopied': 'generate:distCopied',
+ 'export:route': 'generate:route',
+ 'export:routeFailed': 'generate:routeFailed',
+ 'export:page': 'generate:page',
+ 'export:routeCreated': 'generate:routeCreated'
})
// Add Legacy aliases
diff --git a/packages/generator/src/generator.js b/packages/generator/src/generator.js
index 52f96e6942..194f54f375 100644
--- a/packages/generator/src/generator.js
+++ b/packages/generator/src/generator.js
@@ -6,16 +6,16 @@ import defu from 'defu'
import htmlMinifier from 'html-minifier'
import { parse } from 'node-html-parser'
-import { isFullStatic, flatRoutes, isString, isUrl, promisifyRoute, waitFor, TARGETS } from '@nuxt/utils'
+import { isFullStatic, flatRoutes, isString, isUrl, promisifyRoute, waitFor } from '@nuxt/utils'
export default class Generator {
constructor (nuxt, builder) {
this.nuxt = nuxt
this.options = nuxt.options
this.builder = builder
- this.isFullStatic = false
// Set variables
+ this.isFullStatic = isFullStatic(this.options)
this.staticRoutes = path.resolve(this.options.srcDir, this.options.dir.static)
this.srcBuiltPath = path.resolve(this.options.buildDir, 'dist', 'client')
this.distPath = this.options.generate.dir
@@ -23,6 +23,12 @@ export default class Generator {
this.distPath,
isUrl(this.options.build.publicPath) ? '' : this.options.build.publicPath
)
+ // Payloads for full static
+ if (this.isFullStatic) {
+ const { staticAssets } = this.options.generate
+ this.staticAssetsDir = path.resolve(this.distNuxtPath, staticAssets.dir, staticAssets.version)
+ this.staticAssetsBase = this.options.generate.staticAssets.versionBase
+ }
// Shared payload
this._payload = null
@@ -35,18 +41,10 @@ export default class Generator {
consola.debug('Initializing generator...')
await this.initiate({ build, init })
- // Payloads for full static
- if (this.isFullStatic) {
- consola.info('Full static mode activated')
- const { staticAssets } = this.options.generate
- this.staticAssetsDir = path.resolve(this.distNuxtPath, staticAssets.dir, staticAssets.version)
- this.staticAssetsBase = this.options.generate.staticAssets.versionBase
- }
-
consola.debug('Preparing routes for generate...')
const routes = await this.initRoutes()
- consola.info('Generating pages')
+ consola.info('Generating pages' + (this.isFullStatic ? ' with full static mode' : ''))
const errors = await this.generateRoutes(routes)
await this.afterGenerate()
@@ -72,23 +70,13 @@ export default class Generator {
// Start build process
await this.builder.build()
- this.isFullStatic = isFullStatic(this.options)
} else {
const hasBuilt = await fsExtra.exists(path.resolve(this.options.buildDir, 'dist', 'server', 'client.manifest.json'))
if (!hasBuilt) {
- const fullStaticArgs = isFullStatic(this.options) ? ' --target static' : ''
throw new Error(
- `No build files found in ${this.srcBuiltPath}.\nPlease run \`nuxt build${fullStaticArgs}\` before calling \`nuxt export\``
+ `No build files found in ${this.srcBuiltPath}.\nPlease run \`nuxt build\``
)
}
- const config = this.getBuildConfig()
- if (!config || (config.target !== TARGETS.static && !this.options._legacyGenerate)) {
- throw new Error(
- `In order to use \`nuxt export\`, you need to run \`nuxt build --target static\``
- )
- }
- this.isFullStatic = config.isFullStatic
- this.options.render.ssr = config.ssr
}
// Initialize dist directory
@@ -366,9 +354,15 @@ export default class Generator {
}
// Call hook to let user update the path & html
- const page = { route, path: fileName, html, exclude: false }
+ const page = {
+ route,
+ path: fileName,
+ html,
+ exclude: false,
+ errors: pageErrors
+ }
+ page.page = page // Backward compatibility for export:page hook
await this.nuxt.callHook('generate:page', page)
- await this.nuxt.callHook('export:page', { page, errors: pageErrors })
if (page.exclude) {
return false
diff --git a/packages/types/config/generate.d.ts b/packages/types/config/generate.d.ts
index f0fdfebb89..632165eb77 100644
--- a/packages/types/config/generate.d.ts
+++ b/packages/types/config/generate.d.ts
@@ -1,3 +1,5 @@
+import { GlobbyOptions } from 'globby'
+
/**
* NuxtOptionsGenerate
* Documentation: https://nuxtjs.org/api/configuration-generate
@@ -18,4 +20,8 @@ export interface NuxtOptionsGenerate {
interval?: number
routes?: NuxtOptionsGenerateRoute[] | NuxtOptionsGenerateRoutesFunction | NuxtOptionsGenerateRoutesFunctionWithCallback
subFolders?: boolean
+ cache?: false | {
+ ignore?: string[] | function,
+ globbyOptions?: GlobbyOptions
+ }
}
diff --git a/packages/vue-app/src/index.js b/packages/vue-app/src/index.js
index 5cf5d1d85e..11e0d65a7b 100644
--- a/packages/vue-app/src/index.js
+++ b/packages/vue-app/src/index.js
@@ -5,7 +5,6 @@ export const template = {
dependencies,
dir: path.join(__dirname, '..', 'template'),
files: [
- 'nuxt/config.json',
'App.js',
'client.js',
'index.js',
diff --git a/packages/vue-app/template/nuxt/config.json b/packages/vue-app/template/nuxt/config.json
deleted file mode 100644
index 4d88401d15..0000000000
--- a/packages/vue-app/template/nuxt/config.json
+++ /dev/null
@@ -1,5 +0,0 @@
-<%= JSON.stringify({
- isFullStatic: isFullStatic,
- ssr: nuxtOptions.render.ssr,
- target: nuxtOptions.target
-}, null, 2) %>
diff --git a/test/utils/setup-env.js b/test/utils/setup-env.js
new file mode 100644
index 0000000000..95dc33e23b
--- /dev/null
+++ b/test/utils/setup-env.js
@@ -0,0 +1,23 @@
+import consola from 'consola'
+import env from 'std-env'
+import exit from 'exit'
+
+const isWin = env.windows
+
+describe.win = isWin ? describe : describe.skip
+test.win = isWin ? test : test.skip
+
+describe.posix = !isWin ? describe : describe.skip
+test.posix = !isWin ? test : test.skip
+
+jest.setTimeout(60000)
+
+consola.mockTypes(() => jest.fn())
+
+function errorTrap (error) {
+ process.stderr.write('\n' + error.stack + '\n')
+ exit(1)
+}
+
+process.on('unhandledRejection', errorTrap)
+process.on('uncaughtException', errorTrap)
diff --git a/test/utils/setup.js b/test/utils/setup.js
index 04ffa50337..72ba9147c4 100644
--- a/test/utils/setup.js
+++ b/test/utils/setup.js
@@ -1,26 +1,6 @@
-import consola from 'consola'
-import chalk from 'chalk'
-import env from 'std-env'
-import exit from 'exit'
-
-const isWin = env.windows
-
-describe.win = isWin ? describe : describe.skip
-test.win = isWin ? test : test.skip
-
-describe.posix = !isWin ? describe : describe.skip
-test.posix = !isWin ? test : test.skip
+process.env.FORCE_COLOR = 0
+const chalk = require('chalk')
chalk.level = 0
-
-jest.setTimeout(60000)
-
-consola.mockTypes(() => jest.fn())
-
-function errorTrap (error) {
- process.stderr.write('\n' + error.stack + '\n')
- exit(1)
-}
-
-process.on('unhandledRejection', errorTrap)
-process.on('uncaughtException', errorTrap)
+chalk.supportsColor = false
+process.env.FORCE_COLOR = 0