mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-30 17:37:14 +00:00
Merge branch 'dev' of https://github.com/nuxt/nuxt.js into dev
This commit is contained in:
commit
9c754f8021
@ -23,12 +23,6 @@ jobs:
|
|||||||
paths:
|
paths:
|
||||||
- "node_modules"
|
- "node_modules"
|
||||||
|
|
||||||
# Build
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: |
|
|
||||||
yarn build
|
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
- run:
|
- run:
|
||||||
name: Tests
|
name: Tests
|
||||||
@ -41,5 +35,5 @@ jobs:
|
|||||||
if [ "${CIRCLE_BRANCH}" == "dev" ]; then
|
if [ "${CIRCLE_BRANCH}" == "dev" ]; then
|
||||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||||
echo "//registry.yarnpkg.com/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
echo "//registry.yarnpkg.com/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||||
npm run release-next
|
./scripts/release-next && npm publish --tag next
|
||||||
fi
|
fi
|
||||||
|
@ -8,7 +8,7 @@ module.exports = {
|
|||||||
browser: true,
|
browser: true,
|
||||||
node: true
|
node: true
|
||||||
},
|
},
|
||||||
extends: 'standard',
|
extends: ['standard', 'standard-jsx'],
|
||||||
// required to lint *.vue files
|
// required to lint *.vue files
|
||||||
plugins: [
|
plugins: [
|
||||||
'html'
|
'html'
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@ package-lock.json
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
.nuxt
|
.nuxt*
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
# Dist folder
|
# Dist folder
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "8"
|
- "8"
|
||||||
- "6"
|
- "9"
|
||||||
cache:
|
cache:
|
||||||
yarn: true
|
yarn: true
|
||||||
directories:
|
directories:
|
||||||
- node_modules
|
- node_modules
|
||||||
install:
|
install:
|
||||||
- yarn install
|
- yarn install
|
||||||
- yarn run build
|
|
||||||
script:
|
script:
|
||||||
- yarn run test
|
- yarn run test
|
||||||
after_success:
|
after_success:
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# Test against the latest version of this Node.js version
|
# Test against the latest version of this Node.js version
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "6"
|
|
||||||
- nodejs_version: "8"
|
- nodejs_version: "8"
|
||||||
|
- nodejs_version: "9"
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
- "%LOCALAPPDATA%\\Yarn"
|
- "%LOCALAPPDATA%\\Yarn"
|
||||||
|
@ -33,7 +33,6 @@ if (argv.help) {
|
|||||||
Usage
|
Usage
|
||||||
$ nuxt generate <dir>
|
$ nuxt generate <dir>
|
||||||
Options
|
Options
|
||||||
--spa Launch in SPA mode
|
|
||||||
--spa Launch in SPA mode
|
--spa Launch in SPA mode
|
||||||
--universal Launch in Universal mode (default)
|
--universal Launch in Universal mode (default)
|
||||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
// Some parts brought from https://github.com/vuejs/vue/blob/dev/build/config.js
|
|
||||||
const { resolve } = require('path')
|
|
||||||
const rollupBabel = require('rollup-plugin-babel')
|
|
||||||
const rollupAlias = require('rollup-plugin-alias')
|
|
||||||
const rollupCommonJS = require('rollup-plugin-commonjs')
|
|
||||||
const rollupReplace = require('rollup-plugin-replace')
|
|
||||||
const rollupNodeResolve = require('rollup-plugin-node-resolve')
|
|
||||||
const packageJson = require('../package.json')
|
|
||||||
|
|
||||||
const dependencies = Object.keys(packageJson.dependencies)
|
|
||||||
const version = packageJson.version || process.env.VERSION
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
// Banner
|
|
||||||
// -----------------------------
|
|
||||||
const banner =
|
|
||||||
'/*!\n' +
|
|
||||||
' * Nuxt.js v' + version + '\n' +
|
|
||||||
' * Released under the MIT License.\n' +
|
|
||||||
' */'
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
// Aliases
|
|
||||||
// -----------------------------
|
|
||||||
const rootDir = resolve(__dirname, '..')
|
|
||||||
const libDir = resolve(rootDir, 'lib')
|
|
||||||
const distDir = resolve(rootDir, 'dist')
|
|
||||||
|
|
||||||
const aliases = {
|
|
||||||
core: resolve(libDir, 'core/index.js'),
|
|
||||||
builder: resolve(libDir, 'builder/index.js'),
|
|
||||||
common: resolve(libDir, 'common/index.js'),
|
|
||||||
utils: resolve(libDir, 'common/utils.js'),
|
|
||||||
app: resolve(libDir, 'app')
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
// Builds
|
|
||||||
// -----------------------------
|
|
||||||
const builds = {
|
|
||||||
nuxt: {
|
|
||||||
entry: resolve(libDir, 'index.js'),
|
|
||||||
file: resolve(distDir, 'nuxt.js')
|
|
||||||
},
|
|
||||||
core: {
|
|
||||||
entry: resolve(libDir, 'core/index.js'),
|
|
||||||
file: resolve(distDir, 'core.js')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
// Default config
|
|
||||||
// -----------------------------
|
|
||||||
function genConfig(opts) {
|
|
||||||
const config = {
|
|
||||||
input: opts.entry,
|
|
||||||
output: {
|
|
||||||
file: opts.file,
|
|
||||||
format: 'cjs',
|
|
||||||
sourcemap: true
|
|
||||||
},
|
|
||||||
external: ['fs', 'path', 'http', 'module', 'vue-server-renderer/server-plugin', 'vue-server-renderer/client-plugin']
|
|
||||||
.concat(dependencies, opts.external),
|
|
||||||
banner: opts.banner || banner,
|
|
||||||
name: opts.modulename || 'Nuxt',
|
|
||||||
plugins: [
|
|
||||||
rollupAlias(Object.assign({
|
|
||||||
resolve: ['.js', '.json', '.jsx', '.ts']
|
|
||||||
}, aliases, opts.alias)),
|
|
||||||
|
|
||||||
rollupNodeResolve({ preferBuiltins: true }),
|
|
||||||
|
|
||||||
rollupCommonJS(),
|
|
||||||
|
|
||||||
rollupBabel(Object.assign({
|
|
||||||
exclude: 'node_modules/**',
|
|
||||||
plugins: [
|
|
||||||
['transform-runtime', { 'helpers': false, 'polyfill': false }],
|
|
||||||
'transform-async-to-generator',
|
|
||||||
'array-includes',
|
|
||||||
'external-helpers'
|
|
||||||
],
|
|
||||||
presets: [
|
|
||||||
['env', {
|
|
||||||
targets: {
|
|
||||||
node: '6.11.0'
|
|
||||||
},
|
|
||||||
modules: false
|
|
||||||
}]
|
|
||||||
],
|
|
||||||
'env': {
|
|
||||||
'test': {
|
|
||||||
'plugins': [ 'istanbul' ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, opts.babel)),
|
|
||||||
|
|
||||||
rollupReplace({ __VERSION__: version })
|
|
||||||
].concat(opts.plugins || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.env) {
|
|
||||||
config.plugins.push(rollupReplace({
|
|
||||||
'process.env.NODE_ENV': JSON.stringify(opts.env)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.TARGET) {
|
|
||||||
module.exports = genConfig(builds[process.env.TARGET])
|
|
||||||
} else {
|
|
||||||
exports.getBuild = name => genConfig(builds[name])
|
|
||||||
exports.getAllBuilds = () => Object.keys(builds).map(name => genConfig(builds[name]))
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
<script>
|
|
||||||
export default {
|
|
||||||
asyncData({ req }) {
|
|
||||||
return {
|
|
||||||
name: req ? 'server' : 'client'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render(h) {
|
|
||||||
return <div>
|
|
||||||
<p>Hi from {this.name}</p>
|
|
||||||
<nuxt-link to="/">Home page</nuxt-link>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,8 +0,0 @@
|
|||||||
export default {
|
|
||||||
render(h) {
|
|
||||||
return <div>
|
|
||||||
<h1>Welcome !</h1>
|
|
||||||
<nuxt-link to="/about">About page</nuxt-link>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,10 +4,10 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="Header__Title">Nuxt i18n</h1>
|
<h1 class="Header__Title">Nuxt i18n</h1>
|
||||||
<nav class="Header__Menu">
|
<nav class="Header__Menu">
|
||||||
<nuxt-link class="Header__Link" :to="path('/')" exact>
|
<nuxt-link class="Header__Link" :to="$i18n.path('')" exact>
|
||||||
{{ $t('links.home') }}
|
{{ $t('links.home') }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link class="Header__Link" :to="path('/about')" exact>
|
<nuxt-link class="Header__Link" :to="$i18n.path('about')" exact>
|
||||||
{{ $t('links.about') }}
|
{{ $t('links.about') }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link class="Header__Link" v-if="$i18n.locale === 'en'" :to="`/fr` + $route.fullPath" active-class="none" exact>
|
<nuxt-link class="Header__Link" v-if="$i18n.locale === 'en'" :to="`/fr` + $route.fullPath" active-class="none" exact>
|
||||||
@ -24,13 +24,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {}
|
||||||
methods: {
|
|
||||||
path(url) {
|
|
||||||
return (this.$i18n.locale === 'en' ? url : '/' + this.$i18n.locale + url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -14,4 +14,12 @@ export default ({ app, store }) => {
|
|||||||
'fr': require('~/locales/fr.json')
|
'fr': require('~/locales/fr.json')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.i18n.path = (link) => {
|
||||||
|
if (app.i18n.locale === app.i18n.fallbackLocale) {
|
||||||
|
return `/${link}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `/${app.i18n.locale}/${link}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
5
examples/jsx/README.md
Normal file
5
examples/jsx/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Render Functions & JSX Example
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Vue: https://vuejs.org/v2/guide/render-function.html
|
17
examples/jsx/components/test.vue
Normal file
17
examples/jsx/components/test.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<p v-html="data"></p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
data: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
p {
|
||||||
|
padding: 5px 20px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "hello-nuxt-jsx",
|
"name": "nuxt-jsx",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nuxt": "latest"
|
"nuxt": "latest"
|
||||||
},
|
},
|
21
examples/jsx/pages/about.js
Normal file
21
examples/jsx/pages/about.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
import Test from '~/components/test.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
head: {
|
||||||
|
title: 'About Page',
|
||||||
|
meta: [
|
||||||
|
{ hid: 'description', name: 'description', content: 'About page description' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Test
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return <div class='container'>
|
||||||
|
<h1>About page</h1>
|
||||||
|
<test data='I am test component' />
|
||||||
|
<p><nuxt-link to='/'>Home page</nuxt-link></p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
20
examples/jsx/pages/index.js
Executable file
20
examples/jsx/pages/index.js
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
export default {
|
||||||
|
head: {
|
||||||
|
title: 'Home page 🚀',
|
||||||
|
meta: [
|
||||||
|
{ hid: 'description', name: 'description', content: 'Home page description' }
|
||||||
|
],
|
||||||
|
script: [
|
||||||
|
{ src: '/head.js' },
|
||||||
|
// Supported since 1.0
|
||||||
|
{ src: '/body.js', body: true },
|
||||||
|
{ src: '/defer.js', defer: '' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return <div class='container'>
|
||||||
|
<h1>Home page 🚀</h1>
|
||||||
|
<nuxt-link to='/about'>About page</nuxt-link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
7
examples/with-vue-material/README.md
Normal file
7
examples/with-vue-material/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Nuxt With Vue-Material
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
Vue-Material >= 1.0.0beta
|
||||||
|
|
||||||
|
[View Demo](https://nuxt-vue-material.now.sh)
|
25
examples/with-vue-material/nuxt.config.js
Normal file
25
examples/with-vue-material/nuxt.config.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
module.exports = {
|
||||||
|
head: {
|
||||||
|
meta: [
|
||||||
|
{
|
||||||
|
name: 'viewport',
|
||||||
|
content: 'width=device-width, initial-scale=1, minimal-ui'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
link: [
|
||||||
|
{
|
||||||
|
rel: 'stylesheet',
|
||||||
|
href: 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic|Material+Icons'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: 'stylesheet',
|
||||||
|
href: 'https://unpkg.com/vue-material@beta/dist/vue-material.min.css'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: 'stylesheet',
|
||||||
|
href: 'https://unpkg.com/vue-material@beta/dist/theme/default.css'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: ['~/plugins/vue-material']
|
||||||
|
}
|
14
examples/with-vue-material/package.json
Normal file
14
examples/with-vue-material/package.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "with-vue-material",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"nuxt": "latest",
|
||||||
|
"vue": "~2.4.4",
|
||||||
|
"vue-material": "beta"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nuxt",
|
||||||
|
"build": "nuxt build",
|
||||||
|
"start": "nuxt start"
|
||||||
|
}
|
||||||
|
}
|
106
examples/with-vue-material/pages/index.vue
Normal file
106
examples/with-vue-material/pages/index.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-container md-layout-column">
|
||||||
|
<md-toolbar class="md-primary">
|
||||||
|
<md-button class="md-icon-button" @click="showNavigation = true">
|
||||||
|
<md-icon>menu</md-icon>
|
||||||
|
</md-button>
|
||||||
|
<span class="md-title">Nuxt + Vue Material</span>
|
||||||
|
|
||||||
|
<div class="md-toolbar-section-end">
|
||||||
|
<md-button @click="showSidepanel = true">Favorites</md-button>
|
||||||
|
</div>
|
||||||
|
</md-toolbar>
|
||||||
|
|
||||||
|
<md-drawer :md-active.sync="showNavigation">
|
||||||
|
<md-toolbar class="md-transparent" md-elevation="0">
|
||||||
|
<span class="md-title">My App name</span>
|
||||||
|
</md-toolbar>
|
||||||
|
|
||||||
|
<md-list>
|
||||||
|
<md-list-item>
|
||||||
|
<md-icon>move_to_inbox</md-icon>
|
||||||
|
<span class="md-list-item-text">Inbox</span>
|
||||||
|
</md-list-item>
|
||||||
|
|
||||||
|
<md-list-item>
|
||||||
|
<md-icon>send</md-icon>
|
||||||
|
<span class="md-list-item-text">Sent Mail</span>
|
||||||
|
</md-list-item>
|
||||||
|
|
||||||
|
<md-list-item>
|
||||||
|
<md-icon>delete</md-icon>
|
||||||
|
<span class="md-list-item-text">Trash</span>
|
||||||
|
</md-list-item>
|
||||||
|
|
||||||
|
<md-list-item>
|
||||||
|
<md-icon>error</md-icon>
|
||||||
|
<span class="md-list-item-text">Spam</span>
|
||||||
|
</md-list-item>
|
||||||
|
</md-list>
|
||||||
|
</md-drawer>
|
||||||
|
|
||||||
|
<md-drawer class="md-right" :md-active.sync="showSidepanel">
|
||||||
|
<md-toolbar class="md-transparent" md-elevation="0">
|
||||||
|
<span class="md-title">Favorites</span>
|
||||||
|
</md-toolbar>
|
||||||
|
|
||||||
|
<md-list>
|
||||||
|
<md-list-item>
|
||||||
|
<span class="md-list-item-text">Abbey Christansen</span>
|
||||||
|
|
||||||
|
<md-button class="md-icon-button md-list-action">
|
||||||
|
<md-icon class="md-primary">chat_bubble</md-icon>
|
||||||
|
</md-button>
|
||||||
|
</md-list-item>
|
||||||
|
|
||||||
|
<md-list-item>
|
||||||
|
<span class="md-list-item-text">Alex Nelson</span>
|
||||||
|
|
||||||
|
<md-button class="md-icon-button md-list-action">
|
||||||
|
<md-icon class="md-primary">chat_bubble</md-icon>
|
||||||
|
</md-button>
|
||||||
|
</md-list-item>
|
||||||
|
|
||||||
|
<md-list-item>
|
||||||
|
<span class="md-list-item-text">Mary Johnson</span>
|
||||||
|
|
||||||
|
<md-button class="md-icon-button md-list-action">
|
||||||
|
<md-icon>chat_bubble</md-icon>
|
||||||
|
</md-button>
|
||||||
|
</md-list-item>
|
||||||
|
</md-list>
|
||||||
|
</md-drawer>
|
||||||
|
|
||||||
|
<md-content>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.
|
||||||
|
</md-content>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Sidenav',
|
||||||
|
data: () => ({
|
||||||
|
showNavigation: false,
|
||||||
|
showSidepanel: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid rgba(#000, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-drawer {
|
||||||
|
width: 230px;
|
||||||
|
max-width: calc(100vw - 125px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-content {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
4
examples/with-vue-material/plugins/vue-material.js
Normal file
4
examples/with-vue-material/plugins/vue-material.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import VueMaterial from 'vue-material'
|
||||||
|
|
||||||
|
Vue.use(VueMaterial)
|
16
index.js
16
index.js
@ -1,16 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Nuxt.js
|
|
||||||
* (c) 2016-2017 Chopin Brothers
|
|
||||||
* Core maintainer: Pooya (@pi0)
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Node Source Map Support
|
|
||||||
// https://github.com/evanw/node-source-map-support
|
|
||||||
require('source-map-support').install()
|
|
||||||
|
|
||||||
// Fix babel flag
|
|
||||||
/* istanbul ignore else */
|
|
||||||
process.noDeprecation = true
|
|
||||||
|
|
||||||
module.exports = require('./dist/nuxt')
|
|
@ -1,6 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import NuxtChild from './nuxt-child'
|
import NuxtChild from './nuxt-child'
|
||||||
import NuxtError from '<%= components.ErrorPage ? ((components.ErrorPage.includes('~') || components.ErrorPage.includes('@')) ? components.ErrorPage : "../" + components.ErrorPage) : "./nuxt-error.vue" %>'
|
import NuxtError from '<%= components.ErrorPage ? ((components.ErrorPage.indexOf('~') === 0 || components.ErrorPage.indexOf('@') === 0) ? components.ErrorPage : "../" + components.ErrorPage) : "./nuxt-error.vue" %>'
|
||||||
import { compile } from '../utils'
|
import { compile } from '../utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -8,13 +8,12 @@ import NuxtLink from './components/nuxt-link.js'
|
|||||||
import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>'
|
import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>'
|
||||||
import Nuxt from './components/nuxt.js'
|
import Nuxt from './components/nuxt.js'
|
||||||
import App from '<%= appPath %>'
|
import App from '<%= appPath %>'
|
||||||
import { setContext, getLocation } from './utils'
|
import { setContext, getLocation, getRouteData } from './utils'
|
||||||
<% if (store) { %>import { createStore } from './store.js'<% } %>
|
<% if (store) { %>import { createStore } from './store.js'<% } %>
|
||||||
|
|
||||||
/* Plugins */
|
/* Plugins */
|
||||||
|
<% plugins.forEach(plugin => { %>import <%= plugin.name %> from '<%= plugin.name %>' // Source: <%= relativeToBuild(plugin.src) %><%= (plugin.ssr===false) ? ' (ssr: false)' : '' %>
|
||||||
<% plugins.forEach(plugin => { %>// <%= plugin.src %><%= (plugin.ssr===false) ? ' (Only included in client bundle)' : '' %>
|
<% }) %>
|
||||||
import <%= plugin.name %> from '<%= plugin.name %>'<% }) %>
|
|
||||||
|
|
||||||
// Component: <no-ssr>
|
// Component: <no-ssr>
|
||||||
Vue.component(NoSSR.name, NoSSR)
|
Vue.component(NoSSR.name, NoSSR)
|
||||||
@ -167,7 +166,17 @@ async function createApp (ssrContext) {
|
|||||||
// If server-side, wait for async component to be resolved first
|
// If server-side, wait for async component to be resolved first
|
||||||
if (process.server && ssrContext && ssrContext.url) {
|
if (process.server && ssrContext && ssrContext.url) {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
router.push(ssrContext.url, resolve, reject)
|
router.push(ssrContext.url, resolve, () => {
|
||||||
|
// navigated to a different route in router guard
|
||||||
|
const unregister = router.afterEach(async (to, from, next) => {
|
||||||
|
ssrContext.url = to.fullPath
|
||||||
|
app.context.route = await getRouteData(to)
|
||||||
|
app.context.params = to.params || {}
|
||||||
|
app.context.query = to.query || {}
|
||||||
|
unregister()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ export function resolveRouteComponents(route) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRouteData(route) {
|
export async function getRouteData(route) {
|
||||||
// Make sure the components are resolved (code-splitting)
|
// Make sure the components are resolved (code-splitting)
|
||||||
await resolveRouteComponents(route)
|
await resolveRouteComponents(route)
|
||||||
// Send back a copy of route with meta based on Component definition
|
// Send back a copy of route with meta based on Component definition
|
||||||
@ -127,11 +127,16 @@ export async function setContext(app, context) {
|
|||||||
if (!status) return
|
if (!status) return
|
||||||
app.context._redirected = true // Used in middleware
|
app.context._redirected = true // Used in middleware
|
||||||
// if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' })
|
// if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' })
|
||||||
if (typeof status === 'string' && (typeof path === 'undefined' || typeof path === 'object')) {
|
let pathType = typeof path
|
||||||
|
if (typeof status !== 'number' && (pathType === 'undefined' || pathType === 'object')) {
|
||||||
query = path || {}
|
query = path || {}
|
||||||
path = status
|
path = status
|
||||||
|
pathType = typeof path
|
||||||
status = 302
|
status = 302
|
||||||
}
|
}
|
||||||
|
if (pathType === 'object') {
|
||||||
|
path = app.router.resolve(path).href
|
||||||
|
}
|
||||||
// "/absolute/route", "./relative/route" or "../relative/route"
|
// "/absolute/route", "./relative/route" or "../relative/route"
|
||||||
if (/(^[.]{1,2}\/)|(^\/(?!\/))/.test(path)) {
|
if (/(^[.]{1,2}\/)|(^\/(?!\/))/.test(path)) {
|
||||||
app.context.next({
|
app.context.next({
|
||||||
|
@ -1,29 +1,30 @@
|
|||||||
import _ from 'lodash'
|
const { promisify } = require('util')
|
||||||
import chokidar from 'chokidar'
|
const _ = require('lodash')
|
||||||
import fs, { remove, readFile, writeFile, mkdirp, existsSync } from 'fs-extra'
|
const chokidar = require('chokidar')
|
||||||
import hash from 'hash-sum'
|
const { remove, readFile, writeFile, mkdirp, existsSync } = require('fs-extra')
|
||||||
import pify from 'pify'
|
const hash = require('hash-sum')
|
||||||
import webpack from 'webpack'
|
const webpack = require('webpack')
|
||||||
import serialize from 'serialize-javascript'
|
const serialize = require('serialize-javascript')
|
||||||
import { join, resolve, basename, extname, dirname } from 'path'
|
const { join, resolve, basename, extname, dirname } = require('path')
|
||||||
import MFS from 'memory-fs'
|
const MFS = require('memory-fs')
|
||||||
import webpackDevMiddleware from 'webpack-dev-middleware'
|
const webpackDevMiddleware = require('webpack-dev-middleware')
|
||||||
import webpackHotMiddleware from 'webpack-hot-middleware'
|
const webpackHotMiddleware = require('webpack-hot-middleware')
|
||||||
import { r, wp, wChunk, createRoutes, sequence, relativeTo, isPureObject, waitFor } from 'utils'
|
const { r, wp, wChunk, createRoutes, sequence, relativeTo, isPureObject, waitFor, rmCache } = require('../common/utils')
|
||||||
import Debug from 'debug'
|
const Debug = require('debug')
|
||||||
import Glob from 'glob'
|
const Glob = require('glob')
|
||||||
import clientWebpackConfig from './webpack/client.config.js'
|
const clientWebpackConfig = require('./webpack/client.config.js')
|
||||||
import serverWebpackConfig from './webpack/server.config.js'
|
const serverWebpackConfig = require('./webpack/server.config.js')
|
||||||
import dllWebpackConfig from './webpack/dll.config.js'
|
const dllWebpackConfig = require('./webpack/dll.config.js')
|
||||||
import vueLoaderConfig from './webpack/vue-loader.config'
|
const vueLoaderConfig = require('./webpack/vue-loader.config')
|
||||||
import styleLoader from './webpack/style-loader'
|
const styleLoader = require('./webpack/style-loader')
|
||||||
|
const { Options } = require('../common')
|
||||||
|
|
||||||
const debug = Debug('nuxt:build')
|
const debug = Debug('nuxt:build')
|
||||||
debug.color = 2 // Force green color
|
debug.color = 2 // Force green color
|
||||||
|
|
||||||
const glob = pify(Glob)
|
const glob = promisify(Glob)
|
||||||
|
|
||||||
export default class Builder {
|
module.exports = class Builder {
|
||||||
constructor(nuxt) {
|
constructor(nuxt) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.isStatic = false // Flag to know if the build is for a generated app
|
this.isStatic = false // Flag to know if the build is for a generated app
|
||||||
@ -38,17 +39,7 @@ export default class Builder {
|
|||||||
this.customFilesWatcher = null
|
this.customFilesWatcher = null
|
||||||
|
|
||||||
// Mute stats on dev
|
// Mute stats on dev
|
||||||
this.webpackStats = this.options.dev ? false : {
|
this.webpackStats = this.options.dev ? false : this.options.build.stats
|
||||||
chunks: false,
|
|
||||||
children: false,
|
|
||||||
modules: false,
|
|
||||||
colors: true,
|
|
||||||
excludeAssets: [
|
|
||||||
/.map$/,
|
|
||||||
/index\..+\.html$/,
|
|
||||||
/vue-ssr-client-manifest.json/
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to resolve build paths
|
// Helper to resolve build paths
|
||||||
this.relativeToBuild = (...args) => relativeTo(this.options.buildDir, ...args)
|
this.relativeToBuild = (...args) => relativeTo(this.options.buildDir, ...args)
|
||||||
@ -62,18 +53,21 @@ export default class Builder {
|
|||||||
// Stop watching on nuxt.close()
|
// Stop watching on nuxt.close()
|
||||||
if (this.options.dev) {
|
if (this.options.dev) {
|
||||||
this.nuxt.hook('close', () => this.unwatch())
|
this.nuxt.hook('close', () => this.unwatch())
|
||||||
|
} else {
|
||||||
|
this.nuxt.hook('build:done', () => this.generateConfig())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get plugins() {
|
get plugins() {
|
||||||
return this.options.plugins.map((p, i) => {
|
return _.uniqBy(this.options.plugins.map((p, i) => {
|
||||||
if (typeof p === 'string') p = { src: p }
|
if (typeof p === 'string') p = { src: p }
|
||||||
|
const pluginBaseName = basename(p.src, extname(p.src)).replace(/[^a-zA-Z?\d\s:]/g, '')
|
||||||
return {
|
return {
|
||||||
src: this.nuxt.resolvePath(p.src),
|
src: this.nuxt.resolvePath(p.src),
|
||||||
ssr: (p.ssr !== false),
|
ssr: (p.ssr !== false),
|
||||||
name: basename(p.src, extname(p.src)).replace(/[^a-zA-Z?\d\s:]/g, '') + '_plugin_' + hash(p.src)
|
name: 'nuxt_plugin_' + pluginBaseName + '_' + hash(p.src)
|
||||||
}
|
}
|
||||||
})
|
}), p => p.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor() {
|
vendor() {
|
||||||
@ -124,19 +118,6 @@ export default class Builder {
|
|||||||
// Call before hook
|
// Call before hook
|
||||||
await this.nuxt.callHook('build:before', this, this.options.build)
|
await this.nuxt.callHook('build:before', this, this.options.build)
|
||||||
|
|
||||||
// Babel options
|
|
||||||
this.babelOptions = _.defaults(this.options.build.babel, {
|
|
||||||
babelrc: false,
|
|
||||||
cacheDirectory: !!this.options.dev
|
|
||||||
})
|
|
||||||
if (!this.babelOptions.babelrc && !this.babelOptions.presets) {
|
|
||||||
this.babelOptions.presets = [
|
|
||||||
[require.resolve('babel-preset-vue-app'), {
|
|
||||||
targets: { ie: 9, uglify: true }
|
|
||||||
}]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map postcss plugins into instances on object mode once
|
// Map postcss plugins into instances on object mode once
|
||||||
if (isPureObject(this.options.build.postcss)) {
|
if (isPureObject(this.options.build.postcss)) {
|
||||||
if (isPureObject(this.options.build.postcss.plugins)) {
|
if (isPureObject(this.options.build.postcss.plugins)) {
|
||||||
@ -154,9 +135,9 @@ export default class Builder {
|
|||||||
// Check if pages dir exists and warn if not
|
// Check if pages dir exists and warn if not
|
||||||
this._nuxtPages = typeof this.options.build.createRoutes !== 'function'
|
this._nuxtPages = typeof this.options.build.createRoutes !== 'function'
|
||||||
if (this._nuxtPages) {
|
if (this._nuxtPages) {
|
||||||
if (!fs.existsSync(join(this.options.srcDir, 'pages'))) {
|
if (!existsSync(join(this.options.srcDir, 'pages'))) {
|
||||||
let dir = this.options.srcDir
|
let dir = this.options.srcDir
|
||||||
if (fs.existsSync(join(this.options.srcDir, '..', 'pages'))) {
|
if (existsSync(join(this.options.srcDir, '..', 'pages'))) {
|
||||||
throw new Error(`No \`pages\` directory found in ${dir}. Did you mean to run \`nuxt\` in the parent (\`../\`) directory?`)
|
throw new Error(`No \`pages\` directory found in ${dir}. Did you mean to run \`nuxt\` in the parent (\`../\`) directory?`)
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Couldn't find a \`pages\` directory in ${dir}. Please create one under the project root`)
|
throw new Error(`Couldn't find a \`pages\` directory in ${dir}. Please create one under the project root`)
|
||||||
@ -189,6 +170,42 @@ export default class Builder {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBabelOptions({ isServer }) {
|
||||||
|
const options = _.defaults({}, {
|
||||||
|
babelrc: false,
|
||||||
|
cacheDirectory: !!this.options.dev
|
||||||
|
}, this.options.build.babel)
|
||||||
|
|
||||||
|
if (typeof options.presets === 'function') {
|
||||||
|
options.presets = options.presets({ isServer })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.babelrc && !options.presets) {
|
||||||
|
options.presets = [
|
||||||
|
[
|
||||||
|
require.resolve('babel-preset-vue-app'),
|
||||||
|
{
|
||||||
|
targets: isServer ? { node: '8.0.0' } : { ie: 9, uglify: true }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
getFileName(name) {
|
||||||
|
let fileName = this.options.build.filenames[name]
|
||||||
|
|
||||||
|
// Don't use hashes when watching
|
||||||
|
// https://github.com/webpack/webpack/issues/1914#issuecomment-174171709
|
||||||
|
if (this.options.dev) {
|
||||||
|
fileName = fileName.replace(/\[(chunkhash|contenthash|hash)\]\./g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName
|
||||||
|
}
|
||||||
|
|
||||||
async generateRoutesAndFiles() {
|
async generateRoutesAndFiles() {
|
||||||
debug('Generating files...')
|
debug('Generating files...')
|
||||||
// -- Templates --
|
// -- Templates --
|
||||||
@ -220,7 +237,7 @@ export default class Builder {
|
|||||||
router: this.options.router,
|
router: this.options.router,
|
||||||
env: this.options.env,
|
env: this.options.env,
|
||||||
head: this.options.head,
|
head: this.options.head,
|
||||||
middleware: fs.existsSync(join(this.options.srcDir, 'middleware')),
|
middleware: existsSync(join(this.options.srcDir, 'middleware')),
|
||||||
store: this.options.store,
|
store: this.options.store,
|
||||||
css: this.options.css,
|
css: this.options.css,
|
||||||
plugins: this.plugins,
|
plugins: this.plugins,
|
||||||
@ -235,16 +252,18 @@ export default class Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -- Layouts --
|
// -- Layouts --
|
||||||
if (fs.existsSync(resolve(this.options.srcDir, 'layouts'))) {
|
if (existsSync(resolve(this.options.srcDir, 'layouts'))) {
|
||||||
const layoutsFiles = await glob('layouts/**/*.vue', { cwd: this.options.srcDir })
|
const layoutsFiles = await glob('layouts/**/*.{vue,js}', { cwd: this.options.srcDir })
|
||||||
let hasErrorLayout = false
|
let hasErrorLayout = false
|
||||||
layoutsFiles.forEach((file) => {
|
layoutsFiles.forEach((file) => {
|
||||||
let name = file.split('/').slice(1).join('/').replace(/\.vue$/, '')
|
let name = file.split('/').slice(1).join('/').replace(/\.(vue|js)$/, '')
|
||||||
if (name === 'error') {
|
if (name === 'error') {
|
||||||
hasErrorLayout = true
|
hasErrorLayout = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!templateVars.layouts[name] || /\.vue$/.test(file)) {
|
||||||
templateVars.layouts[name] = this.relativeToBuild(this.options.srcDir, file)
|
templateVars.layouts[name] = this.relativeToBuild(this.options.srcDir, file)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (!templateVars.components.ErrorPage && hasErrorLayout) {
|
if (!templateVars.components.ErrorPage && hasErrorLayout) {
|
||||||
templateVars.components.ErrorPage = this.relativeToBuild(this.options.srcDir, 'layouts/error.vue')
|
templateVars.components.ErrorPage = this.relativeToBuild(this.options.srcDir, 'layouts/error.vue')
|
||||||
@ -262,8 +281,14 @@ export default class Builder {
|
|||||||
// If user defined a custom method to create routes
|
// If user defined a custom method to create routes
|
||||||
if (this._nuxtPages) {
|
if (this._nuxtPages) {
|
||||||
// Use nuxt.js createRoutes bases on pages/
|
// Use nuxt.js createRoutes bases on pages/
|
||||||
const files = await glob('pages/**/*.vue', { cwd: this.options.srcDir })
|
const files = {};
|
||||||
templateVars.router.routes = createRoutes(files, this.options.srcDir)
|
(await glob('pages/**/*.{vue,js}', { cwd: this.options.srcDir })).forEach(f => {
|
||||||
|
const key = f.replace(/\.(js|vue)$/, '')
|
||||||
|
if (/\.vue$/.test(f) || !files[key]) {
|
||||||
|
files[key] = f
|
||||||
|
}
|
||||||
|
})
|
||||||
|
templateVars.router.routes = createRoutes(Object.values(files), this.options.srcDir)
|
||||||
} else {
|
} else {
|
||||||
templateVars.router.routes = this.options.build.createRoutes(this.options.srcDir)
|
templateVars.router.routes = this.options.build.createRoutes(this.options.srcDir)
|
||||||
}
|
}
|
||||||
@ -299,7 +324,7 @@ export default class Builder {
|
|||||||
}
|
}
|
||||||
// Allow override templates using a file with same name in ${srcDir}/app
|
// Allow override templates using a file with same name in ${srcDir}/app
|
||||||
const customPath = r(this.options.srcDir, 'app', file)
|
const customPath = r(this.options.srcDir, 'app', file)
|
||||||
const customFileExists = fs.existsSync(customPath)
|
const customFileExists = existsSync(customPath)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
src: customFileExists
|
src: customFileExists
|
||||||
@ -436,7 +461,7 @@ export default class Builder {
|
|||||||
compiler.plugin('done', async (stats) => {
|
compiler.plugin('done', async (stats) => {
|
||||||
await this.nuxt.callHook('build:compiled', { name, compiler, stats })
|
await this.nuxt.callHook('build:compiled', { name, compiler, stats })
|
||||||
// Reload renderer if available
|
// Reload renderer if available
|
||||||
this.nuxt.renderer.loadResources(sharedFS || fs)
|
this.nuxt.renderer.loadResources(sharedFS || require('fs'))
|
||||||
// Resolve on next tick
|
// Resolve on next tick
|
||||||
process.nextTick(resolve)
|
process.nextTick(resolve)
|
||||||
})
|
})
|
||||||
@ -460,8 +485,11 @@ export default class Builder {
|
|||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
// not keep modified or deleted items in Vue.prototype
|
// not keep modified or deleted items in Vue.prototype
|
||||||
delete require.cache[require.resolve('vue')]
|
Object.keys(require.cache).forEach(key => {
|
||||||
delete require.cache[require.resolve('vue-router')]
|
if (!/(node_modules\/postcss)|(\.node$)/.test(key)) {
|
||||||
|
rmCache(key)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@ -489,17 +517,16 @@ export default class Builder {
|
|||||||
debug('Adding webpack middleware...')
|
debug('Adding webpack middleware...')
|
||||||
|
|
||||||
// Create webpack dev middleware
|
// Create webpack dev middleware
|
||||||
this.webpackDevMiddleware = pify(webpackDevMiddleware(compiler, Object.assign({
|
this.webpackDevMiddleware = promisify(webpackDevMiddleware(compiler, Object.assign({
|
||||||
publicPath: this.options.build.publicPath,
|
publicPath: this.options.build.publicPath,
|
||||||
stats: this.webpackStats,
|
stats: this.webpackStats,
|
||||||
noInfo: true,
|
logLevel: 'silent',
|
||||||
quiet: true,
|
|
||||||
watchOptions: this.options.watchers.webpack
|
watchOptions: this.options.watchers.webpack
|
||||||
}, this.options.build.devMiddleware)))
|
}, this.options.build.devMiddleware)))
|
||||||
|
|
||||||
this.webpackDevMiddleware.close = pify(this.webpackDevMiddleware.close)
|
this.webpackDevMiddleware.close = promisify(this.webpackDevMiddleware.close)
|
||||||
|
|
||||||
this.webpackHotMiddleware = pify(webpackHotMiddleware(compiler, Object.assign({
|
this.webpackHotMiddleware = promisify(webpackHotMiddleware(compiler, Object.assign({
|
||||||
log: false,
|
log: false,
|
||||||
heartbeat: 10000
|
heartbeat: 10000
|
||||||
}, this.options.build.hotMiddleware)))
|
}, this.options.build.hotMiddleware)))
|
||||||
@ -520,14 +547,14 @@ export default class Builder {
|
|||||||
r(src, 'layouts'),
|
r(src, 'layouts'),
|
||||||
r(src, 'store'),
|
r(src, 'store'),
|
||||||
r(src, 'middleware'),
|
r(src, 'middleware'),
|
||||||
r(src, 'layouts/*.vue'),
|
r(src, 'layouts/*.{vue,js}'),
|
||||||
r(src, 'layouts/**/*.vue')
|
r(src, 'layouts/**/*.{vue,js}')
|
||||||
]
|
]
|
||||||
if (this._nuxtPages) {
|
if (this._nuxtPages) {
|
||||||
patterns.push(
|
patterns.push(
|
||||||
r(src, 'pages'),
|
r(src, 'pages'),
|
||||||
r(src, 'pages/*.vue'),
|
r(src, 'pages/*.{vue,js}'),
|
||||||
r(src, 'pages/**/*.vue')
|
r(src, 'pages/**/*.{vue,js}')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const options = Object.assign({}, this.options.watchers.chokidar, {
|
const options = Object.assign({}, this.options.watchers.chokidar, {
|
||||||
@ -560,6 +587,12 @@ export default class Builder {
|
|||||||
// Stop webpack middleware
|
// Stop webpack middleware
|
||||||
await this.webpackDevMiddleware.close()
|
await this.webpackDevMiddleware.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async generateConfig() {
|
||||||
|
const config = resolve(this.options.buildDir, 'build.config.js')
|
||||||
|
const options = _.omit(this.options, Options.unsafeKeys)
|
||||||
|
await writeFile(config, `module.exports = ${JSON.stringify(options, null, ' ')}`, 'utf8')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const STATUS = {
|
const STATUS = {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { copy, remove, writeFile, mkdirp, removeSync, existsSync } from 'fs-extra'
|
const { copy, remove, writeFile, mkdirp, removeSync, existsSync } = require('fs-extra')
|
||||||
import _ from 'lodash'
|
const _ = require('lodash')
|
||||||
import { resolve, join, dirname, sep } from 'path'
|
const { resolve, join, dirname, sep } = require('path')
|
||||||
import { minify } from 'html-minifier'
|
const { minify } = require('html-minifier')
|
||||||
import { isUrl, promisifyRoute, waitFor, flatRoutes } from 'utils'
|
const { isUrl, promisifyRoute, waitFor, flatRoutes } = require('../common/utils')
|
||||||
|
|
||||||
export default class Generator {
|
module.exports = class Generator {
|
||||||
constructor(nuxt, builder) {
|
constructor(nuxt, builder) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.options = nuxt.options
|
this.options = nuxt.options
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Builder from './builder'
|
const Builder = require('./builder')
|
||||||
import Generator from './generator'
|
const Generator = require('./generator')
|
||||||
|
|
||||||
export {
|
module.exports = {
|
||||||
Builder,
|
Builder,
|
||||||
Generator
|
Generator
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||||
import { cloneDeep } from 'lodash'
|
const { cloneDeep } = require('lodash')
|
||||||
import { join, resolve } from 'path'
|
const { join, resolve } = require('path')
|
||||||
import webpack from 'webpack'
|
const webpack = require('webpack')
|
||||||
import { isUrl, urlJoin } from 'utils'
|
const { isUrl, urlJoin } = require('../../common/utils')
|
||||||
import TimeFixPlugin from './timefix-plugin'
|
const TimeFixPlugin = require('./plugins/timefix')
|
||||||
|
const WarnFixPlugin = require('./plugins/warnfix')
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -13,19 +14,17 @@ import TimeFixPlugin from './timefix-plugin'
|
|||||||
| webpack config files
|
| webpack config files
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export default function webpackBaseConfig(name) {
|
module.exports = function webpackBaseConfig({ name, isServer }) {
|
||||||
const nodeModulesDir = join(__dirname, '..', 'node_modules')
|
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
name,
|
name,
|
||||||
devtool: this.options.dev ? 'cheap-module-source-map' : 'nosources-source-map',
|
devtool: this.options.dev ? 'cheap-module-eval-source-map' : false,
|
||||||
entry: {
|
entry: {
|
||||||
app: null
|
app: null
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: resolve(this.options.buildDir, 'dist'),
|
path: resolve(this.options.buildDir, 'dist'),
|
||||||
filename: this.options.build.filenames.app,
|
filename: this.getFileName('app'),
|
||||||
chunkFilename: this.options.build.filenames.chunk,
|
chunkFilename: this.getFileName('chunk'),
|
||||||
publicPath: (isUrl(this.options.build.publicPath)
|
publicPath: (isUrl(this.options.build.publicPath)
|
||||||
? this.options.build.publicPath
|
? this.options.build.publicPath
|
||||||
: urlJoin(this.options.router.base, this.options.build.publicPath))
|
: urlJoin(this.options.router.base, this.options.build.publicPath))
|
||||||
@ -47,16 +46,10 @@ export default function webpackBaseConfig(name) {
|
|||||||
'assets': join(this.options.srcDir, 'assets'),
|
'assets': join(this.options.srcDir, 'assets'),
|
||||||
'static': join(this.options.srcDir, 'static')
|
'static': join(this.options.srcDir, 'static')
|
||||||
},
|
},
|
||||||
modules: [
|
modules: this.options.modulesDir
|
||||||
...this.options.modulesDir,
|
|
||||||
nodeModulesDir
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
resolveLoader: {
|
resolveLoader: {
|
||||||
modules: [
|
modules: this.options.modulesDir
|
||||||
...this.options.modulesDir,
|
|
||||||
nodeModulesDir
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
noParse: /es6-promise\.js$/, // Avoid webpack shimming process
|
noParse: /es6-promise\.js$/, // Avoid webpack shimming process
|
||||||
@ -64,13 +57,13 @@ export default function webpackBaseConfig(name) {
|
|||||||
{
|
{
|
||||||
test: /\.vue$/,
|
test: /\.vue$/,
|
||||||
loader: 'vue-loader',
|
loader: 'vue-loader',
|
||||||
options: this.vueLoader()
|
options: this.vueLoader({ isServer })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
options: Object.assign({}, this.babelOptions)
|
options: this.getBabelOptions({ isServer })
|
||||||
},
|
},
|
||||||
{ test: /\.css$/, use: this.styleLoader('css') },
|
{ test: /\.css$/, use: this.styleLoader('css') },
|
||||||
{ test: /\.less$/, use: this.styleLoader('less', 'less-loader') },
|
{ test: /\.less$/, use: this.styleLoader('less', 'less-loader') },
|
||||||
@ -106,32 +99,23 @@ export default function webpackBaseConfig(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add timefix-plugin before others plugins
|
// Add timefix-plugin before others plugins
|
||||||
|
if (this.options.dev) {
|
||||||
config.plugins.unshift(new TimeFixPlugin())
|
config.plugins.unshift(new TimeFixPlugin())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide warnings about plugins without a default export (#1179)
|
||||||
|
config.plugins.push(new WarnFixPlugin())
|
||||||
|
|
||||||
// CSS extraction
|
// CSS extraction
|
||||||
const extractCSS = this.options.build.extractCSS
|
const extractCSS = this.options.build.extractCSS
|
||||||
if (extractCSS) {
|
if (extractCSS) {
|
||||||
const extractOptions = Object.assign(
|
const extractOptions = Object.assign(
|
||||||
{ filename: this.options.build.filenames.css },
|
{ filename: this.getFileName('css') },
|
||||||
typeof extractCSS === 'object' ? extractCSS : {}
|
typeof extractCSS === 'object' ? extractCSS : {}
|
||||||
)
|
)
|
||||||
config.plugins.push(new ExtractTextPlugin(extractOptions))
|
config.plugins.push(new ExtractTextPlugin(extractOptions))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for hiding Warnings about plugins without a default export (#1179)
|
|
||||||
config.plugins.push({
|
|
||||||
apply(compiler) {
|
|
||||||
compiler.plugin('done', stats => {
|
|
||||||
stats.compilation.warnings = stats.compilation.warnings.filter(warn => {
|
|
||||||
if (warn.name === 'ModuleDependencyWarning' && warn.message.includes(`export 'default'`) && warn.message.includes('plugin')) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// Dev specific config
|
// Dev specific config
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { each } from 'lodash'
|
const { each } = require('lodash')
|
||||||
import webpack from 'webpack'
|
const webpack = require('webpack')
|
||||||
import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
|
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
|
||||||
import HTMLPlugin from 'html-webpack-plugin'
|
const HTMLPlugin = require('html-webpack-plugin')
|
||||||
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
|
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
|
||||||
import UglifyJSPlugin from 'uglifyjs-webpack-plugin'
|
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
|
||||||
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
|
||||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
const ProgressPlugin = require('webpack/lib/ProgressPlugin')
|
||||||
import { resolve } from 'path'
|
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
|
||||||
import { existsSync } from 'fs'
|
const { resolve } = require('path')
|
||||||
import Debug from 'debug'
|
const { existsSync } = require('fs')
|
||||||
import base from './base.config.js'
|
const Debug = require('debug')
|
||||||
|
const Chalk = require('chalk')
|
||||||
|
const base = require('./base.config.js')
|
||||||
|
|
||||||
const debug = Debug('nuxt:build')
|
const debug = Debug('nuxt:build')
|
||||||
debug.color = 2 // Force green color
|
debug.color = 2 // Force green color
|
||||||
@ -24,8 +26,8 @@ debug.color = 2 // Force green color
|
|||||||
| In production, will generate public/dist/style.css
|
| In production, will generate public/dist/style.css
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export default function webpackClientConfig() {
|
module.exports = function webpackClientConfig() {
|
||||||
let config = base.call(this, 'client')
|
let config = base.call(this, { name: 'client', isServer: false })
|
||||||
|
|
||||||
// Entry points
|
// Entry points
|
||||||
config.entry.app = resolve(this.options.buildDir, 'client.js')
|
config.entry.app = resolve(this.options.buildDir, 'client.js')
|
||||||
@ -73,7 +75,7 @@ export default function webpackClientConfig() {
|
|||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'manifest',
|
name: 'manifest',
|
||||||
minChunks: Infinity,
|
minChunks: Infinity,
|
||||||
filename: this.options.build.filenames.manifest
|
filename: this.getFileName('manifest')
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -91,17 +93,29 @@ export default function webpackClientConfig() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Build progress bar
|
// Build progress bar
|
||||||
config.plugins.push(
|
if (this.options.build.profile) {
|
||||||
new ProgressBarPlugin()
|
config.plugins.push(new ProgressPlugin({
|
||||||
)
|
profile: true
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
config.plugins.push(new ProgressBarPlugin({
|
||||||
|
complete: Chalk.green('█'),
|
||||||
|
incomplete: Chalk.white('█'),
|
||||||
|
format: ' :bar ' + Chalk.green.bold(':percent') + ' :msg',
|
||||||
|
clear: false
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldClearConsole = this.options.build.stats !== false &&
|
||||||
|
this.options.build.stats !== 'errors-only'
|
||||||
|
|
||||||
|
// Add friendly error plugin
|
||||||
|
config.plugins.push(new FriendlyErrorsWebpackPlugin({ clearConsole: shouldClearConsole }))
|
||||||
|
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// Dev specific config
|
// Dev specific config
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
if (this.options.dev) {
|
if (this.options.dev) {
|
||||||
// Add friendly error plugin
|
|
||||||
config.plugins.push(new FriendlyErrorsWebpackPlugin())
|
|
||||||
|
|
||||||
// https://webpack.js.org/plugins/named-modules-plugin
|
// https://webpack.js.org/plugins/named-modules-plugin
|
||||||
config.plugins.push(new webpack.NamedModulesPlugin())
|
config.plugins.push(new webpack.NamedModulesPlugin())
|
||||||
|
|
||||||
@ -139,7 +153,7 @@ export default function webpackClientConfig() {
|
|||||||
if (this.options.build.uglify !== false) {
|
if (this.options.build.uglify !== false) {
|
||||||
config.plugins.push(
|
config.plugins.push(
|
||||||
new UglifyJSPlugin(Object.assign({
|
new UglifyJSPlugin(Object.assign({
|
||||||
cache: true,
|
// cache: true,
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
parallel: true,
|
parallel: true,
|
||||||
extractComments: {
|
extractComments: {
|
||||||
@ -184,36 +198,18 @@ export default function webpackClientConfig() {
|
|||||||
// Adds Common Chunks Plugin
|
// Adds Common Chunks Plugin
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
function commonChunksPlugin(config) {
|
function commonChunksPlugin(config) {
|
||||||
const _this = this
|
|
||||||
const totalPages = _this.routes ? _this.routes.length : 0
|
|
||||||
|
|
||||||
// This well-known vendor may exist as a dependency of other requests.
|
|
||||||
const maybeVendor = [
|
|
||||||
'/core-js/',
|
|
||||||
'/regenerator-runtime/',
|
|
||||||
'/es6-promise/',
|
|
||||||
'/babel-runtime/',
|
|
||||||
'/lodash/'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Create explicit vendor chunk
|
// Create explicit vendor chunk
|
||||||
config.plugins.unshift(
|
config.plugins.unshift(
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'vendor',
|
name: 'vendor',
|
||||||
filename: this.options.build.filenames.vendor,
|
filename: this.getFileName('vendor'),
|
||||||
minChunks(module, count) {
|
minChunks(module, count) {
|
||||||
// Detect and externalize well-known vendor if detected
|
|
||||||
if (module.context && maybeVendor.some(v => module.context.includes(v))) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// A module is extracted into the vendor chunk when...
|
// A module is extracted into the vendor chunk when...
|
||||||
return (
|
return (
|
||||||
// If it's inside node_modules
|
// If it's inside node_modules
|
||||||
/node_modules/.test(module.context) &&
|
/node_modules/.test(module.context) &&
|
||||||
// Do not externalize if the request is a CSS file
|
// Do not externalize if the request is a CSS file or a Vue file which can potentially emit CSS assets!
|
||||||
!/\.(css|less|scss|sass|styl|stylus)$/.test(module.request) &&
|
!/\.(css|less|scss|sass|styl|stylus|vue)$/.test(module.request)
|
||||||
// Used in at-least 1/2 of the total pages
|
|
||||||
(totalPages <= 2 ? count >= totalPages : count >= totalPages * 0.5)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import webpack from 'webpack'
|
const webpack = require('webpack')
|
||||||
import { resolve } from 'path'
|
const { resolve } = require('path')
|
||||||
import ClientConfig from './client.config'
|
const ClientConfig = require('./client.config')
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -8,7 +8,7 @@ import ClientConfig from './client.config'
|
|||||||
| https://github.com/webpack/webpack/tree/master/examples/dll
|
| https://github.com/webpack/webpack/tree/master/examples/dll
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export default function webpackDllConfig(_refConfig) {
|
module.exports = function webpackDllConfig(_refConfig) {
|
||||||
const refConfig = _refConfig || new ClientConfig()
|
const refConfig = _refConfig || new ClientConfig()
|
||||||
|
|
||||||
const name = refConfig.name + '-dll'
|
const name = refConfig.name + '-dll'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Taken from https://github.com/egoist/poi/blob/3e93c88c520db2d20c25647415e6ae0d3de61145/packages/poi/lib/webpack/timefix-plugin.js#L1-L16
|
// Taken from https://github.com/egoist/poi/blob/3e93c88c520db2d20c25647415e6ae0d3de61145/packages/poi/lib/webpack/timefix-plugin.js#L1-L16
|
||||||
// Thanks to @egoist
|
// Thanks to @egoist
|
||||||
export default class TimeFixPlugin {
|
module.exports = class TimeFixPlugin {
|
||||||
constructor(timefix = 11000) {
|
constructor(timefix = 11000) {
|
||||||
this.timefix = timefix
|
this.timefix = timefix
|
||||||
}
|
}
|
14
lib/builder/webpack/plugins/warnfix.js
Normal file
14
lib/builder/webpack/plugins/warnfix.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module.exports = class WarnFixPlugin {
|
||||||
|
apply(compiler) /* istanbul ignore next */ {
|
||||||
|
compiler.plugin('done', stats => {
|
||||||
|
stats.compilation.warnings = stats.compilation.warnings.filter(warn => {
|
||||||
|
if (warn.name === 'ModuleDependencyWarning' &&
|
||||||
|
warn.message.includes(`export 'default'`) &&
|
||||||
|
warn.message.includes('nuxt_plugin_')) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
import webpack from 'webpack'
|
const webpack = require('webpack')
|
||||||
import VueSSRServerPlugin from 'vue-server-renderer/server-plugin'
|
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
|
||||||
import nodeExternals from 'webpack-node-externals'
|
const nodeExternals = require('webpack-node-externals')
|
||||||
import { each } from 'lodash'
|
const { each } = require('lodash')
|
||||||
import { resolve } from 'path'
|
const { resolve } = require('path')
|
||||||
import { existsSync } from 'fs'
|
const { existsSync } = require('fs')
|
||||||
import base from './base.config.js'
|
const base = require('./base.config.js')
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Webpack Server Config
|
| Webpack Server Config
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export default function webpackServerConfig() {
|
module.exports = function webpackServerConfig() {
|
||||||
let config = base.call(this, 'server')
|
let config = base.call(this, { name: 'server', isServer: true })
|
||||||
|
|
||||||
// env object defined in nuxt.config.js
|
// env object defined in nuxt.config.js
|
||||||
let env = {}
|
let env = {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||||
import { join } from 'path'
|
const { join } = require('path')
|
||||||
|
|
||||||
export default function styleLoader(ext, loaders = [], isVueLoader = false) {
|
module.exports = function styleLoader(ext, loaders = [], isVueLoader = false) {
|
||||||
// Normalize loaders
|
// Normalize loaders
|
||||||
loaders = (Array.isArray(loaders) ? loaders : [loaders]).map(loader => {
|
loaders = (Array.isArray(loaders) ? loaders : [loaders]).map(loader => {
|
||||||
if (typeof loader === 'string') {
|
if (typeof loader === 'string') {
|
||||||
@ -45,8 +45,8 @@ export default function styleLoader(ext, loaders = [], isVueLoader = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.build.extractCSS && !this.options.dev) {
|
if (this.options.build.extractCSS) {
|
||||||
return ExtractTextPlugin.extract({
|
const extraction = ExtractTextPlugin.extract({
|
||||||
fallback: vueStyleLoader,
|
fallback: vueStyleLoader,
|
||||||
use: [
|
use: [
|
||||||
cssLoader,
|
cssLoader,
|
||||||
@ -54,6 +54,7 @@ export default function styleLoader(ext, loaders = [], isVueLoader = false) {
|
|||||||
...loaders
|
...loaders
|
||||||
].filter(l => l)
|
].filter(l => l)
|
||||||
})
|
})
|
||||||
|
return this.options.dev ? ['css-hot-loader'].concat(extraction) : extraction
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/yenshih/style-resources-loader
|
// https://github.com/yenshih/style-resources-loader
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export default function vueLoader() {
|
module.exports = function vueLoader({ isServer }) {
|
||||||
// https://vue-loader.vuejs.org/en
|
// https://vue-loader.vuejs.org/en
|
||||||
const config = {
|
const config = {
|
||||||
postcss: this.options.build.postcss,
|
postcss: this.options.build.postcss,
|
||||||
@ -8,7 +8,7 @@ export default function vueLoader() {
|
|||||||
loaders: {
|
loaders: {
|
||||||
'js': {
|
'js': {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: Object.assign({}, this.babelOptions)
|
options: this.getBabelOptions({ isServer })
|
||||||
},
|
},
|
||||||
// Note: do not nest the `postcss` option under `loaders`
|
// Note: do not nest the `postcss` option under `loaders`
|
||||||
'css': this.styleLoader('css', [], true),
|
'css': this.styleLoader('css', [], true),
|
||||||
|
@ -8,10 +8,9 @@ pe.skipPackage('regenerator-runtime')
|
|||||||
pe.skipPackage('babel-runtime')
|
pe.skipPackage('babel-runtime')
|
||||||
pe.skipPackage('core-js')
|
pe.skipPackage('core-js')
|
||||||
|
|
||||||
// Skip dist artifacts and Node internals
|
// Skip node internals
|
||||||
const skipFiles = [ 'nuxt.js', 'core.js' ]
|
|
||||||
pe.skip((traceLine, lineNumber) => {
|
pe.skip((traceLine, lineNumber) => {
|
||||||
if (!traceLine.file || skipFiles.indexOf(traceLine.file) !== -1) {
|
if (!traceLine.file) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import * as Utils from './utils'
|
const Utils = require('./utils')
|
||||||
import Options from './options'
|
const Options = require('./options')
|
||||||
|
|
||||||
export default {
|
module.exports = {
|
||||||
Utils,
|
|
||||||
Options
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
Utils,
|
Utils,
|
||||||
Options
|
Options
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import _ from 'lodash'
|
const _ = require('lodash')
|
||||||
import Debug from 'debug'
|
const Debug = require('debug')
|
||||||
import { join, resolve } from 'path'
|
const { join, resolve } = require('path')
|
||||||
import { existsSync } from 'fs'
|
const { existsSync } = require('fs')
|
||||||
import { isUrl, isPureObject } from 'utils'
|
const { isUrl, isPureObject } = require('../common/utils')
|
||||||
|
|
||||||
const debug = Debug('nuxt:build')
|
const debug = Debug('nuxt:build')
|
||||||
debug.color = 2 // Force green color
|
debug.color = 2 // Force green color
|
||||||
|
|
||||||
const Options = {}
|
const Options = {}
|
||||||
|
|
||||||
export default Options
|
module.exports = Options
|
||||||
|
|
||||||
Options.from = function (_options) {
|
Options.from = function (_options) {
|
||||||
// Clone options to prevent unwanted side-effects
|
// Clone options to prevent unwanted side-effects
|
||||||
@ -32,25 +32,30 @@ Options.from = function (_options) {
|
|||||||
options.layoutTransition = { name: options.layoutTransition }
|
options.layoutTransition = { name: options.layoutTransition }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasValue = v => typeof v === 'string' && v
|
||||||
|
options.rootDir = hasValue(options.rootDir) ? options.rootDir : process.cwd()
|
||||||
|
|
||||||
|
// Apply defaults by ${buildDir}/dist/build.config.js
|
||||||
|
// TODO: Unsafe operation.
|
||||||
|
// const buildDir = options.buildDir || Options.defaults.buildDir
|
||||||
|
// const buildConfig = resolve(options.rootDir, buildDir, 'build.config.js')
|
||||||
|
// if (existsSync(buildConfig)) {
|
||||||
|
// _.defaultsDeep(options, require(buildConfig))
|
||||||
|
// }
|
||||||
|
|
||||||
// Apply defaults
|
// Apply defaults
|
||||||
_.defaultsDeep(options, Options.defaults)
|
_.defaultsDeep(options, Options.defaults)
|
||||||
|
|
||||||
// Resolve dirs
|
// Resolve dirs
|
||||||
const hasValue = v => typeof v === 'string' && v
|
|
||||||
options.rootDir = hasValue(options.rootDir) ? options.rootDir : process.cwd()
|
|
||||||
options.srcDir = hasValue(options.srcDir) ? resolve(options.rootDir, options.srcDir) : options.rootDir
|
options.srcDir = hasValue(options.srcDir) ? resolve(options.rootDir, options.srcDir) : options.rootDir
|
||||||
options.buildDir = resolve(options.rootDir, options.buildDir)
|
options.buildDir = resolve(options.rootDir, options.buildDir)
|
||||||
options.cacheDir = resolve(options.rootDir, options.cacheDir)
|
options.cacheDir = resolve(options.rootDir, options.cacheDir)
|
||||||
|
|
||||||
// Normalize modulesDir
|
// Populate modulesDir
|
||||||
/* istanbul ignore if */
|
options.modulesDir = []
|
||||||
if (!options.modulesDir) {
|
.concat(options.modulesDir, join(options.nuxtDir, 'node_modules'))
|
||||||
options.modulesDir = ['node_modules']
|
.filter(dir => hasValue(dir))
|
||||||
}
|
.map(dir => resolve(options.rootDir, dir))
|
||||||
if (!Array.isArray(options.modulesDir)) {
|
|
||||||
options.modulesDir = [options.modulesDir]
|
|
||||||
}
|
|
||||||
options.modulesDir = options.modulesDir.filter(dir => hasValue(dir)).map(dir => resolve(options.rootDir, dir))
|
|
||||||
|
|
||||||
// If app.html is defined, set the template path to the user template
|
// If app.html is defined, set the template path to the user template
|
||||||
options.appTemplatePath = resolve(options.buildDir, 'views/app.template.html')
|
options.appTemplatePath = resolve(options.buildDir, 'views/app.template.html')
|
||||||
@ -127,6 +132,7 @@ Options.from = function (_options) {
|
|||||||
}
|
}
|
||||||
if (isPureObject(options.build.postcss)) {
|
if (isPureObject(options.build.postcss)) {
|
||||||
options.build.postcss = Object.assign({
|
options.build.postcss = Object.assign({
|
||||||
|
useConfigFile: false,
|
||||||
sourceMap: options.build.cssSourceMap,
|
sourceMap: options.build.cssSourceMap,
|
||||||
plugins: {
|
plugins: {
|
||||||
// https://github.com/postcss/postcss-import
|
// https://github.com/postcss/postcss-import
|
||||||
@ -185,16 +191,23 @@ Options.modes = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Options.unsafeKeys = [
|
||||||
|
'rootDir', 'srcDir', 'buildDir', 'modulesDir', 'cacheDir', 'nuxtDir',
|
||||||
|
'nuxtAppDir', 'build', 'generate', 'router.routes', 'appTemplatePath'
|
||||||
|
]
|
||||||
|
|
||||||
Options.defaults = {
|
Options.defaults = {
|
||||||
mode: 'universal',
|
mode: 'universal',
|
||||||
dev: process.env.NODE_ENV !== 'production',
|
dev: process.env.NODE_ENV !== 'production',
|
||||||
debug: undefined, // Will be equal to dev if not provided
|
debug: undefined, // Will be equal to dev if not provided
|
||||||
buildDir: '.nuxt',
|
buildDir: '.nuxt',
|
||||||
cacheDir: '.cache',
|
cacheDir: '.cache',
|
||||||
nuxtDir: resolve(__dirname, '..'), // Relative to dist
|
nuxtDir: resolve(__dirname, '../..'),
|
||||||
nuxtAppDir: resolve(__dirname, '../lib/app/'), // Relative to dist
|
nuxtAppDir: resolve(__dirname, '../app'),
|
||||||
|
modulesDir: ['node_modules'], // ~> relative to options.rootDir
|
||||||
build: {
|
build: {
|
||||||
analyze: false,
|
analyze: false,
|
||||||
|
profile: process.argv.includes('--profile'),
|
||||||
dll: false,
|
dll: false,
|
||||||
scopeHoisting: false,
|
scopeHoisting: false,
|
||||||
extractCSS: false,
|
extractCSS: false,
|
||||||
@ -216,7 +229,18 @@ Options.defaults = {
|
|||||||
templates: [],
|
templates: [],
|
||||||
watch: [],
|
watch: [],
|
||||||
devMiddleware: {},
|
devMiddleware: {},
|
||||||
hotMiddleware: {}
|
hotMiddleware: {},
|
||||||
|
stats: {
|
||||||
|
chunks: false,
|
||||||
|
children: false,
|
||||||
|
modules: false,
|
||||||
|
colors: true,
|
||||||
|
excludeAssets: [
|
||||||
|
/.map$/,
|
||||||
|
/index\..+\.html$/,
|
||||||
|
/vue-ssr-client-manifest.json/
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
generate: {
|
generate: {
|
||||||
dir: 'dist',
|
dir: 'dist',
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { resolve, relative, sep } from 'path'
|
const { resolve, relative, sep } = require('path')
|
||||||
import _ from 'lodash'
|
const _ = require('lodash')
|
||||||
|
|
||||||
export function encodeHtml(str) {
|
exports.encodeHtml = function encodeHtml(str) {
|
||||||
return str.replace(/</g, '<').replace(/>/g, '>')
|
return str.replace(/</g, '<').replace(/>/g, '>')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getContext(req, res) {
|
exports.getContext = function getContext(req, res) {
|
||||||
return { req, res }
|
return { req, res }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setAnsiColors(ansiHTML) {
|
exports.setAnsiColors = function setAnsiColors(ansiHTML) {
|
||||||
ansiHTML.setColors({
|
ansiHTML.setColors({
|
||||||
reset: ['efefef', 'a6004c'],
|
reset: ['efefef', 'a6004c'],
|
||||||
darkgrey: '5a012b',
|
darkgrey: '5a012b',
|
||||||
@ -22,19 +22,19 @@ export function setAnsiColors(ansiHTML) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function waitFor(ms) {
|
exports.waitFor = async function waitFor(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, (ms || 0)))
|
return new Promise(resolve => setTimeout(resolve, (ms || 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function urlJoin() {
|
exports.urlJoin = function urlJoin() {
|
||||||
return [].slice.call(arguments).join('/').replace(/\/+/g, '/').replace(':/', '://')
|
return [].slice.call(arguments).join('/').replace(/\/+/g, '/').replace(':/', '://')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isUrl(url) {
|
exports.isUrl = function isUrl(url) {
|
||||||
return (url.indexOf('http') === 0 || url.indexOf('//') === 0)
|
return (url.indexOf('http') === 0 || url.indexOf('//') === 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function promisifyRoute(fn, ...args) {
|
exports.promisifyRoute = function promisifyRoute(fn, ...args) {
|
||||||
// If routes is an array
|
// If routes is an array
|
||||||
if (Array.isArray(fn)) {
|
if (Array.isArray(fn)) {
|
||||||
return Promise.resolve(fn)
|
return Promise.resolve(fn)
|
||||||
@ -57,15 +57,15 @@ export function promisifyRoute(fn, ...args) {
|
|||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sequence(tasks, fn) {
|
exports.sequence = function sequence(tasks, fn) {
|
||||||
return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve())
|
return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parallel(tasks, fn) {
|
exports.parallel = function parallel(tasks, fn) {
|
||||||
return Promise.all(tasks.map(task => fn(task)))
|
return Promise.all(tasks.map(task => fn(task)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function chainFn(base, fn) {
|
exports.chainFn = function chainFn(base, fn) {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (!(fn instanceof Function)) {
|
if (!(fn instanceof Function)) {
|
||||||
return
|
return
|
||||||
@ -88,13 +88,13 @@ export function chainFn(base, fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPureObject(o) {
|
exports.isPureObject = function isPureObject(o) {
|
||||||
return !Array.isArray(o) && typeof o === 'object'
|
return !Array.isArray(o) && typeof o === 'object'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isWindows = /^win/.test(process.platform)
|
const isWindows = exports.isWindows = /^win/.test(process.platform)
|
||||||
|
|
||||||
export function wp(p = '') {
|
const wp = exports.wp = function wp(p = '') {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
return p.replace(/\\/g, '\\\\')
|
return p.replace(/\\/g, '\\\\')
|
||||||
@ -102,7 +102,7 @@ export function wp(p = '') {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wChunk(p = '') {
|
exports.wChunk = function wChunk(p = '') {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
return p.replace(/\//g, '_')
|
return p.replace(/\//g, '_')
|
||||||
@ -114,18 +114,18 @@ const reqSep = /\//g
|
|||||||
const sysSep = _.escapeRegExp(sep)
|
const sysSep = _.escapeRegExp(sep)
|
||||||
const normalize = string => string.replace(reqSep, sysSep)
|
const normalize = string => string.replace(reqSep, sysSep)
|
||||||
|
|
||||||
export function r() {
|
const r = exports.r = function r() {
|
||||||
let args = Array.prototype.slice.apply(arguments)
|
let args = Array.prototype.slice.apply(arguments)
|
||||||
let lastArg = _.last(args)
|
let lastArg = _.last(args)
|
||||||
|
|
||||||
if (lastArg.includes('@') || lastArg.includes('~')) {
|
if (lastArg.indexOf('@') === 0 || lastArg.indexOf('~') === 0) {
|
||||||
return wp(lastArg)
|
return wp(lastArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return wp(resolve(...args.map(normalize)))
|
return wp(resolve(...args.map(normalize)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function relativeTo() {
|
exports.relativeTo = function relativeTo() {
|
||||||
let args = Array.prototype.slice.apply(arguments)
|
let args = Array.prototype.slice.apply(arguments)
|
||||||
let dir = args.shift()
|
let dir = args.shift()
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ export function relativeTo() {
|
|||||||
let path = r(...args)
|
let path = r(...args)
|
||||||
|
|
||||||
// Check if path is an alias
|
// Check if path is an alias
|
||||||
if (path.includes('@') || path.includes('~')) {
|
if (path.indexOf('@') === 0 || path.indexOf('~') === 0) {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,13 +145,17 @@ export function relativeTo() {
|
|||||||
return wp(rp)
|
return wp(rp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flatRoutes(router, path = '', routes = []) {
|
exports.flatRoutes = function flatRoutes(router, path = '', routes = []) {
|
||||||
router.forEach((r) => {
|
router.forEach((r) => {
|
||||||
if (!r.path.includes(':') && !r.path.includes('*')) {
|
if (!r.path.includes(':') && !r.path.includes('*')) {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (r.children) {
|
if (r.children) {
|
||||||
|
if (path === '' && r.path === '/') {
|
||||||
|
routes.push('/')
|
||||||
|
}
|
||||||
flatRoutes(r.children, path + r.path + '/', routes)
|
flatRoutes(r.children, path + r.path + '/', routes)
|
||||||
} else {
|
} else {
|
||||||
|
path = path.replace(/^\/+$/, '/')
|
||||||
routes.push((r.path === '' && path[path.length - 1] === '/' ? path.slice(0, -1) : path) + r.path)
|
routes.push((r.path === '' && path[path.length - 1] === '/' ? path.slice(0, -1) : path) + r.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +163,7 @@ export function flatRoutes(router, path = '', routes = []) {
|
|||||||
return routes
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanChildrenRoutes(routes, isChild = false) {
|
function cleanChildrenRoutes(routes, isChild = false) {
|
||||||
let start = -1
|
let start = -1
|
||||||
let routesIndex = []
|
let routesIndex = []
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
@ -205,16 +209,16 @@ export function cleanChildrenRoutes(routes, isChild = false) {
|
|||||||
return routes
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createRoutes(files, srcDir) {
|
exports.createRoutes = function createRoutes(files, srcDir) {
|
||||||
let routes = []
|
let routes = []
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
let keys = file.replace(/^pages/, '').replace(/\.vue$/, '').replace(/\/{2,}/g, '/').split('/').slice(1)
|
let keys = file.replace(/^pages/, '').replace(/\.(vue|js)$/, '').replace(/\/{2,}/g, '/').split('/').slice(1)
|
||||||
let route = { name: '', path: '', component: r(srcDir, file) }
|
let route = { name: '', path: '', component: r(srcDir, file) }
|
||||||
let parent = routes
|
let parent = routes
|
||||||
keys.forEach((key, i) => {
|
keys.forEach((key, i) => {
|
||||||
route.name = route.name ? route.name + '-' + key.replace('_', '') : key.replace('_', '')
|
route.name = route.name ? route.name + '-' + key.replace('_', '') : key.replace('_', '')
|
||||||
route.name += (key === '_') ? 'all' : ''
|
route.name += (key === '_') ? 'all' : ''
|
||||||
route.chunkName = file.replace(/\.vue$/, '')
|
route.chunkName = file.replace(/\.(vue|js)$/, '')
|
||||||
let child = _.find(parent, { name: route.name })
|
let child = _.find(parent, { name: route.name })
|
||||||
if (child) {
|
if (child) {
|
||||||
child.children = child.children || []
|
child.children = child.children || []
|
||||||
@ -264,3 +268,16 @@ export function createRoutes(files, srcDir) {
|
|||||||
})
|
})
|
||||||
return cleanChildrenRoutes(routes)
|
return cleanChildrenRoutes(routes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.rmCache = function rmCache(path) {
|
||||||
|
const mod = require.cache[path]
|
||||||
|
delete require.cache[path]
|
||||||
|
if (mod.parent && mod.parent.children) {
|
||||||
|
for (let i = 0; i < mod.parent.children.length; i++) {
|
||||||
|
if (mod.parent.children[i] === mod) {
|
||||||
|
mod.parent.children.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Options, Utils } from 'common'
|
const { Options, Utils } = require('../common')
|
||||||
import Module from './module'
|
const Module = require('./module')
|
||||||
import Nuxt from './nuxt'
|
const Nuxt = require('./nuxt')
|
||||||
import Renderer from './renderer'
|
const Renderer = require('./renderer')
|
||||||
|
|
||||||
export {
|
module.exports = {
|
||||||
Nuxt,
|
Nuxt,
|
||||||
Module,
|
Module,
|
||||||
Renderer,
|
Renderer,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
import Vue from 'vue'
|
const Vue = require('vue')
|
||||||
import VueMeta from 'vue-meta'
|
const VueMeta = require('vue-meta')
|
||||||
import VueServerRenderer from 'vue-server-renderer'
|
const VueServerRenderer = require('vue-server-renderer')
|
||||||
import LRU from 'lru-cache'
|
const LRU = require('lru-cache')
|
||||||
|
|
||||||
export default class MetaRenderer {
|
module.exports = class MetaRenderer {
|
||||||
constructor(nuxt, renderer) {
|
constructor(nuxt, renderer) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.renderer = renderer
|
this.renderer = renderer
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import path from 'path'
|
const path = require('path')
|
||||||
import fs from 'fs'
|
const fs = require('fs')
|
||||||
import { uniq } from 'lodash'
|
const { uniq } = require('lodash')
|
||||||
import hash from 'hash-sum'
|
const hash = require('hash-sum')
|
||||||
import { chainFn, sequence } from 'utils'
|
const { chainFn, sequence } = require('../common/utils')
|
||||||
import Debug from 'debug'
|
const Debug = require('debug')
|
||||||
|
|
||||||
const debug = Debug('nuxt:module')
|
const debug = Debug('nuxt:module')
|
||||||
|
|
||||||
export default class ModuleContainer {
|
module.exports = class ModuleContainer {
|
||||||
constructor(nuxt) {
|
constructor(nuxt) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.options = nuxt.options
|
this.options = nuxt.options
|
||||||
|
@ -1,33 +1,25 @@
|
|||||||
import chalk from 'chalk'
|
const Debug = require('debug')
|
||||||
import { Options } from 'common'
|
const enableDestroy = require('server-destroy')
|
||||||
import { sequence } from 'utils'
|
const Module = require('module')
|
||||||
import ModuleContainer from './module'
|
const { isPlainObject } = require('lodash')
|
||||||
import Renderer from './renderer'
|
const chalk = require('chalk')
|
||||||
import Debug from 'debug'
|
const { Options } = require('../common')
|
||||||
import enableDestroy from 'server-destroy'
|
const { sequence } = require('../common/utils')
|
||||||
import Module from 'module'
|
const { join, resolve } = require('path')
|
||||||
import { isPlainObject } from 'lodash'
|
const { version } = require('../../package.json')
|
||||||
import { join, resolve } from 'path'
|
const ModuleContainer = require('./module')
|
||||||
|
const Renderer = require('./renderer')
|
||||||
|
|
||||||
const debug = Debug('nuxt:')
|
const debug = Debug('nuxt:')
|
||||||
debug.color = 5
|
debug.color = 5
|
||||||
|
|
||||||
export default class Nuxt {
|
module.exports = class Nuxt {
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
this.options = Options.from(options)
|
this.options = Options.from(options)
|
||||||
|
|
||||||
// Paths for resolving requires from `rootDir`
|
|
||||||
this.nodeModulePaths = Module._nodeModulePaths(this.options.rootDir)
|
|
||||||
|
|
||||||
if (this.options.nuxtDir.indexOf(this.options.rootDir) !== 0) {
|
|
||||||
this.nodeModulePaths = [
|
|
||||||
...this.nodeModulePaths,
|
|
||||||
...Module._nodeModulePaths(this.options.nuxtDir)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initialized = false
|
this.initialized = false
|
||||||
this.errorHandler = this.errorHandler.bind(this)
|
this.errorHandler = this.errorHandler.bind(this)
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
this._hooks = {}
|
this._hooks = {}
|
||||||
this.hook = this.hook.bind(this)
|
this.hook = this.hook.bind(this)
|
||||||
@ -45,7 +37,7 @@ export default class Nuxt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get version() {
|
static get version() {
|
||||||
return '__VERSION__'
|
return version
|
||||||
}
|
}
|
||||||
|
|
||||||
async ready() {
|
async ready() {
|
||||||
@ -177,7 +169,7 @@ export default class Nuxt {
|
|||||||
resolvePath(path) {
|
resolvePath(path) {
|
||||||
// Try to resolve using NPM resolve path first
|
// Try to resolve using NPM resolve path first
|
||||||
try {
|
try {
|
||||||
let resolvedPath = Module._resolveFilename(path, { paths: this.nodeModulePaths })
|
let resolvedPath = Module._resolveFilename(path, { paths: this.options.modulesDir })
|
||||||
return resolvedPath
|
return resolvedPath
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Just continue
|
// Just continue
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import ansiHTML from 'ansi-html'
|
const ansiHTML = require('ansi-html')
|
||||||
import serialize from 'serialize-javascript'
|
const serialize = require('serialize-javascript')
|
||||||
import generateETag from 'etag'
|
const generateETag = require('etag')
|
||||||
import fresh from 'fresh'
|
const fresh = require('fresh')
|
||||||
import serveStatic from 'serve-static'
|
const serveStatic = require('serve-static')
|
||||||
import compression from 'compression'
|
const compression = require('compression')
|
||||||
import _ from 'lodash'
|
const _ = require('lodash')
|
||||||
import { join, resolve } from 'path'
|
const { join, resolve } = require('path')
|
||||||
import fs from 'fs-extra'
|
const fs = require('fs-extra')
|
||||||
import { createBundleRenderer } from 'vue-server-renderer'
|
const { createBundleRenderer } = require('vue-server-renderer')
|
||||||
import { getContext, setAnsiColors, isUrl, waitFor } from 'utils'
|
const { getContext, setAnsiColors, isUrl, waitFor } = require('../common/utils')
|
||||||
import Debug from 'debug'
|
const Debug = require('debug')
|
||||||
import Youch from '@nuxtjs/youch'
|
const Youch = require('@nuxtjs/youch')
|
||||||
import { SourceMapConsumer } from 'source-map'
|
const { SourceMapConsumer } = require('source-map')
|
||||||
import connect from 'connect'
|
const connect = require('connect')
|
||||||
import { Options } from 'common'
|
const { Options } = require('../common')
|
||||||
import MetaRenderer from './meta'
|
const MetaRenderer = require('./meta')
|
||||||
|
|
||||||
const debug = Debug('nuxt:render')
|
const debug = Debug('nuxt:render')
|
||||||
debug.color = 4 // Force blue color
|
debug.color = 4 // Force blue color
|
||||||
@ -23,7 +23,7 @@ setAnsiColors(ansiHTML)
|
|||||||
|
|
||||||
let jsdom = null
|
let jsdom = null
|
||||||
|
|
||||||
export default class Renderer {
|
module.exports = class Renderer {
|
||||||
constructor(nuxt) {
|
constructor(nuxt) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.options = nuxt.options
|
this.options = nuxt.options
|
||||||
@ -126,6 +126,7 @@ export default class Renderer {
|
|||||||
|
|
||||||
get isResourcesAvailable() {
|
get isResourcesAvailable() {
|
||||||
// Required for both
|
// Required for both
|
||||||
|
/* istanbul ignore if */
|
||||||
if (!this.resources.clientManifest) {
|
if (!this.resources.clientManifest) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -223,7 +224,7 @@ export default class Renderer {
|
|||||||
|
|
||||||
// open in editor for debug mode only
|
// open in editor for debug mode only
|
||||||
const _this = this
|
const _this = this
|
||||||
if (this.options.debug) {
|
if (this.options.debug && this.options.dev) {
|
||||||
this.useMiddleware({
|
this.useMiddleware({
|
||||||
path: '_open',
|
path: '_open',
|
||||||
handler(req, res) {
|
handler(req, res) {
|
||||||
@ -417,9 +418,11 @@ export default class Renderer {
|
|||||||
if (line) {
|
if (line) {
|
||||||
frame.lineNumber = line
|
frame.lineNumber = line
|
||||||
}
|
}
|
||||||
|
/* istanbul ignore if */
|
||||||
if (column) {
|
if (column) {
|
||||||
frame.columnNumber = column
|
frame.columnNumber = column
|
||||||
}
|
}
|
||||||
|
/* istanbul ignore if */
|
||||||
if (name) {
|
if (name) {
|
||||||
frame.functionName = name
|
frame.functionName = name
|
||||||
}
|
}
|
||||||
|
13
lib/index.js
13
lib/index.js
@ -1,4 +1,11 @@
|
|||||||
import * as core from './core'
|
/*!
|
||||||
import * as builder from './builder'
|
* Nuxt.js
|
||||||
|
* (c) 2016-2017 Chopin Brothers
|
||||||
|
* Core maintainer: Pooya Parsa (@pi0)
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
export default Object.assign({}, core, builder)
|
const core = require('./core')
|
||||||
|
const builder = require('./builder')
|
||||||
|
|
||||||
|
module.exports = Object.assign({}, core, builder)
|
||||||
|
81
package.json
81
package.json
@ -13,7 +13,7 @@
|
|||||||
"name": "Pooya Parsa (@pi0)"
|
"name": "Pooya Parsa (@pi0)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"main": "./index.js",
|
"main": "./lib/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -21,9 +21,7 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"bin",
|
"bin",
|
||||||
"dist",
|
"lib"
|
||||||
"lib",
|
|
||||||
"index.js"
|
|
||||||
],
|
],
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"nuxt",
|
"nuxt",
|
||||||
@ -47,44 +45,39 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run lint && cross-env NODE_ENV=test npm run build:nuxt && nyc ava --verbose --serial test/ -- && nyc report --reporter=html",
|
"test": "npm run lint && nyc ava --verbose test/ -- && nyc report --reporter=html",
|
||||||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
|
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
|
||||||
"lint": "eslint --ext .js,.vue bin/* build/ lib/ test/ examples/",
|
"lint": "eslint --ext .js,.vue bin/* build/ lib/ test/ examples/",
|
||||||
"build": "rimraf dist/ && npm run build:nuxt && npm run build:core",
|
|
||||||
"build:nuxt": "rollup -c build/rollup.config.js --environment TARGET:nuxt",
|
|
||||||
"build:core": "rollup -c build/rollup.config.js --environment TARGET:core",
|
|
||||||
"watch": "npm run build:nuxt -- -w",
|
|
||||||
"make-start": "node ./build/start.js",
|
|
||||||
"precommit": "npm run lint",
|
"precommit": "npm run lint",
|
||||||
"postinstall": "opencollective postinstall || exit 0",
|
"postinstall": "opencollective postinstall || exit 0"
|
||||||
"release-next": "npm run build && node ./build/release-next && npm publish --tag next"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.11",
|
"node": ">=8.0.0",
|
||||||
"npm": ">=3.10.0"
|
"npm": ">=5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/youch": "^3.1.0",
|
"@nuxtjs/youch": "^3.1.0",
|
||||||
"ansi-html": "^0.0.7",
|
"ansi-html": "^0.0.7",
|
||||||
"autoprefixer": "^7.1.6",
|
"autoprefixer": "^7.2.3",
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-loader": "^7.1.2",
|
"babel-loader": "^7.1.2",
|
||||||
"babel-preset-vue-app": "^1.3.1",
|
"babel-preset-vue-app": "^2.0.0",
|
||||||
"caniuse-lite": "^1.0.30000772",
|
"caniuse-lite": "^1.0.30000784",
|
||||||
"chalk": "^2.3.0",
|
"chalk": "^2.3.0",
|
||||||
"chokidar": "^1.7.0",
|
"chokidar": "^1.7.0",
|
||||||
"clone": "^2.1.1",
|
"clone": "^2.1.1",
|
||||||
"compression": "^1.7.1",
|
"compression": "^1.7.1",
|
||||||
"connect": "^3.6.5",
|
"connect": "^3.6.5",
|
||||||
|
"css-hot-loader": "^1.3.4",
|
||||||
"css-loader": "^0.28.7",
|
"css-loader": "^0.28.7",
|
||||||
"debug": "^3.1.0",
|
"debug": "^3.1.0",
|
||||||
"es6-promise": "^4.1.1",
|
"es6-promise": "^4.2.1",
|
||||||
"etag": "^1.8.1",
|
"etag": "^1.8.1",
|
||||||
"extract-text-webpack-plugin": "^3.0.2",
|
"extract-text-webpack-plugin": "^3.0.2",
|
||||||
"file-loader": "^1.1.5",
|
"file-loader": "^1.1.6",
|
||||||
"fresh": "^0.5.2",
|
"fresh": "^0.5.2",
|
||||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||||
"fs-extra": "^4.0.2",
|
"fs-extra": "^5.0.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
"hash-sum": "^1.0.2",
|
"hash-sum": "^1.0.2",
|
||||||
"html-minifier": "3.5.7",
|
"html-minifier": "3.5.7",
|
||||||
@ -95,7 +88,6 @@
|
|||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"open-in-editor": "^2.2.0",
|
"open-in-editor": "^2.2.0",
|
||||||
"opencollective": "^1.0.3",
|
"opencollective": "^1.0.3",
|
||||||
"pify": "^3.0.0",
|
|
||||||
"postcss": "^6.0.14",
|
"postcss": "^6.0.14",
|
||||||
"postcss-cssnext": "^3.0.2",
|
"postcss-cssnext": "^3.0.2",
|
||||||
"postcss-import": "^11.0.0",
|
"postcss-import": "^11.0.0",
|
||||||
@ -107,57 +99,50 @@
|
|||||||
"serve-static": "^1.13.1",
|
"serve-static": "^1.13.1",
|
||||||
"server-destroy": "^1.0.1",
|
"server-destroy": "^1.0.1",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
"source-map-support": "^0.5.0",
|
"style-resources-loader": "^1.0.0",
|
||||||
"style-resources-loader": "^0.3.0",
|
"uglifyjs-webpack-plugin": "^1.1.4",
|
||||||
"uglifyjs-webpack-plugin": "^1.0.1",
|
|
||||||
"url-loader": "^0.6.2",
|
"url-loader": "^0.6.2",
|
||||||
"vue": "^2.5.9",
|
"vue": "^2.5.13",
|
||||||
"vue-loader": "^13.5.0",
|
"vue-loader": "^13.6.0",
|
||||||
"vue-meta": "^1.3.1",
|
"vue-meta": "^1.4.0",
|
||||||
"vue-router": "^3.0.1",
|
"vue-router": "^3.0.1",
|
||||||
"vue-server-renderer": "^2.5.9",
|
"vue-server-renderer": "^2.5.13",
|
||||||
"vue-template-compiler": "^2.5.9",
|
"vue-template-compiler": "^2.5.13",
|
||||||
"vuex": "^3.0.1",
|
"vuex": "^3.0.1",
|
||||||
"webpack": "^3.8.1",
|
"webpack": "^3.10.0",
|
||||||
"webpack-bundle-analyzer": "^2.9.0",
|
"webpack-bundle-analyzer": "^2.9.0",
|
||||||
"webpack-dev-middleware": "^1.12.2",
|
"webpack-dev-middleware": "^2.0.2",
|
||||||
"webpack-hot-middleware": "^2.21.0",
|
"webpack-hot-middleware": "^2.21.0",
|
||||||
"webpack-node-externals": "^1.6.0"
|
"webpack-node-externals": "^1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ava": "^0.24.0",
|
"ava": "^0.24.0",
|
||||||
"babel-eslint": "^8.0.1",
|
"babel-eslint": "^8.0.3",
|
||||||
"babel-plugin-array-includes": "^2.0.3",
|
"babel-plugin-array-includes": "^2.0.3",
|
||||||
"babel-plugin-external-helpers": "^6.22.0",
|
"babel-plugin-external-helpers": "^6.22.0",
|
||||||
"babel-plugin-istanbul": "^4.1.5",
|
"babel-plugin-istanbul": "^4.1.5",
|
||||||
"codecov": "^3.0.0",
|
"codecov": "^3.0.0",
|
||||||
"copy-webpack-plugin": "^4.2.0",
|
"copy-webpack-plugin": "^4.3.0",
|
||||||
"cross-env": "^5.1.1",
|
"cross-env": "^5.1.2",
|
||||||
"eslint": "^4.12.0",
|
"eslint": "^4.13.1",
|
||||||
"eslint-config-standard": "^10.2.1",
|
"eslint-config-standard": "^11.0.0-beta.0",
|
||||||
|
"eslint-config-standard-jsx": "^4.0.2",
|
||||||
"eslint-plugin-html": "^4.0.1",
|
"eslint-plugin-html": "^4.0.1",
|
||||||
"eslint-plugin-import": "^2.8.0",
|
"eslint-plugin-import": "^2.8.0",
|
||||||
"eslint-plugin-node": "^5.2.1",
|
"eslint-plugin-node": "^5.2.1",
|
||||||
"eslint-plugin-promise": "^3.6.0",
|
"eslint-plugin-promise": "^3.6.0",
|
||||||
|
"eslint-plugin-react": "^7.5.1",
|
||||||
"eslint-plugin-standard": "^3.0.1",
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
"finalhandler": "^1.1.0",
|
"finalhandler": "^1.1.0",
|
||||||
"jsdom": "^11.3.0",
|
"jsdom": "^11.5.1",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"nyc": "^11.3.0",
|
"nyc": "^11.4.1",
|
||||||
"puppeteer": "^0.13.0",
|
"puppeteer": "^0.13.0",
|
||||||
"request": "^2.83.0",
|
"request": "^2.83.0",
|
||||||
"request-promise-native": "^1.0.5",
|
"request-promise-native": "^1.0.5",
|
||||||
"rimraf": "^2.6.2",
|
"sinon": "^4.1.2",
|
||||||
"rollup": "^0.51.7",
|
"uglify-js": "^3.2.2"
|
||||||
"rollup-plugin-alias": "^1.4.0",
|
|
||||||
"rollup-plugin-babel": "^3.0.2",
|
|
||||||
"rollup-plugin-commonjs": "^8.2.6",
|
|
||||||
"rollup-plugin-node-resolve": "^3.0.0",
|
|
||||||
"rollup-plugin-replace": "^2.0.0",
|
|
||||||
"rollup-watch": "^4.3.1",
|
|
||||||
"std-mocks": "^1.0.1",
|
|
||||||
"uglify-js": "^3.2.0"
|
|
||||||
},
|
},
|
||||||
"collective": {
|
"collective": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
1
build/release-next.js → scripts/release-next
Normal file → Executable file
1
build/release-next.js → scripts/release-next
Normal file → Executable file
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const { readFileSync, writeFileSync } = require('fs-extra')
|
const { readFileSync, writeFileSync } = require('fs-extra')
|
||||||
const { resolve } = require('path')
|
const { resolve } = require('path')
|
||||||
const { spawnSync } = require('child_process')
|
const { spawnSync } = require('child_process')
|
@ -1,6 +1,6 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Options } from '../index'
|
import { Nuxt, Options } from '..'
|
||||||
import { version } from '../package.json'
|
import { version } from '../package.json'
|
||||||
|
|
||||||
test('Nuxt.version is same as package', t => {
|
test('Nuxt.version is same as package', t => {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index'
|
import { Nuxt, Builder } from '..'
|
||||||
import * as browser from './helpers/browser'
|
import * as browser from './helpers/browser'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const port = 4003
|
const port = 4003
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
@ -10,36 +11,46 @@ let nuxt = null
|
|||||||
let page = null
|
let page = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4003
|
// Init nuxt.js and create server listening on localhost:4003
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
dev: false,
|
buildDir: '.nuxt-csr',
|
||||||
|
dev: true,
|
||||||
head: {
|
head: {
|
||||||
titleTemplate(titleChunk) {
|
titleTemplate(titleChunk) {
|
||||||
return titleChunk ? `${titleChunk} - Nuxt.js` : 'Nuxt.js'
|
return titleChunk ? `${titleChunk} - Nuxt.js` : 'Nuxt.js'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(options)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test.before('Start browser', async t => {
|
test.serial('Start browser', async t => {
|
||||||
|
t.plan(0) // suppress 'no assertions' warning
|
||||||
await browser.start({
|
await browser.start({
|
||||||
// slowMo: 50,
|
// slowMo: 50,
|
||||||
// headless: false
|
// headless: false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Open /', async t => {
|
test.serial('Open /', async t => {
|
||||||
page = await browser.page(url('/'))
|
page = await browser.page(url('/'))
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'Index page')
|
t.is(await page.$text('h1'), 'Index page')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateless', async t => {
|
test.serial('/stateless', async t => {
|
||||||
const { hook } = await page.nuxt.navigate('/stateless', false)
|
const { hook } = await page.nuxt.navigate('/stateless', false)
|
||||||
const loading = await page.nuxt.loadingData()
|
const loading = await page.nuxt.loadingData()
|
||||||
|
|
||||||
@ -48,27 +59,27 @@ test('/stateless', async t => {
|
|||||||
t.is(await page.$text('h1'), 'My component!')
|
t.is(await page.$text('h1'), 'My component!')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/css', async t => {
|
test.serial('/css', async t => {
|
||||||
await page.nuxt.navigate('/css')
|
await page.nuxt.navigate('/css')
|
||||||
|
|
||||||
t.is(await page.$text('.red'), 'This is red')
|
t.is(await page.$text('.red'), 'This is red')
|
||||||
t.is(await page.$eval('.red', (red) => window.getComputedStyle(red).color), 'rgb(255, 0, 0)')
|
t.is(await page.$eval('.red', (red) => window.getComputedStyle(red).color), 'rgb(255, 0, 0)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateful', async t => {
|
test.serial('/stateful', async t => {
|
||||||
await page.nuxt.navigate('/stateful')
|
await page.nuxt.navigate('/stateful')
|
||||||
|
|
||||||
t.is(await page.$text('p'), 'The answer is 42')
|
t.is(await page.$text('p'), 'The answer is 42')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/store', async t => {
|
test.serial('/store', async t => {
|
||||||
await page.nuxt.navigate('/store')
|
await page.nuxt.navigate('/store')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'Vuex Nested Modules')
|
t.is(await page.$text('h1'), 'Vuex Nested Modules')
|
||||||
t.is(await page.$text('p'), '1')
|
t.is(await page.$text('p'), '1')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/head', async t => {
|
test.serial('/head', async t => {
|
||||||
const msg = new Promise((resolve) => page.on('console', (msg) => resolve(msg.text)))
|
const msg = new Promise((resolve) => page.on('console', (msg) => resolve(msg.text)))
|
||||||
await page.nuxt.navigate('/head')
|
await page.nuxt.navigate('/head')
|
||||||
const metas = await page.$$attr('meta', 'content')
|
const metas = await page.$$attr('meta', 'content')
|
||||||
@ -79,31 +90,31 @@ test('/head', async t => {
|
|||||||
t.is(metas[0], 'my meta')
|
t.is(metas[0], 'my meta')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/async-data', async t => {
|
test.serial('/async-data', async t => {
|
||||||
await page.nuxt.navigate('/async-data')
|
await page.nuxt.navigate('/async-data')
|
||||||
|
|
||||||
t.is(await page.$text('p'), 'Nuxt.js')
|
t.is(await page.$text('p'), 'Nuxt.js')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/await-async-data', async t => {
|
test.serial('/await-async-data', async t => {
|
||||||
await page.nuxt.navigate('/await-async-data')
|
await page.nuxt.navigate('/await-async-data')
|
||||||
|
|
||||||
t.is(await page.$text('p'), 'Await Nuxt.js')
|
t.is(await page.$text('p'), 'Await Nuxt.js')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/callback-async-data', async t => {
|
test.serial('/callback-async-data', async t => {
|
||||||
await page.nuxt.navigate('/callback-async-data')
|
await page.nuxt.navigate('/callback-async-data')
|
||||||
|
|
||||||
t.is(await page.$text('p'), 'Callback Nuxt.js')
|
t.is(await page.$text('p'), 'Callback Nuxt.js')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/users/1', async t => {
|
test.serial('/users/1', async t => {
|
||||||
await page.nuxt.navigate('/users/1')
|
await page.nuxt.navigate('/users/1')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'User: 1')
|
t.is(await page.$text('h1'), 'User: 1')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/validate should display a 404', async t => {
|
test.serial('/validate should display a 404', async t => {
|
||||||
await page.nuxt.navigate('/validate')
|
await page.nuxt.navigate('/validate')
|
||||||
const error = await page.nuxt.errorData()
|
const error = await page.nuxt.errorData()
|
||||||
|
|
||||||
@ -111,79 +122,91 @@ test('/validate should display a 404', async t => {
|
|||||||
t.is(error.message, 'This page could not be found')
|
t.is(error.message, 'This page could not be found')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/validate?valid=true', async t => {
|
test.serial('/validate?valid=true', async t => {
|
||||||
await page.nuxt.navigate('/validate?valid=true')
|
await page.nuxt.navigate('/validate?valid=true')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'I am valid')
|
t.is(await page.$text('h1'), 'I am valid')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect', async t => {
|
test.serial('/redirect', async t => {
|
||||||
await page.nuxt.navigate('/redirect')
|
await page.nuxt.navigate('/redirect')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'Index page')
|
t.is(await page.$text('h1'), 'Index page')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error', async t => {
|
test.serial('/error', async t => {
|
||||||
await page.nuxt.navigate('/error')
|
await page.nuxt.navigate('/error')
|
||||||
|
|
||||||
t.deepEqual(await page.nuxt.errorData(), { statusCode: 500 })
|
t.deepEqual(await page.nuxt.errorData(), { statusCode: 500 })
|
||||||
t.is(await page.$text('.title'), 'Error mouahahah')
|
t.is(await page.$text('.title'), 'Error mouahahah')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error2', async t => {
|
test.serial('/error2', async t => {
|
||||||
await page.nuxt.navigate('/error2')
|
await page.nuxt.navigate('/error2')
|
||||||
|
|
||||||
t.is(await page.$text('.title'), 'Custom error')
|
t.is(await page.$text('.title'), 'Custom error')
|
||||||
t.deepEqual(await page.nuxt.errorData(), { message: 'Custom error' })
|
t.deepEqual(await page.nuxt.errorData(), { message: 'Custom error' })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect2', async t => {
|
test.serial('/redirect-middleware', async t => {
|
||||||
await page.nuxt.navigate('/redirect2')
|
await page.nuxt.navigate('/redirect-middleware')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'Index page')
|
t.is(await page.$text('h1'), 'Index page')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect3', async t => {
|
test.serial('/redirect-external', async t => {
|
||||||
// New page for redirecting to external link.
|
// New page for redirecting to external link.
|
||||||
const page = await browser.page(url('/'))
|
const page = await browser.page(url('/'))
|
||||||
await page.nuxt.navigate('/redirect3', false)
|
await page.nuxt.navigate('/redirect-external', false)
|
||||||
await page.waitForFunction(() => window.location.href === 'https://nuxtjs.org/')
|
await page.waitForFunction(() => window.location.href === 'https://nuxtjs.org/')
|
||||||
page.close()
|
page.close()
|
||||||
t.pass()
|
t.pass()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/no-ssr', async t => {
|
test.serial('/redirect-name', async t => {
|
||||||
|
await page.nuxt.navigate('/redirect-name')
|
||||||
|
|
||||||
|
t.is(await page.$text('h1'), 'My component!')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/no-ssr', async t => {
|
||||||
await page.nuxt.navigate('/no-ssr')
|
await page.nuxt.navigate('/no-ssr')
|
||||||
|
|
||||||
t.is(await page.$text('h1'), 'Displayed only on client-side')
|
t.is(await page.$text('h1'), 'Displayed only on client-side')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/meta', async t => {
|
test.serial('/meta', async t => {
|
||||||
await page.nuxt.navigate('/meta')
|
await page.nuxt.navigate('/meta')
|
||||||
|
|
||||||
const state = await page.nuxt.storeState()
|
const state = await page.nuxt.storeState()
|
||||||
t.deepEqual(state.meta, [{ works: true }])
|
t.deepEqual(state.meta, [{ works: true }])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/fn-midd', async t => {
|
test.serial('/fn-midd', async t => {
|
||||||
await page.nuxt.navigate('/fn-midd')
|
await page.nuxt.navigate('/fn-midd')
|
||||||
|
|
||||||
t.is(await page.$text('.title'), 'You need to ask the permission')
|
t.is(await page.$text('.title'), 'You need to ask the permission')
|
||||||
t.deepEqual(await page.nuxt.errorData(), { message: 'You need to ask the permission', statusCode: 403 })
|
t.deepEqual(await page.nuxt.errorData(), { message: 'You need to ask the permission', statusCode: 403 })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/fn-midd?please=true', async t => {
|
test.serial('/fn-midd?please=true', async t => {
|
||||||
await page.nuxt.navigate('/fn-midd?please=true')
|
await page.nuxt.navigate('/fn-midd?please=true')
|
||||||
|
|
||||||
const h1 = await page.$text('h1')
|
const h1 = await page.$text('h1')
|
||||||
t.true(h1.includes('Date:'))
|
t.true(h1.includes('Date:'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
test.serial('/router-guard', async t => {
|
||||||
test.after('Closing server and nuxt.js', t => {
|
await page.nuxt.navigate('/router-guard')
|
||||||
nuxt.close()
|
|
||||||
|
t.is(await page.$text('p'), 'Nuxt.js')
|
||||||
})
|
})
|
||||||
|
|
||||||
test.after('Stop browser', async t => {
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
|
await nuxt.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
test.after.always('Stop browser', async t => {
|
||||||
await browser.stop()
|
await browser.stop()
|
||||||
})
|
})
|
||||||
|
@ -1,29 +1,85 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
// import rp from 'request-promise-native'
|
import { intercept, release } from './helpers/console'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder, Utils } from '..'
|
||||||
|
import { truncateSync, readFileSync, writeFileSync } from 'fs'
|
||||||
|
|
||||||
const port = 4001
|
const port = 4001
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
const rootDir = resolve(__dirname, 'fixtures/basic')
|
||||||
|
const pluginPath = resolve(rootDir, 'plugins', 'watch.js')
|
||||||
|
const pluginContent = readFileSync(pluginPath)
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir,
|
||||||
dev: true
|
buildDir: '.nuxt-dev',
|
||||||
|
dev: true,
|
||||||
|
build: {
|
||||||
|
stats: false,
|
||||||
|
profile: true,
|
||||||
|
extractCSS: {
|
||||||
|
allChunks: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
'~/plugins/watch.js'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const spies = await intercept({ log: true, stderr: true }, async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(options)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(spies.log.calledWithMatch('DONE'))
|
||||||
|
t.true(spies.log.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateless', async t => {
|
test.serial('/extractCSS', async t => {
|
||||||
|
const window = await nuxt.renderAndGetWindow(url('/extractCSS'))
|
||||||
|
const html = window.document.head.innerHTML
|
||||||
|
t.true(html.includes('vendor.css'))
|
||||||
|
t.true(!html.includes('30px'))
|
||||||
|
t.is(window.getComputedStyle(window.document.body).getPropertyValue('font-size'), '30px')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('remove mixins in live reloading', async t => {
|
||||||
|
const spies = await intercept({ log: true, error: true, stderr: true })
|
||||||
|
await nuxt.renderRoute(url('/'))
|
||||||
|
t.true(spies.log.calledWith('I am mixin'))
|
||||||
|
|
||||||
|
truncateSync(pluginPath)
|
||||||
|
await new Promise(async (resolve, reject) => {
|
||||||
|
let waitTimes = 0
|
||||||
|
while (spies.log.neverCalledWithMatch(/Compiled successfully/)) {
|
||||||
|
if (waitTimes++ >= 20) {
|
||||||
|
t.fail('Dev server doesn\'t reload after 2000ms')
|
||||||
|
reject(Error())
|
||||||
|
}
|
||||||
|
await Utils.waitFor(100)
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
spies.log.reset()
|
||||||
|
|
||||||
|
await nuxt.renderRoute(url('/'))
|
||||||
|
t.true(spies.log.neverCalledWith('I am mixin'))
|
||||||
|
t.is(spies.error.getCall(0).args[0].statusCode, 404)
|
||||||
|
release()
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/stateless', async t => {
|
||||||
|
const spies = await intercept()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/stateless'))
|
const window = await nuxt.renderAndGetWindow(url('/stateless'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<h1>My component!</h1>'))
|
t.true(html.includes('<h1>My component!</h1>'))
|
||||||
|
t.true(spies.info.calledWithMatch('You are running Vue in development mode.'))
|
||||||
|
release()
|
||||||
})
|
})
|
||||||
|
|
||||||
// test('/_nuxt/test.hot-update.json should returns empty html', async t => {
|
// test('/_nuxt/test.hot-update.json should returns empty html', async t => {
|
||||||
@ -36,6 +92,7 @@ test('/stateless', async t => {
|
|||||||
// })
|
// })
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', async t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
|
writeFileSync(pluginPath, pluginContent)
|
||||||
await nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,22 +1,32 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder, Generator } from '../index.js'
|
import { Nuxt, Builder, Generator } from '..'
|
||||||
|
import { intercept } from './helpers/console'
|
||||||
|
|
||||||
test('Fail with routes() which throw an error', async t => {
|
test('Fail with routes() which throw an error', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
|
buildDir: '.nuxt-fail',
|
||||||
dev: false,
|
dev: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
|
},
|
||||||
generate: {
|
generate: {
|
||||||
async routes() {
|
async routes() {
|
||||||
throw new Error('Not today!')
|
throw new Error('Not today!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const spies = await intercept(async () => {
|
||||||
const nuxt = new Nuxt(options)
|
const nuxt = new Nuxt(options)
|
||||||
const builder = new Builder(nuxt)
|
const builder = new Builder(nuxt)
|
||||||
const generator = new Generator(nuxt, builder)
|
const generator = new Generator(nuxt, builder)
|
||||||
|
|
||||||
return generator.generate()
|
return generator.generate()
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
t.true(e.message === 'Not today!')
|
t.true(e.message === 'Not today!')
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
t.true(spies.log.calledWithMatch('DONE'))
|
||||||
|
t.true(spies.error.withArgs('Could not resolve routes').calledOnce)
|
||||||
})
|
})
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
import test from 'ava'
|
|
||||||
import { resolve } from 'path'
|
|
||||||
import { existsSync } from 'fs'
|
|
||||||
import http from 'http'
|
|
||||||
import serveStatic from 'serve-static'
|
|
||||||
import finalhandler from 'finalhandler'
|
|
||||||
import rp from 'request-promise-native'
|
|
||||||
import { Nuxt, Builder, Generator } from '../index.js'
|
|
||||||
|
|
||||||
const port = 4002
|
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
|
||||||
|
|
||||||
let nuxt = null
|
|
||||||
let server = null
|
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
|
||||||
test.before('Init Nuxt.js', async t => {
|
|
||||||
const rootDir = resolve(__dirname, 'fixtures/basic')
|
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
|
||||||
config.rootDir = rootDir
|
|
||||||
config.dev = false
|
|
||||||
config.generate.subFolders = false
|
|
||||||
|
|
||||||
nuxt = new Nuxt(config)
|
|
||||||
const builder = new Builder(nuxt)
|
|
||||||
const generator = new Generator(nuxt, builder)
|
|
||||||
try {
|
|
||||||
await generator.generate() // throw an error (of /validate route)
|
|
||||||
} catch (err) {
|
|
||||||
}
|
|
||||||
|
|
||||||
const serve = serveStatic(resolve(__dirname, 'fixtures/basic/dist'), { extensions: ['html'] })
|
|
||||||
server = http.createServer((req, res) => {
|
|
||||||
serve(req, res, finalhandler(req, res))
|
|
||||||
})
|
|
||||||
server.listen(port)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Check ready hook called', async t => {
|
|
||||||
t.true(nuxt.__hook_called__)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/stateless', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/stateless'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('<h1>My component!</h1>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/css', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/css'))
|
|
||||||
const element = window.document.querySelector('.red')
|
|
||||||
t.not(element, null)
|
|
||||||
t.is(element.textContent, 'This is red')
|
|
||||||
t.is(element.className, 'red')
|
|
||||||
t.is(window.getComputedStyle(element).color, 'red')
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/stateful', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/stateful'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('<div><p>The answer is 42</p></div>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/head', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/head'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
const metas = window.document.getElementsByTagName('meta')
|
|
||||||
t.is(window.document.title, 'My title')
|
|
||||||
t.is(metas[0].getAttribute('content'), 'my meta')
|
|
||||||
t.true(html.includes('<div><h1>I can haz meta tags</h1></div>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/async-data', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/async-data'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('<p>Nuxt.js</p>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/users/1', async t => {
|
|
||||||
const html = await rp(url('/users/1'))
|
|
||||||
t.true(html.includes('<h1>User: 1</h1>'))
|
|
||||||
t.true(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1.html')))
|
|
||||||
t.false(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1/index.html')))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/users/2', async t => {
|
|
||||||
const html = await rp(url('/users/2'))
|
|
||||||
t.true(html.includes('<h1>User: 2</h1>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/users/3 (payload given)', async t => {
|
|
||||||
const html = await rp(url('/users/3'))
|
|
||||||
t.true(html.includes('<h1>User: 3000</h1>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/users/4 -> Not found', async t => {
|
|
||||||
try {
|
|
||||||
await rp(url('/users/4'))
|
|
||||||
} catch (error) {
|
|
||||||
t.true(error.statusCode === 404)
|
|
||||||
t.true(error.response.body.includes('Cannot GET /users/4'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/validate should not be server-rendered', async t => {
|
|
||||||
const html = await rp(url('/validate'))
|
|
||||||
t.true(html.includes('<div id="__nuxt"></div>'))
|
|
||||||
t.true(html.includes('serverRendered:!1'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/validate -> should display a 404', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/validate'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('This page could not be found'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/validate?valid=true', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/validate?valid=true'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('I am valid</h1>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/redirect should not be server-rendered', async t => {
|
|
||||||
const html = await rp(url('/redirect'))
|
|
||||||
t.true(html.includes('<div id="__nuxt"></div>'))
|
|
||||||
t.true(html.includes('serverRendered:!1'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('/redirect -> check redirected source', async t => {
|
|
||||||
const window = await nuxt.renderAndGetWindow(url('/redirect'))
|
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
t.true(html.includes('<h1>Index page</h1>'))
|
|
||||||
})
|
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
|
||||||
test.after('Closing server', t => {
|
|
||||||
server.close()
|
|
||||||
})
|
|
@ -1,31 +1,39 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'fs'
|
||||||
|
import { remove } from 'fs-extra'
|
||||||
import http from 'http'
|
import http from 'http'
|
||||||
import serveStatic from 'serve-static'
|
import serveStatic from 'serve-static'
|
||||||
import finalhandler from 'finalhandler'
|
import finalhandler from 'finalhandler'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Nuxt, Builder, Generator } from '../index.js'
|
import { interceptLog, release } from './helpers/console'
|
||||||
|
import { Nuxt, Builder, Generator } from '..'
|
||||||
|
|
||||||
const port = 4002
|
const port = 4002
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
const rootDir = resolve(__dirname, 'fixtures/basic')
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
let server = null
|
let server = null
|
||||||
|
let generator = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const rootDir = resolve(__dirname, 'fixtures/basic')
|
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
|
config.buildDir = '.nuxt-generate'
|
||||||
config.dev = false
|
config.dev = false
|
||||||
|
config.build.stats = false
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
const builder = new Builder(nuxt)
|
const builder = new Builder(nuxt)
|
||||||
const generator = new Generator(nuxt, builder)
|
generator = new Generator(nuxt, builder)
|
||||||
try {
|
|
||||||
await generator.generate() // throw an error (of /validate route)
|
await generator.generate()
|
||||||
} catch (err) {
|
})
|
||||||
}
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
|
||||||
const serve = serveStatic(resolve(__dirname, 'fixtures/basic/dist'))
|
const serve = serveStatic(resolve(__dirname, 'fixtures/basic/dist'))
|
||||||
server = http.createServer((req, res) => {
|
server = http.createServer((req, res) => {
|
||||||
serve(req, res, finalhandler(req, res))
|
serve(req, res, finalhandler(req, res))
|
||||||
@ -33,17 +41,17 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
server.listen(port)
|
server.listen(port)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Check ready hook called', async t => {
|
test.serial('Check ready hook called', async t => {
|
||||||
t.true(nuxt.__hook_called__)
|
t.true(nuxt.__hook_called__)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateless', async t => {
|
test.serial('/stateless', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/stateless'))
|
const window = await nuxt.renderAndGetWindow(url('/stateless'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<h1>My component!</h1>'))
|
t.true(html.includes('<h1>My component!</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/css', async t => {
|
test.serial('/css', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/css'))
|
const window = await nuxt.renderAndGetWindow(url('/css'))
|
||||||
const element = window.document.querySelector('.red')
|
const element = window.document.querySelector('.red')
|
||||||
t.not(element, null)
|
t.not(element, null)
|
||||||
@ -52,84 +60,106 @@ test('/css', async t => {
|
|||||||
t.is(window.getComputedStyle(element).color, 'red')
|
t.is(window.getComputedStyle(element).color, 'red')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateful', async t => {
|
test.serial('/stateful', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/stateful'))
|
const window = await nuxt.renderAndGetWindow(url('/stateful'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<div><p>The answer is 42</p></div>'))
|
t.true(html.includes('<div><p>The answer is 42</p></div>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/head', async t => {
|
test.serial('/head', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/head'))
|
const window = await nuxt.renderAndGetWindow(url('/head'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
const metas = window.document.getElementsByTagName('meta')
|
const metas = window.document.getElementsByTagName('meta')
|
||||||
t.is(window.document.title, 'My title')
|
t.is(window.document.title, 'My title')
|
||||||
t.is(metas[0].getAttribute('content'), 'my meta')
|
t.is(metas[0].getAttribute('content'), 'my meta')
|
||||||
t.true(html.includes('<div><h1>I can haz meta tags</h1></div>'))
|
t.true(html.includes('<div><h1>I can haz meta tags</h1></div>'))
|
||||||
|
release()
|
||||||
|
t.is(logSpy.getCall(0).args[0], 'Body script!')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/async-data', async t => {
|
test.serial('/async-data', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/async-data'))
|
const window = await nuxt.renderAndGetWindow(url('/async-data'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<p>Nuxt.js</p>'))
|
t.true(html.includes('<p>Nuxt.js</p>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/users/1', async t => {
|
test.serial('/users/1/index.html', async t => {
|
||||||
const html = await rp(url('/users/1'))
|
const html = await rp(url('/users/1/index.html'))
|
||||||
t.true(html.includes('<h1>User: 1</h1>'))
|
t.true(html.includes('<h1>User: 1</h1>'))
|
||||||
t.true(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1/index.html')))
|
t.true(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1/index.html')))
|
||||||
t.false(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1.html')))
|
t.false(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1.html')))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/users/2', async t => {
|
test.serial('/users/2', async t => {
|
||||||
const html = await rp(url('/users/2'))
|
const html = await rp(url('/users/2'))
|
||||||
t.true(html.includes('<h1>User: 2</h1>'))
|
t.true(html.includes('<h1>User: 2</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/users/3 (payload given)', async t => {
|
test.serial('/users/3 (payload given)', async t => {
|
||||||
const html = await rp(url('/users/3'))
|
const html = await rp(url('/users/3'))
|
||||||
t.true(html.includes('<h1>User: 3000</h1>'))
|
t.true(html.includes('<h1>User: 3000</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/users/4 -> Not found', async t => {
|
test.serial('/users/4 -> Not found', async t => {
|
||||||
try {
|
const error = await t.throws(rp(url('/users/4')))
|
||||||
await rp(url('/users/4'))
|
|
||||||
} catch (error) {
|
|
||||||
t.true(error.statusCode === 404)
|
t.true(error.statusCode === 404)
|
||||||
t.true(error.response.body.includes('Cannot GET /users/4'))
|
t.true(error.response.body.includes('Cannot GET /users/4'))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/validate should not be server-rendered', async t => {
|
test.serial('/validate should not be server-rendered', async t => {
|
||||||
const html = await rp(url('/validate'))
|
const html = await rp(url('/validate'))
|
||||||
t.true(html.includes('<div id="__nuxt"></div>'))
|
t.true(html.includes('<div id="__nuxt"></div>'))
|
||||||
t.true(html.includes('serverRendered:!1'))
|
t.true(html.includes('serverRendered:!1'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/validate -> should display a 404', async t => {
|
test.serial('/validate -> should display a 404', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/validate'))
|
const window = await nuxt.renderAndGetWindow(url('/validate'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('This page could not be found'))
|
t.true(html.includes('This page could not be found'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/validate?valid=true', async t => {
|
test.serial('/validate?valid=true', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/validate?valid=true'))
|
const window = await nuxt.renderAndGetWindow(url('/validate?valid=true'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('I am valid</h1>'))
|
t.true(html.includes('I am valid</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect should not be server-rendered', async t => {
|
test.serial('/redirect should not be server-rendered', async t => {
|
||||||
const html = await rp(url('/redirect'))
|
const html = await rp(url('/redirect'))
|
||||||
t.true(html.includes('<div id="__nuxt"></div>'))
|
t.true(html.includes('<div id="__nuxt"></div>'))
|
||||||
t.true(html.includes('serverRendered:!1'))
|
t.true(html.includes('serverRendered:!1'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect -> check redirected source', async t => {
|
test.serial('/redirect -> check redirected source', async t => {
|
||||||
const window = await nuxt.renderAndGetWindow(url('/redirect'))
|
const window = await nuxt.renderAndGetWindow(url('/redirect'))
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<h1>Index page</h1>'))
|
t.true(html.includes('<h1>Index page</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
test.serial('/users/1 not found', async t => {
|
||||||
test.after('Closing server', t => {
|
await remove(resolve(rootDir, 'dist/users'))
|
||||||
server.close()
|
const error = await t.throws(rp(url('/users/1')))
|
||||||
|
t.true(error.statusCode === 404)
|
||||||
|
t.true(error.response.body.includes('Cannot GET /users/1'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('nuxt re-generating with no subfolders', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
|
nuxt.options.generate.subFolders = false
|
||||||
|
await generator.generate()
|
||||||
|
release()
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/users/1.html', async t => {
|
||||||
|
const html = await rp(url('/users/1.html'))
|
||||||
|
t.true(html.includes('<h1>User: 1</h1>'))
|
||||||
|
t.true(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1.html')))
|
||||||
|
t.false(existsSync(resolve(__dirname, 'fixtures/basic/dist', 'users/1/index.html')))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
|
test.after.always('Closing server', async t => {
|
||||||
|
await server.close()
|
||||||
})
|
})
|
||||||
|
@ -1,29 +1,39 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import stdMocks from 'std-mocks'
|
import { Nuxt, Builder } from '..'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { interceptLog, interceptError, release } from './helpers/console'
|
||||||
|
|
||||||
const port = 4003
|
const port = 4004
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4003
|
// Init nuxt.js and create server listening on localhost:4003
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
|
buildDir: '.nuxt-ssr',
|
||||||
dev: false,
|
dev: false,
|
||||||
head: {
|
head: {
|
||||||
titleTemplate(titleChunk) {
|
titleTemplate(titleChunk) {
|
||||||
return titleChunk ? `${titleChunk} - Nuxt.js` : 'Nuxt.js'
|
return titleChunk ? `${titleChunk} - Nuxt.js` : 'Nuxt.js'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nuxt = new Nuxt(options)
|
|
||||||
await new Builder(nuxt).build()
|
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
const logSpy = await interceptLog(async () => {
|
||||||
|
nuxt = new Nuxt(options)
|
||||||
|
const builder = await new Builder(nuxt)
|
||||||
|
await builder.build()
|
||||||
|
await nuxt.listen(port, '0.0.0.0')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/stateless', async t => {
|
test('/stateless', async t => {
|
||||||
@ -60,18 +70,21 @@ test('/store', async t => {
|
|||||||
t.true(html.includes('<p>1</p>'))
|
t.true(html.includes('<p>1</p>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/head', async t => {
|
test.serial('/head', async t => {
|
||||||
stdMocks.use()
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/head'), { virtualConsole: false })
|
const window = await nuxt.renderAndGetWindow(url('/head'), { virtualConsole: false })
|
||||||
const html = window.document.body.innerHTML
|
|
||||||
const metas = window.document.getElementsByTagName('meta')
|
|
||||||
stdMocks.restore()
|
|
||||||
const { stdout } = stdMocks.flush()
|
|
||||||
t.is(stdout[0], 'Body script!\n')
|
|
||||||
t.is(window.document.title, 'My title - Nuxt.js')
|
t.is(window.document.title, 'My title - Nuxt.js')
|
||||||
t.is(metas[0].getAttribute('content'), 'my meta')
|
|
||||||
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<div><h1>I can haz meta tags</h1></div>'))
|
t.true(html.includes('<div><h1>I can haz meta tags</h1></div>'))
|
||||||
t.true(html.includes('<script data-n-head="true" src="/body.js" data-body="true">'))
|
t.true(html.includes('<script data-n-head="true" src="/body.js" data-body="true">'))
|
||||||
|
|
||||||
|
const metas = window.document.getElementsByTagName('meta')
|
||||||
|
t.is(metas[0].getAttribute('content'), 'my meta')
|
||||||
|
release()
|
||||||
|
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Body script!')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/async-data', async t => {
|
test('/async-data', async t => {
|
||||||
@ -119,7 +132,7 @@ test('/redirect -> check redirected source', async t => {
|
|||||||
|
|
||||||
test('/redirect -> external link', async t => {
|
test('/redirect -> external link', async t => {
|
||||||
const headers = {}
|
const headers = {}
|
||||||
const { html } = await nuxt.renderRoute('/redirect3', {
|
const { html } = await nuxt.renderRoute('/redirect-external', {
|
||||||
res: {
|
res: {
|
||||||
setHeader(k, v) {
|
setHeader(k, v) {
|
||||||
headers[k] = v
|
headers[k] = v
|
||||||
@ -137,20 +150,18 @@ test('/special-state -> check window.__NUXT__.test = true', async t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('/error', async t => {
|
test('/error', async t => {
|
||||||
try {
|
const err = await t.throws(nuxt.renderRoute('/error', { req: {}, res: {} }))
|
||||||
await nuxt.renderRoute('/error', { req: {}, res: {} })
|
|
||||||
} catch (err) {
|
|
||||||
t.true(err.message.includes('Error mouahahah'))
|
t.true(err.message.includes('Error mouahahah'))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error status code', async t => {
|
test.serial('/error status code', async t => {
|
||||||
try {
|
const errorSpy = await interceptError()
|
||||||
await rp(url('/error'))
|
const err = await t.throws(rp(url('/error')))
|
||||||
} catch (err) {
|
|
||||||
t.true(err.statusCode === 500)
|
t.true(err.statusCode === 500)
|
||||||
t.true(err.response.body.includes('An error occurred in the application and your page could not be served'))
|
t.true(err.response.body.includes('An error occurred in the application and your page could not be served'))
|
||||||
}
|
release()
|
||||||
|
t.true(errorSpy.calledOnce)
|
||||||
|
t.true(errorSpy.args[0][0].message.includes('Error mouahahah'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error2', async t => {
|
test('/error2', async t => {
|
||||||
@ -161,35 +172,34 @@ test('/error2', async t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('/error2 status code', async t => {
|
test('/error2 status code', async t => {
|
||||||
try {
|
const error = await t.throws(rp(url('/error2')))
|
||||||
await rp(url('/error2'))
|
t.is(error.statusCode, 500)
|
||||||
} catch (err) {
|
t.true(error.response.body.includes('Custom error'))
|
||||||
t.is(err.statusCode, 500)
|
|
||||||
t.true(err.response.body.includes('Custom error'))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/error-midd', async t => {
|
test.serial('/error-midd', async t => {
|
||||||
stdMocks.use()
|
const errorSpy = await interceptError()
|
||||||
try {
|
const err = await t.throws(rp(url('/error-midd')))
|
||||||
await rp(url('/error-midd'))
|
|
||||||
} catch (err) {
|
|
||||||
stdMocks.restore()
|
|
||||||
t.is(err.statusCode, 505)
|
t.is(err.statusCode, 505)
|
||||||
t.true(err.response.body.includes('Middleware Error'))
|
t.true(err.response.body.includes('Middleware Error'))
|
||||||
const output = stdMocks.flush()
|
release()
|
||||||
// Don't display error since redirect returns a noopApp
|
// Don't display error since redirect returns a noopApp
|
||||||
t.true(output.stderr.length === 0)
|
t.true(errorSpy.notCalled)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/redirect2', async t => {
|
test.serial('/redirect-middleware', async t => {
|
||||||
stdMocks.use()
|
const errorSpy = await interceptError()
|
||||||
await rp(url('/redirect2')) // Should not console.error
|
await rp(url('/redirect-middleware')) // Should not console.error
|
||||||
stdMocks.restore()
|
release()
|
||||||
const output = stdMocks.flush()
|
|
||||||
// Don't display error since redirect returns a noopApp
|
// Don't display error since redirect returns a noopApp
|
||||||
t.true(output.stderr.length === 0)
|
t.true(errorSpy.notCalled)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('/redirect-name', async t => {
|
||||||
|
const { html, redirected } = await nuxt.renderRoute('/redirect-name')
|
||||||
|
t.true(html.includes('<div id="__nuxt"></div>'))
|
||||||
|
t.true(redirected.path === '/stateless')
|
||||||
|
t.true(redirected.status === 302)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/no-ssr', async t => {
|
test('/no-ssr', async t => {
|
||||||
@ -224,7 +234,6 @@ test('/_nuxt/ should return 404', async t => {
|
|||||||
|
|
||||||
test('/meta', async t => {
|
test('/meta', async t => {
|
||||||
const { html } = await nuxt.renderRoute('/meta')
|
const { html } = await nuxt.renderRoute('/meta')
|
||||||
|
|
||||||
t.true(html.includes('"meta":[{"works":true}]'))
|
t.true(html.includes('"meta":[{"works":true}]'))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -239,7 +248,23 @@ test('/fn-midd?please=true', async t => {
|
|||||||
t.true(html.includes('<h1>Date:'))
|
t.true(html.includes('<h1>Date:'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
test('/router-guard', async t => {
|
||||||
test.after('Closing server and nuxt.js', t => {
|
const { html } = await nuxt.renderRoute('/router-guard')
|
||||||
nuxt.close()
|
t.true(html.includes('<p>Nuxt.js</p>'))
|
||||||
|
t.false(html.includes('Router Guard'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('/jsx', async t => {
|
||||||
|
const { html } = await nuxt.renderRoute('/jsx')
|
||||||
|
t.true(html.includes('<h1>JSX Page</h1>'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('/js-link', async t => {
|
||||||
|
const { html } = await nuxt.renderRoute('/js-link')
|
||||||
|
t.true(html.includes('<h1>vue file is first-class</h1>'))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,35 +1,46 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder, Utils } from '../index.js'
|
import { Nuxt, Builder, Utils } from '..'
|
||||||
import * as browser from './helpers/browser'
|
import * as browser from './helpers/browser'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const port = 4005
|
const port = 4014
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
let page
|
||||||
|
const dates = {}
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/children'),
|
rootDir: resolve(__dirname, 'fixtures/children'),
|
||||||
dev: false
|
buildDir: '.nuxt-patch',
|
||||||
|
dev: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(options)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
test.before('Start browser', async t => {
|
|
||||||
|
test.serial('Start browser', async t => {
|
||||||
|
t.plan(0) // suppress 'no assertions' warning
|
||||||
await browser.start({
|
await browser.start({
|
||||||
// slowMo: 50,
|
// slowMo: 50,
|
||||||
// headless: false
|
// headless: false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let page
|
test.serial('Loading /patch and keep ', async t => {
|
||||||
const dates = {}
|
|
||||||
|
|
||||||
test('Loading /patch and keep ', async t => {
|
|
||||||
page = await browser.page(url('/patch'))
|
page = await browser.page(url('/patch'))
|
||||||
|
|
||||||
const h1 = await page.$text('h1')
|
const h1 = await page.$text('h1')
|
||||||
@ -39,7 +50,7 @@ test('Loading /patch and keep ', async t => {
|
|||||||
dates.patch = await page.$text('[data-date-patch]')
|
dates.patch = await page.$text('[data-date-patch]')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/1', async t => {
|
test.serial('Navigate to /patch/1', async t => {
|
||||||
const { hook } = await page.nuxt.navigate('/patch/1', false)
|
const { hook } = await page.nuxt.navigate('/patch/1', false)
|
||||||
const loading = await page.nuxt.loadingData()
|
const loading = await page.nuxt.loadingData()
|
||||||
t.is(loading.show, true)
|
t.is(loading.show, true)
|
||||||
@ -52,7 +63,7 @@ test('Navigate to /patch/1', async t => {
|
|||||||
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2', async t => {
|
test.serial('Navigate to /patch/2', async t => {
|
||||||
await page.nuxt.navigate('/patch/2')
|
await page.nuxt.navigate('/patch/2')
|
||||||
const date = await page.$text('[data-date-id]')
|
const date = await page.$text('[data-date-id]')
|
||||||
|
|
||||||
@ -62,19 +73,19 @@ test('Navigate to /patch/2', async t => {
|
|||||||
dates.id = date
|
dates.id = date
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2?test=true', async t => {
|
test.serial('Navigate to /patch/2?test=true', async t => {
|
||||||
await page.nuxt.navigate('/patch/2?test=true')
|
await page.nuxt.navigate('/patch/2?test=true')
|
||||||
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
||||||
t.is(dates.id, await page.$text('[data-date-id]'))
|
t.is(dates.id, await page.$text('[data-date-id]'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2#test', async t => {
|
test.serial('Navigate to /patch/2#test', async t => {
|
||||||
await page.nuxt.navigate('/patch/2#test')
|
await page.nuxt.navigate('/patch/2#test')
|
||||||
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
||||||
t.is(dates.id, await page.$text('[data-date-id]'))
|
t.is(dates.id, await page.$text('[data-date-id]'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2/child', async t => {
|
test.serial('Navigate to /patch/2/child', async t => {
|
||||||
await page.nuxt.navigate('/patch/2/child')
|
await page.nuxt.navigate('/patch/2/child')
|
||||||
dates.child = await page.$text('[data-date-child]')
|
dates.child = await page.$text('[data-date-child]')
|
||||||
dates.slug = await page.$text('[data-date-child-slug]')
|
dates.slug = await page.$text('[data-date-child-slug]')
|
||||||
@ -85,7 +96,7 @@ test('Navigate to /patch/2/child', async t => {
|
|||||||
t.true(+dates.slug > +dates.child)
|
t.true(+dates.slug > +dates.child)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2/child/1', async t => {
|
test.serial('Navigate to /patch/2/child/1', async t => {
|
||||||
await page.nuxt.navigate('/patch/2/child/1')
|
await page.nuxt.navigate('/patch/2/child/1')
|
||||||
const date = await page.$text('[data-date-child-slug]')
|
const date = await page.$text('[data-date-child-slug]')
|
||||||
|
|
||||||
@ -96,7 +107,7 @@ test('Navigate to /patch/2/child/1', async t => {
|
|||||||
dates.slug = date
|
dates.slug = date
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Navigate to /patch/2/child/1?foo=bar', async t => {
|
test.serial('Navigate to /patch/2/child/1?foo=bar', async t => {
|
||||||
await page.nuxt.navigate('/patch/2/child/1?foo=bar')
|
await page.nuxt.navigate('/patch/2/child/1?foo=bar')
|
||||||
|
|
||||||
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
t.is(dates.patch, await page.$text('[data-date-patch]'))
|
||||||
@ -105,7 +116,7 @@ test('Navigate to /patch/2/child/1?foo=bar', async t => {
|
|||||||
t.is(dates.slug, await page.$text('[data-date-child-slug]'))
|
t.is(dates.slug, await page.$text('[data-date-child-slug]'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Search a country', async t => {
|
test.serial('Search a country', async t => {
|
||||||
const countries = await page.$$text('[data-test-search-result]')
|
const countries = await page.$$text('[data-test-search-result]')
|
||||||
t.is(countries.length, 5)
|
t.is(countries.length, 5)
|
||||||
|
|
||||||
@ -125,10 +136,11 @@ test('Search a country', async t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
test.after('Stop browser', async t => {
|
|
||||||
|
test.after.always('Stop browser', async t => {
|
||||||
await page.close()
|
await page.close()
|
||||||
await browser.stop()
|
await browser.stop()
|
||||||
})
|
})
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const port = 4004
|
const port = 4013
|
||||||
// const url = (route) => 'http://localhost:' + port + route
|
// const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/children'),
|
rootDir: resolve(__dirname, 'fixtures/children'),
|
||||||
dev: false
|
dev: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(options)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/parent', async t => {
|
test('/parent', async t => {
|
||||||
@ -54,6 +63,6 @@ test('/parent/validate-child?key=12345', async t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
|
import { promisify } from 'util'
|
||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve, sep } from 'path'
|
import { resolve, sep } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Utils } from '../index.js'
|
|
||||||
import pify from 'pify'
|
|
||||||
import { exec, spawn } from 'child_process'
|
import { exec, spawn } from 'child_process'
|
||||||
|
import { Utils } from '..'
|
||||||
|
|
||||||
const execify = pify(exec, { multiArgs: true })
|
const execify = promisify(exec)
|
||||||
const rootDir = resolve(__dirname, 'fixtures/basic')
|
const rootDir = resolve(__dirname, 'fixtures/basic')
|
||||||
|
|
||||||
const port = 4011
|
const port = 4011
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
test('bin/nuxt-build', async t => {
|
test.serial('bin/nuxt-build', async t => {
|
||||||
const binBuild = resolve(__dirname, '..', 'bin', 'nuxt-build')
|
const binBuild = resolve(__dirname, '..', 'bin', 'nuxt-build')
|
||||||
|
|
||||||
const [ stdout, stderr ] = await execify(`node ${binBuild} ${rootDir}`)
|
const { stdout, stderr } = await execify(`node ${binBuild} ${rootDir}`)
|
||||||
|
|
||||||
t.true(stdout.includes('server-bundle.json'))
|
t.true(stdout.includes('server-bundle.json'))
|
||||||
t.true(stderr.includes('Building done'))
|
t.true(stderr.includes('Building done'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('bin/nuxt-start', async t => {
|
test.serial('bin/nuxt-start', async t => {
|
||||||
const binStart = resolve(__dirname, '..', 'bin', 'nuxt-start')
|
const binStart = resolve(__dirname, '..', 'bin', 'nuxt-start')
|
||||||
|
|
||||||
let stdout = ''
|
let stdout = ''
|
||||||
@ -79,10 +79,10 @@ test('bin/nuxt-start', async t => {
|
|||||||
t.is(exitCode, null)
|
t.is(exitCode, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('bin/nuxt-generate', async t => {
|
test.serial('bin/nuxt-generate', async t => {
|
||||||
const binGenerate = resolve(__dirname, '..', 'bin', 'nuxt-generate')
|
const binGenerate = resolve(__dirname, '..', 'bin', 'nuxt-generate')
|
||||||
|
|
||||||
const [ stdout, stderr ] = await execify(`node ${binGenerate} ${rootDir}`)
|
const { stdout, stderr } = await execify(`node ${binGenerate} ${rootDir}`)
|
||||||
|
|
||||||
t.true(stdout.includes('server-bundle.json'))
|
t.true(stdout.includes('server-bundle.json'))
|
||||||
t.true(stderr.includes('Destination folder cleaned'))
|
t.true(stderr.includes('Destination folder cleaned'))
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { interceptLog, interceptError, release } from './helpers/console'
|
||||||
|
|
||||||
const port = 4009
|
const port = 4009
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
@ -9,36 +10,87 @@ const url = (route) => 'http://localhost:' + port + route
|
|||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const rootDir = resolve(__dirname, 'fixtures/debug')
|
const rootDir = resolve(__dirname, 'fixtures/debug')
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/_open (open-in-editor)', async t => {
|
test.serial('/test/_open (open-in-editor)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { body } = await rp(url('/test/_open?file=pages/index.vue'), { resolveWithFullResponse: true })
|
const { body } = await rp(url('/test/_open?file=pages/index.vue'), { resolveWithFullResponse: true })
|
||||||
t.is(body, 'opened in editor!')
|
t.is(body, 'opened in editor!')
|
||||||
|
release()
|
||||||
|
t.is(logSpy.getCall(0).args[0], '[open in editor]')
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/_open should return error (open-in-editor)', async t => {
|
test.serial('/test/_open should return error (open-in-editor)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { body } = await rp(url('/test/_open?file='), { resolveWithFullResponse: true })
|
const { body } = await rp(url('/test/_open?file='), { resolveWithFullResponse: true })
|
||||||
t.is(body, 'File is not specified')
|
t.is(body, 'File is not specified')
|
||||||
|
release()
|
||||||
|
t.is(logSpy.getCall(0).args[0], '[open in editor]')
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/error should return error stack trace (Youch)', async t => {
|
test.serial('/test/error should return error stack trace (Youch)', async t => {
|
||||||
|
const errorSpy = await interceptError()
|
||||||
const { response, error } = await t.throws(nuxt.renderAndGetWindow(url('/test/error')))
|
const { response, error } = await t.throws(nuxt.renderAndGetWindow(url('/test/error')))
|
||||||
t.is(response.statusCode, 500)
|
t.is(response.statusCode, 500)
|
||||||
t.is(response.statusMessage, 'NuxtServerError')
|
t.is(response.statusMessage, 'NuxtServerError')
|
||||||
t.true(error.includes('test youch !'))
|
t.true(error.includes('test youch !'))
|
||||||
t.true(error.includes('<div class="error-frames">'))
|
t.true(error.includes('<div class="error-frames">'))
|
||||||
|
release()
|
||||||
|
t.true(errorSpy.calledTwice)
|
||||||
|
t.true(errorSpy.getCall(0).args[0].includes('test youch !'))
|
||||||
|
t.true(errorSpy.getCall(1).args[0].message.includes('test youch !'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/test/error no source-map (Youch)', async t => {
|
||||||
|
const sourceMaps = nuxt.renderer.resources.serverBundle.maps
|
||||||
|
nuxt.renderer.resources.serverBundle.maps = {}
|
||||||
|
|
||||||
|
const errorSpy = await interceptError()
|
||||||
|
const { response, error } = await t.throws(nuxt.renderAndGetWindow(url('/test/error')))
|
||||||
|
t.is(response.statusCode, 500)
|
||||||
|
t.is(response.statusMessage, 'NuxtServerError')
|
||||||
|
t.true(error.includes('test youch !'))
|
||||||
|
t.true(error.includes('<div class="error-frames">'))
|
||||||
|
release()
|
||||||
|
t.true(errorSpy.calledTwice)
|
||||||
|
t.true(errorSpy.getCall(0).args[0].includes('test youch !'))
|
||||||
|
t.true(errorSpy.getCall(1).args[0].message.includes('test youch !'))
|
||||||
|
|
||||||
|
nuxt.renderer.resources.serverBundle.maps = sourceMaps
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/test/error should return json format error (Youch)', async t => {
|
||||||
|
const opts = {
|
||||||
|
headers: {
|
||||||
|
'accept': 'application/json'
|
||||||
|
},
|
||||||
|
resolveWithFullResponse: true
|
||||||
|
}
|
||||||
|
const errorSpy = await interceptError()
|
||||||
|
const { response: { headers } } = await t.throws(rp(url('/test/error'), opts))
|
||||||
|
t.is(headers['content-type'], 'text/json; charset=utf-8')
|
||||||
|
release()
|
||||||
|
t.true(errorSpy.calledTwice)
|
||||||
|
t.true(errorSpy.getCall(0).args[0].includes('test youch !'))
|
||||||
|
t.true(errorSpy.getCall(1).args[0].message.includes('test youch !'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,55 +1,52 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import stdMocks from 'std-mocks'
|
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { intercept, interceptWarn, release } from './helpers/console'
|
||||||
|
|
||||||
const port = 4010
|
const port = 4010
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
let builder = null
|
let builder = null
|
||||||
let builtErr = null
|
let buildSpies = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const rootDir = resolve(__dirname, 'fixtures/deprecate')
|
const rootDir = resolve(__dirname, 'fixtures/deprecate')
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
|
|
||||||
|
buildSpies = await intercept(async () => {
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
builder = new Builder(nuxt)
|
builder = await new Builder(nuxt)
|
||||||
|
|
||||||
stdMocks.use({
|
|
||||||
stdout: false,
|
|
||||||
stderr: true
|
|
||||||
})
|
|
||||||
await builder.build()
|
await builder.build()
|
||||||
stdMocks.restore()
|
|
||||||
builtErr = stdMocks.flush().stderr
|
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(buildSpies.log.calledWithMatch('DONE'))
|
||||||
|
t.true(buildSpies.log.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Deprecated: context.isServer and context.isClient', async t => {
|
test.serial('Deprecated: context.isServer and context.isClient', async t => {
|
||||||
stdMocks.use()
|
const warnSpy = await interceptWarn()
|
||||||
await rp(url('/'))
|
await rp(url('/'))
|
||||||
stdMocks.restore()
|
t.true(warnSpy.calledWith('context.isServer has been deprecated, please use process.server instead.'))
|
||||||
const output = stdMocks.flush()
|
t.true(warnSpy.calledWith('context.isClient has been deprecated, please use process.client instead.'))
|
||||||
t.true(output.stderr.length === 2)
|
t.true(warnSpy.calledTwice)
|
||||||
|
release()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Deprecated: dev in build.extend()', async t => {
|
test.serial('Deprecated: dev in build.extend()', async t => {
|
||||||
const deprecatedMsg = 'dev has been deprecated in build.extend(), please use isDev'
|
t.true(buildSpies.warn.withArgs('dev has been deprecated in build.extend(), please use isDev').calledTwice)
|
||||||
const errors = builtErr.filter(value => value.indexOf(deprecatedMsg) === 0)
|
|
||||||
t.true(errors.length === 2)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Deprecated: nuxt.plugin()', async t => {
|
test.serial('Deprecated: nuxt.plugin()', async t => {
|
||||||
t.true(nuxt.__builder_plugin)
|
t.true(nuxt.__builder_plugin)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
import { promisify } from 'util'
|
||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import pify from 'pify'
|
import { Nuxt, Builder } from '..'
|
||||||
import stdMocks from 'std-mocks'
|
import { interceptLog, release } from './helpers/console'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
|
||||||
|
|
||||||
const readFile = pify(fs.readFile)
|
const readFile = promisify(fs.readFile)
|
||||||
const rootDir = resolve(__dirname, './fixtures/dll')
|
const rootDir = resolve(__dirname, 'fixtures/dll')
|
||||||
const dllDir = resolve(rootDir, '.cache/client-dll')
|
const dllDir = resolve(rootDir, '.cache/client-dll')
|
||||||
|
|
||||||
const checkCache = (lib) => {
|
const checkCache = (lib) => {
|
||||||
@ -19,12 +19,16 @@ const checkCache = (lib) => {
|
|||||||
|
|
||||||
let nuxt
|
let nuxt
|
||||||
|
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = true
|
config.dev = true
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
})
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Check vue cache', checkCache('vue'))
|
test('Check vue cache', checkCache('vue'))
|
||||||
@ -34,15 +38,13 @@ test('Check vue-meta cache', checkCache('vue-meta'))
|
|||||||
test('Check vue-router cache', checkCache('vue-router'))
|
test('Check vue-router cache', checkCache('vue-router'))
|
||||||
|
|
||||||
test('Build with DllReferencePlugin', async t => {
|
test('Build with DllReferencePlugin', async t => {
|
||||||
stdMocks.use()
|
const logSpy = await interceptLog()
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
stdMocks.restore()
|
release()
|
||||||
const output = stdMocks.flush()
|
t.true(logSpy.withArgs('Using dll for 3 libs').calledOnce)
|
||||||
const dllLog = output.stdout.filter(value => value === 'Using dll for 3 libs\n')
|
|
||||||
t.true(dllLog.length === 1)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing nuxt.js', t => {
|
test.after.always('Closing nuxt.js', t => {
|
||||||
nuxt.close()
|
nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,17 +1,26 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import pify from 'pify'
|
import { Nuxt, Builder } from '..'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { promisify } from 'util'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const readFile = pify(fs.readFile)
|
const readFile = promisify(fs.readFile)
|
||||||
|
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const nuxt = new Nuxt({
|
const config = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/dynamic-routes'),
|
rootDir: resolve(__dirname, 'fixtures/dynamic-routes'),
|
||||||
dev: false
|
dev: false,
|
||||||
})
|
build: {
|
||||||
|
stats: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
|
const nuxt = new Nuxt(config)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
})
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Check .nuxt/router.js', t => {
|
test('Check .nuxt/router.js', t => {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import rp from 'request-promise-native'
|
||||||
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { interceptLog, interceptError, release } from './helpers/console'
|
||||||
|
|
||||||
const port = 4005
|
const port = 4005
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
@ -8,37 +10,61 @@ const url = (route) => 'http://localhost:' + port + route
|
|||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/error'),
|
rootDir: resolve(__dirname, 'fixtures/error'),
|
||||||
dev: false
|
dev: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(options)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/ should display an error', async t => {
|
test.serial('/ should display an error', async t => {
|
||||||
try {
|
const error = await t.throws(nuxt.renderRoute('/'))
|
||||||
await nuxt.renderRoute('/')
|
t.true(error.message.includes('not_defined is not defined'))
|
||||||
} catch (e) {
|
|
||||||
t.true(e.message.includes('not_defined is not defined'))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/404 should display an error too', async t => {
|
test.serial('/404 should display an error too', async t => {
|
||||||
let { error } = await nuxt.renderRoute('/404')
|
let { error } = await nuxt.renderRoute('/404')
|
||||||
t.true(error.message.includes('This page could not be found'))
|
t.true(error.message.includes('This page could not be found'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/ with renderAndGetWindow()', async t => {
|
test.serial('/ with renderAndGetWindow()', async t => {
|
||||||
|
const errorSpy = await interceptError()
|
||||||
const err = await t.throws(nuxt.renderAndGetWindow(url('/')))
|
const err = await t.throws(nuxt.renderAndGetWindow(url('/')))
|
||||||
t.is(err.response.statusCode, 500)
|
t.is(err.response.statusCode, 500)
|
||||||
t.is(err.response.statusMessage, 'NuxtServerError')
|
t.is(err.response.statusMessage, 'NuxtServerError')
|
||||||
|
release()
|
||||||
|
t.true(errorSpy.calledOnce)
|
||||||
|
t.true(errorSpy.getCall(0).args[0].message.includes('render function or template not defined in component: anonymous'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('/ with text/json content', async t => {
|
||||||
|
const opts = {
|
||||||
|
headers: {
|
||||||
|
'accept': 'application/json'
|
||||||
|
},
|
||||||
|
resolveWithFullResponse: true
|
||||||
|
}
|
||||||
|
const errorSpy = await interceptError()
|
||||||
|
const { response: { headers } } = await t.throws(rp(url('/'), opts))
|
||||||
|
t.is(headers['content-type'], 'text/json; charset=utf-8')
|
||||||
|
release()
|
||||||
|
t.true(errorSpy.calledOnce)
|
||||||
|
t.true(errorSpy.getCall(0).args[0].message.includes('render function or template not defined in component: anonymous'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const port = 4000
|
const port = 4000
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
@ -11,17 +12,21 @@ let nuxt
|
|||||||
let app
|
let app
|
||||||
|
|
||||||
// Init nuxt.js and create express server
|
// Init nuxt.js and create express server
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const config = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
dev: false
|
buildDir: '.nuxt-express',
|
||||||
|
dev: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create nuxt instace
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(options)
|
nuxt = new Nuxt(config)
|
||||||
|
|
||||||
// Build
|
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
|
})
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
|
||||||
// Create express app
|
// Create express app
|
||||||
app = express()
|
app = express()
|
||||||
|
1
test/fixtures/basic/nuxt.config.js
vendored
1
test/fixtures/basic/nuxt.config.js
vendored
@ -20,6 +20,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
transition: false,
|
transition: false,
|
||||||
build: {
|
build: {
|
||||||
|
scopeHoisting: true,
|
||||||
postcss: [
|
postcss: [
|
||||||
require('postcss-cssnext')()
|
require('postcss-cssnext')()
|
||||||
]
|
]
|
||||||
|
9
test/fixtures/basic/pages/extractCSS.vue
vendored
Normal file
9
test/fixtures/basic/pages/extractCSS.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
2
test/fixtures/basic/pages/js-link.js
vendored
Normal file
2
test/fixtures/basic/pages/js-link.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export default {
|
||||||
|
}
|
5
test/fixtures/basic/pages/js-link.vue
vendored
Normal file
5
test/fixtures/basic/pages/js-link.vue
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<h1>vue file is first-class</h1>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./js-link.js"></script>
|
7
test/fixtures/basic/pages/jsx.js
vendored
Normal file
7
test/fixtures/basic/pages/jsx.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default {
|
||||||
|
render() {
|
||||||
|
return <div class='container'>
|
||||||
|
<h1>JSX Page</h1>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
11
test/fixtures/basic/pages/redirect-name.vue
vendored
Normal file
11
test/fixtures/basic/pages/redirect-name.vue
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div>Redirecting...</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
fetch({ redirect }) {
|
||||||
|
return redirect({name: 'stateless'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
11
test/fixtures/basic/pages/router-guard.vue
vendored
Normal file
11
test/fixtures/basic/pages/router-guard.vue
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div>Router Guard</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
beforeRouteEnter(to, from, next) {
|
||||||
|
next({path: '/async-data'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
12
test/fixtures/basic/plugins/watch.js
vendored
Normal file
12
test/fixtures/basic/plugins/watch.js
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
const Plugin = {
|
||||||
|
install(Vue) {
|
||||||
|
Vue.mixin({
|
||||||
|
created() {
|
||||||
|
console.log('I am mixin') // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vue.use(Plugin)
|
7
test/fixtures/debug/nuxt.config.js
vendored
7
test/fixtures/debug/nuxt.config.js
vendored
@ -2,12 +2,13 @@ module.exports = {
|
|||||||
router: {
|
router: {
|
||||||
base: '/test/'
|
base: '/test/'
|
||||||
},
|
},
|
||||||
|
dev: true, // Needed for _open middleware
|
||||||
debug: true,
|
debug: true,
|
||||||
build: {
|
|
||||||
scopeHoisting: true
|
|
||||||
},
|
|
||||||
editor: {
|
editor: {
|
||||||
cmd: 'echo',
|
cmd: 'echo',
|
||||||
pattern: ''
|
pattern: ''
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
test/fixtures/deprecate/nuxt.config.js
vendored
1
test/fixtures/deprecate/nuxt.config.js
vendored
@ -3,6 +3,7 @@ module.exports = {
|
|||||||
'~/modules/hooks'
|
'~/modules/hooks'
|
||||||
],
|
],
|
||||||
build: {
|
build: {
|
||||||
|
stats: false,
|
||||||
extend(config, options) {
|
extend(config, options) {
|
||||||
if (options.dev) {
|
if (options.dev) {
|
||||||
// Please use isDev instead of dev
|
// Please use isDev instead of dev
|
||||||
|
1
test/fixtures/dll/nuxt.config.js
vendored
1
test/fixtures/dll/nuxt.config.js
vendored
@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
build: {
|
build: {
|
||||||
|
stats: false,
|
||||||
dll: true,
|
dll: true,
|
||||||
extend(config, options) {
|
extend(config, options) {
|
||||||
if (options.isClient) {
|
if (options.isClient) {
|
||||||
|
3
test/fixtures/module/modules/middleware/use-middleware.js
vendored
Normal file
3
test/fixtures/module/modules/middleware/use-middleware.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = function (req, res, next) {
|
||||||
|
res.end('Use external middleware')
|
||||||
|
}
|
10
test/fixtures/module/nuxt.config.js
vendored
10
test/fixtures/module/nuxt.config.js
vendored
@ -21,5 +21,15 @@ module.exports = {
|
|||||||
hook('build:done', builder => {
|
hook('build:done', builder => {
|
||||||
builder.__build_done__ = true
|
builder.__build_done__ = true
|
||||||
})
|
})
|
||||||
|
// Add hook for renderer
|
||||||
|
hook('render:before', (renderer) => {
|
||||||
|
renderer.useMiddleware({
|
||||||
|
path: '/use-middleware',
|
||||||
|
handler: '~/modules/middleware/use-middleware'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
test/fixtures/spa/nuxt.config.js
vendored
6
test/fixtures/spa/nuxt.config.js
vendored
@ -1,6 +1,8 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
rootDir: __dirname,
|
|
||||||
mode: 'spa',
|
mode: 'spa',
|
||||||
dev: false,
|
dev: false,
|
||||||
transition: false
|
transition: false,
|
||||||
|
build: {
|
||||||
|
stats: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
test/fixtures/ssr/nuxt.config.js
vendored
Normal file
10
test/fixtures/ssr/nuxt.config.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
dev: false,
|
||||||
|
render: {
|
||||||
|
resourceHints: false
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
stats: false,
|
||||||
|
extractCSS: true
|
||||||
|
}
|
||||||
|
}
|
12
test/fixtures/with-config/nuxt.config.js
vendored
12
test/fixtures/with-config/nuxt.config.js
vendored
@ -42,12 +42,22 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
// extractCSS: true,
|
stats: false,
|
||||||
publicPath: '/orion/',
|
publicPath: '/orion/',
|
||||||
analyze: {
|
analyze: {
|
||||||
analyzerMode: 'disabled',
|
analyzerMode: 'disabled',
|
||||||
generateStatsFile: true
|
generateStatsFile: true
|
||||||
},
|
},
|
||||||
|
styleResources: {
|
||||||
|
patterns: [
|
||||||
|
'~/assets/pre-process.scss'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
babel: {
|
||||||
|
presets({ isServer }) {
|
||||||
|
return null // Coverage: Return null, so defaults will be used.
|
||||||
|
}
|
||||||
|
},
|
||||||
extend(config, options) {
|
extend(config, options) {
|
||||||
return Object.assign({}, config, {
|
return Object.assign({}, config, {
|
||||||
devtool: 'nosources-source-map'
|
devtool: 'nosources-source-map'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { Nuxt, Generator } from '../index.js'
|
import { Nuxt, Generator } from '..'
|
||||||
|
|
||||||
test('initRoutes with routes (fn => array)', async t => {
|
test('initRoutes with routes (fn => array)', async t => {
|
||||||
const array = ['/1', '/2', '/3', '/4']
|
const array = ['/1', '/2', '/3', '/4']
|
||||||
|
136
test/helpers/console.js
Normal file
136
test/helpers/console.js
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import sinon from 'sinon'
|
||||||
|
|
||||||
|
let context = null
|
||||||
|
|
||||||
|
export function release() {
|
||||||
|
if (context === null) {
|
||||||
|
process.stderr.write('Console spy context was empty, did a previous test already release it?\n')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.log) {
|
||||||
|
console.log = context.log // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
if (context.info) {
|
||||||
|
console.info = context.info // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
if (context.warn) {
|
||||||
|
console.warn = context.warn // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
if (context.error) {
|
||||||
|
console.error = context.error // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
if (context.stdout) {
|
||||||
|
process.stdout.write = context.stdout
|
||||||
|
}
|
||||||
|
if (context.stderr) {
|
||||||
|
process.stderr.write = context.stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
context = null
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function intercept(levels, msg, cb) {
|
||||||
|
if (context !== null) {
|
||||||
|
process.stderr.write('Console spy context was not empty, did a previous test not release it?\n')
|
||||||
|
}
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
if (cb === undefined && typeof msg === 'function') {
|
||||||
|
cb = msg
|
||||||
|
msg = undefined
|
||||||
|
|
||||||
|
if (typeof levels === 'string') {
|
||||||
|
msg = levels
|
||||||
|
levels = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb === undefined && msg === undefined && typeof levels === 'function') {
|
||||||
|
cb = levels
|
||||||
|
levels = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const all = levels === undefined || levels === {}
|
||||||
|
const spies = {}
|
||||||
|
|
||||||
|
if (all || levels.log) {
|
||||||
|
context.log = console.log // eslint-disable-line no-console
|
||||||
|
spies.log = console.log = sinon.spy() // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || levels.info) {
|
||||||
|
context.info = console.info // eslint-disable-line no-console
|
||||||
|
spies.info = console.info = sinon.spy() // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || levels.warn) {
|
||||||
|
context.warn = console.warn // eslint-disable-line no-console
|
||||||
|
spies.warn = console.warn = sinon.spy() // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || levels.error) {
|
||||||
|
context.error = console.error // eslint-disable-line no-console
|
||||||
|
spies.error = console.error = sinon.spy() // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levels && levels.stdout) {
|
||||||
|
context.stdout = process.stdout.write
|
||||||
|
spies.stdout = process.stdout.write = sinon.spy()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levels && levels.stderr) {
|
||||||
|
context.stderr = process.stderr.write
|
||||||
|
spies.stderr = process.stderr.write = sinon.spy()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb) {
|
||||||
|
if (msg) {
|
||||||
|
if (context.stdout) {
|
||||||
|
context.stdout(` ${msg}`)
|
||||||
|
} else {
|
||||||
|
process.stdout.write(` ${msg}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await cb()
|
||||||
|
|
||||||
|
release()
|
||||||
|
|
||||||
|
if (msg) {
|
||||||
|
process.stdout.write('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return spies
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptLog(msg, cb) {
|
||||||
|
const { log } = await intercept({ log: true }, msg, cb)
|
||||||
|
return log
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptInfo(msg, cb) {
|
||||||
|
const { info } = await intercept({ info: true }, msg, cb)
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptWarn(msg, cb) {
|
||||||
|
const { warn } = await intercept({ warn: true }, msg, cb)
|
||||||
|
return warn
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptError(msg, cb) {
|
||||||
|
const { error } = await intercept({ error: true }, msg, cb)
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptStdout(msg, cb) {
|
||||||
|
const { stdout } = await intercept({ stdout: true }, msg, cb)
|
||||||
|
return stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function interceptStderr(msg, cb) {
|
||||||
|
const { stderr } = await intercept({ stderr: true }, msg, cb)
|
||||||
|
return stderr
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
|
||||||
test('Nuxt.js Class', t => {
|
test('Nuxt.js Class', t => {
|
||||||
t.is(typeof Nuxt, 'function')
|
t.is(typeof Nuxt, 'function')
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Nuxt.js Instance', async t => {
|
test('Nuxt.js Instance', async t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = new Nuxt({
|
||||||
rootDir: resolve(__dirname, 'fixtures', 'empty')
|
rootDir: resolve(__dirname, 'fixtures', 'empty')
|
||||||
})
|
})
|
||||||
@ -17,7 +17,7 @@ test.serial('Nuxt.js Instance', async t => {
|
|||||||
t.is(nuxt.initialized, true)
|
t.is(nuxt.initialized, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Fail to build when no pages/ directory but is in the parent', t => {
|
test('Fail to build when no pages/ directory but is in the parent', t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = new Nuxt({
|
||||||
dev: false,
|
dev: false,
|
||||||
rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages')
|
rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages')
|
||||||
@ -29,7 +29,7 @@ test.serial('Fail to build when no pages/ directory but is in the parent', t =>
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Fail to build when no pages/ directory', t => {
|
test('Fail to build when no pages/ directory', t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = new Nuxt({
|
||||||
dev: false,
|
dev: false,
|
||||||
rootDir: resolve(__dirname)
|
rootDir: resolve(__dirname)
|
||||||
|
@ -1,69 +1,71 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import stdMocks from 'std-mocks'
|
|
||||||
import { resolve, normalize } from 'path'
|
import { resolve, normalize } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { intercept } from './helpers/console'
|
||||||
|
|
||||||
const port = 4006
|
const port = 4006
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
let builder = null
|
let builder = null
|
||||||
let builtErr = null
|
let buildSpies = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const rootDir = resolve(__dirname, 'fixtures/module')
|
const rootDir = resolve(__dirname, 'fixtures/module')
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
const config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
builder = new Builder(nuxt)
|
builder = new Builder(nuxt)
|
||||||
|
|
||||||
stdMocks.use({
|
buildSpies = await intercept({ log: true, error: true }, async () => {
|
||||||
stdout: false,
|
|
||||||
stderr: true
|
|
||||||
})
|
|
||||||
await builder.build()
|
await builder.build()
|
||||||
stdMocks.restore()
|
|
||||||
builtErr = stdMocks.flush().stderr
|
|
||||||
|
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(buildSpies.log.calledWithMatch('DONE'))
|
||||||
|
t.true(buildSpies.log.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Vendor', async t => {
|
test.serial('Vendor', async t => {
|
||||||
t.true(nuxt.options.build.vendor.indexOf('lodash') !== -1, 'lodash added to config')
|
t.true(nuxt.options.build.vendor.indexOf('lodash') !== -1, 'lodash added to config')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Plugin', async t => {
|
test.serial('Plugin', async t => {
|
||||||
t.true(normalize(nuxt.options.plugins[0].src)
|
t.true(normalize(nuxt.options.plugins[0].src)
|
||||||
.includes(normalize('fixtures/module/.nuxt/basic.reverse.')), 'plugin added to config')
|
.includes(normalize('fixtures/module/.nuxt/basic.reverse.')), 'plugin added to config')
|
||||||
const { html } = await nuxt.renderRoute('/')
|
const { html } = await nuxt.renderRoute('/')
|
||||||
t.true(html.includes('<h1>TXUN</h1>'), 'plugin works')
|
t.true(html.includes('<h1>TXUN</h1>'), 'plugin works')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test.serial('Hooks', async t => {
|
||||||
|
t.is(nuxt.__module_hook, 1)
|
||||||
|
t.is(nuxt.__renderer_hook, 2)
|
||||||
|
t.is(nuxt.__builder_hook, 3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('Hooks - Functional', async t => {
|
||||||
|
t.true(nuxt.__ready_called__)
|
||||||
|
t.true(builder.__build_done__)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.serial('Hooks - Error', async t => {
|
||||||
|
t.true(buildSpies.error.calledWithMatch(/build:extendRoutes/))
|
||||||
|
})
|
||||||
|
|
||||||
test('Middleware', async t => {
|
test('Middleware', async t => {
|
||||||
let response = await rp(url('/api'))
|
let response = await rp(url('/api'))
|
||||||
t.is(response, 'It works!', '/api response is correct')
|
t.is(response, 'It works!', '/api response is correct')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Hooks', async t => {
|
test('Hooks - Use external middleware before render', async t => {
|
||||||
t.is(nuxt.__module_hook, 1)
|
let response = await rp(url('/use-middleware'))
|
||||||
t.is(nuxt.__renderer_hook, 2)
|
t.is(response, 'Use external middleware')
|
||||||
t.is(nuxt.__builder_hook, 3)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Hooks - Functional', async t => {
|
|
||||||
t.true(nuxt.__ready_called__)
|
|
||||||
t.true(builder.__build_done__)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Hooks - Error', async t => {
|
|
||||||
const errors = builtErr.filter(value => value.indexOf('build:extendRoutes') >= 0)
|
|
||||||
t.true(errors.length === 1)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import stdMocks from 'std-mocks'
|
import { resolve } from 'path'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { interceptLog, release } from './helpers/console'
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
|
||||||
const port = 4004
|
const port = 4012
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
const renderRoute = async _url => {
|
const renderRoute = async _url => {
|
||||||
@ -15,39 +16,63 @@ const renderRoute = async _url => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
nuxt = new Nuxt(require('./fixtures/spa/nuxt.config'))
|
const rootDir = resolve(__dirname, 'fixtures/spa')
|
||||||
|
const config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
|
config.rootDir = rootDir
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
|
nuxt = new Nuxt(config)
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/ (basic spa)', async t => {
|
test.serial('/ (basic spa)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { html } = await renderRoute('/')
|
const { html } = await renderRoute('/')
|
||||||
t.true(html.includes('Hello SPA!'))
|
t.true(html.includes('Hello SPA!'))
|
||||||
|
release()
|
||||||
|
t.true(logSpy.withArgs('created').notCalled)
|
||||||
|
t.true(logSpy.withArgs('mounted').calledOnce)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/custom (custom layout)', async t => {
|
test.serial('/custom (custom layout)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { html } = await renderRoute('/custom')
|
const { html } = await renderRoute('/custom')
|
||||||
t.true(html.includes('Custom layout'))
|
t.true(html.includes('Custom layout'))
|
||||||
|
release()
|
||||||
|
t.true(logSpy.withArgs('created').calledOnce)
|
||||||
|
t.true(logSpy.withArgs('mounted').calledOnce)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/custom (not default layout)', async t => {
|
test.serial('/custom (not default layout)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { head } = await renderRoute('/custom')
|
const { head } = await renderRoute('/custom')
|
||||||
t.false(head.includes('src="/_nuxt/layouts/default.'))
|
t.false(head.includes('src="/_nuxt/layouts/default.'))
|
||||||
|
release()
|
||||||
|
t.true(logSpy.withArgs('created').calledOnce)
|
||||||
|
t.true(logSpy.withArgs('mounted').calledOnce)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/custom (call mounted and created once)', async t => {
|
test.serial('/custom (call mounted and created once)', async t => {
|
||||||
stdMocks.use()
|
const logSpy = await interceptLog()
|
||||||
await renderRoute('/custom')
|
await renderRoute('/custom')
|
||||||
stdMocks.restore()
|
release()
|
||||||
const output = stdMocks.flush()
|
t.true(logSpy.withArgs('created').calledOnce)
|
||||||
const creates = output.stdout.filter(value => value === 'created\n')
|
t.true(logSpy.withArgs('mounted').calledOnce)
|
||||||
t.true(creates.length === 1)
|
})
|
||||||
const mounts = output.stdout.filter(value => value === 'mounted\n')
|
|
||||||
t.true(mounts.length === 1)
|
test('/_nuxt/ (access publicPath in spa mode)', async t => {
|
||||||
|
const { response: { statusCode, statusMessage } } = await t.throws(renderRoute('/_nuxt/'))
|
||||||
|
t.is(statusCode, 404)
|
||||||
|
t.is(statusMessage, 'ResourceNotFound')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -3,6 +3,7 @@ import { resolve } from 'path'
|
|||||||
import { Nuxt, Builder, Utils } from '..'
|
import { Nuxt, Builder, Utils } from '..'
|
||||||
import { uniq } from 'lodash'
|
import { uniq } from 'lodash'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
|
import { interceptLog } from './helpers/console'
|
||||||
|
|
||||||
const port = 4008
|
const port = 4008
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
@ -17,20 +18,19 @@ const url = (route) => 'http://localhost:' + port + route
|
|||||||
const isWindows = /^win/.test(process.platform)
|
const isWindows = /^win/.test(process.platform)
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.serial('Init Nuxt.js', async t => {
|
||||||
const options = {
|
const rootDir = resolve(__dirname, 'fixtures/ssr')
|
||||||
rootDir: resolve(__dirname, 'fixtures/ssr'),
|
const config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
dev: false,
|
config.rootDir = rootDir
|
||||||
render: {
|
|
||||||
resourceHints: false
|
const logSpy = await interceptLog(async () => {
|
||||||
},
|
nuxt = new Nuxt(config)
|
||||||
build: {
|
|
||||||
extractCSS: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nuxt = new Nuxt(options)
|
|
||||||
await new Builder(nuxt).build()
|
await new Builder(nuxt).build()
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// == Uniq Test ==
|
// == Uniq Test ==
|
||||||
@ -121,6 +121,6 @@ test('stress test with asyncData', async t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
test.after('Closing server and nuxt.js', t => {
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
nuxt.close()
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import ansiHTML from 'ansi-html'
|
import ansiHTML from 'ansi-html'
|
||||||
import { Utils } from '../index.js'
|
import { Utils } from '..'
|
||||||
|
|
||||||
test('encodeHtml', t => {
|
test('encodeHtml', t => {
|
||||||
const html = '<h1>Hello</h1>'
|
const html = '<h1>Hello</h1>'
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import rp from 'request-promise-native'
|
import rp from 'request-promise-native'
|
||||||
import { Nuxt, Builder } from '../index.js'
|
import { Nuxt, Builder } from '..'
|
||||||
|
import { interceptLog, release } from './helpers/console'
|
||||||
|
|
||||||
const port = 4007
|
const port = 4007
|
||||||
const url = (route) => 'http://localhost:' + port + route
|
const url = (route) => 'http://localhost:' + port + route
|
||||||
|
|
||||||
let nuxt = null
|
let nuxt = null
|
||||||
|
let builder = null
|
||||||
|
|
||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.before('Init Nuxt.js', async t => {
|
||||||
@ -14,14 +16,25 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
|
|
||||||
|
const logSpy = await interceptLog(async () => {
|
||||||
nuxt = new Nuxt(config)
|
nuxt = new Nuxt(config)
|
||||||
await new Builder(nuxt).build()
|
builder = new Builder(nuxt)
|
||||||
|
await builder.build()
|
||||||
await nuxt.listen(port, 'localhost')
|
await nuxt.listen(port, 'localhost')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.true(logSpy.calledWithMatch('DONE'))
|
||||||
|
t.true(logSpy.calledWithMatch('OPEN'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/', async t => {
|
test.serial('/', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const { html } = await nuxt.renderRoute('/')
|
const { html } = await nuxt.renderRoute('/')
|
||||||
t.true(html.includes('<h1>I have custom configurations</h1>'))
|
t.true(html.includes('<h1>I have custom configurations</h1>'))
|
||||||
|
release()
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/ (global styles inlined)', async t => {
|
test('/ (global styles inlined)', async t => {
|
||||||
@ -49,40 +62,65 @@ test('/ (custom postcss.config.js)', async t => {
|
|||||||
t.true(html.includes('::-webkit-input-placeholder'))
|
t.true(html.includes('::-webkit-input-placeholder'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/ (router base)', async t => {
|
test.serial('/test/ (router base)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/'))
|
const window = await nuxt.renderAndGetWindow(url('/test/'))
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.is(window.__NUXT__.layout, 'default')
|
t.is(window.__NUXT__.layout, 'default')
|
||||||
t.true(html.includes('<h1>Default layout</h1>'))
|
t.true(html.includes('<h1>Default layout</h1>'))
|
||||||
t.true(html.includes('<h1>I have custom configurations</h1>'))
|
t.true(html.includes('<h1>I have custom configurations</h1>'))
|
||||||
|
release()
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/about (custom layout)', async t => {
|
test.serial('/test/about (custom layout)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/about'))
|
const window = await nuxt.renderAndGetWindow(url('/test/about'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.is(window.__NUXT__.layout, 'custom')
|
t.is(window.__NUXT__.layout, 'custom')
|
||||||
t.true(html.includes('<h1>Custom layout</h1>'))
|
t.true(html.includes('<h1>Custom layout</h1>'))
|
||||||
t.true(html.includes('<h1>About page</h1>'))
|
t.true(html.includes('<h1>About page</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/desktop (custom layout in desktop folder)', async t => {
|
test.serial('/test/desktop (custom layout in desktop folder)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/desktop'))
|
const window = await nuxt.renderAndGetWindow(url('/test/desktop'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.is(window.__NUXT__.layout, 'desktop/default')
|
t.is(window.__NUXT__.layout, 'desktop/default')
|
||||||
t.true(html.includes('<h1>Default desktop layout</h1>'))
|
t.true(html.includes('<h1>Default desktop layout</h1>'))
|
||||||
t.true(html.includes('<h1>Desktop page</h1>'))
|
t.true(html.includes('<h1>Desktop page</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/mobile (custom layout in mobile folder)', async t => {
|
test.serial('/test/mobile (custom layout in mobile folder)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/mobile'))
|
const window = await nuxt.renderAndGetWindow(url('/test/mobile'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.is(window.__NUXT__.layout, 'mobile/default')
|
t.is(window.__NUXT__.layout, 'mobile/default')
|
||||||
t.true(html.includes('<h1>Default mobile layout</h1>'))
|
t.true(html.includes('<h1>Default mobile layout</h1>'))
|
||||||
t.true(html.includes('<h1>Mobile page</h1>'))
|
t.true(html.includes('<h1>Mobile page</h1>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/env', async t => {
|
test.serial('/test/env', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/env'))
|
const window = await nuxt.renderAndGetWindow(url('/test/env'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<h1>Custom env layout</h1>'))
|
t.true(html.includes('<h1>Custom env layout</h1>'))
|
||||||
t.true(html.includes('"bool": true'))
|
t.true(html.includes('"bool": true'))
|
||||||
@ -94,20 +132,35 @@ test('/test/env', async t => {
|
|||||||
t.true(html.includes('"obj": {'))
|
t.true(html.includes('"obj": {'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/error', async t => {
|
test.serial('/test/error', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/error'))
|
const window = await nuxt.renderAndGetWindow(url('/test/error'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('Error page'))
|
t.true(html.includes('Error page'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/user-agent', async t => {
|
test.serial('/test/user-agent', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/user-agent'))
|
const window = await nuxt.renderAndGetWindow(url('/test/user-agent'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<pre>Mozilla'))
|
t.true(html.includes('<pre>Mozilla'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/test/about-bis (added with extendRoutes)', async t => {
|
test.serial('/test/about-bis (added with extendRoutes)', async t => {
|
||||||
|
const logSpy = await interceptLog()
|
||||||
const window = await nuxt.renderAndGetWindow(url('/test/about-bis'))
|
const window = await nuxt.renderAndGetWindow(url('/test/about-bis'))
|
||||||
|
t.true(logSpy.calledOnce)
|
||||||
|
t.is(logSpy.args[0][0], 'Test plugin!')
|
||||||
|
release()
|
||||||
|
|
||||||
const html = window.document.body.innerHTML
|
const html = window.document.body.innerHTML
|
||||||
t.true(html.includes('<h1>Custom layout</h1>'))
|
t.true(html.includes('<h1>Custom layout</h1>'))
|
||||||
t.true(html.includes('<h1>About page</h1>'))
|
t.true(html.includes('<h1>About page</h1>'))
|
||||||
@ -128,7 +181,18 @@ test('Check /test.txt should return 404', async t => {
|
|||||||
t.is(err.response.statusCode, 404)
|
t.is(err.response.statusCode, 404)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
test('Check build.styleResources for style-resources-loader', async t => {
|
||||||
test.after('Closing server and nuxt.js', t => {
|
const loaders = builder.styleLoader('scss')
|
||||||
nuxt.close()
|
const loader = loaders.find(l => l.loader === 'style-resources-loader')
|
||||||
|
t.is(typeof loader, 'object')
|
||||||
|
t.deepEqual(loader.options, {
|
||||||
|
patterns: [
|
||||||
|
'~/assets/pre-process.scss'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
|
test.after.always('Closing server and nuxt.js', async t => {
|
||||||
|
await nuxt.close()
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user