mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 16:43:55 +00:00
Merge remote-tracking branch 'nuxt/dev' into dev
This commit is contained in:
commit
a315b71ea8
35
.circleci/config.yml
Executable file
35
.circleci/config.yml
Executable file
@ -0,0 +1,35 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
working_directory: /usr/src/app
|
||||
docker:
|
||||
- image: banian/node-headless-chrome
|
||||
steps:
|
||||
# Checkout repository
|
||||
- checkout
|
||||
|
||||
# Restore cache
|
||||
- restore_cache:
|
||||
key: yarn-{{ checksum "yarn.lock" }}
|
||||
|
||||
# Install dependencies
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: NODE_ENV=dev yarn
|
||||
|
||||
# Keep cache
|
||||
- save_cache:
|
||||
key: yarn-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- "node_modules"
|
||||
|
||||
# Build
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
yarn build
|
||||
|
||||
# Test
|
||||
- run:
|
||||
name: Tests
|
||||
command: yarn test && yarn coverage
|
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@ -0,0 +1,4 @@
|
||||
app
|
||||
node_modules
|
||||
dist
|
||||
.nuxt
|
@ -22,7 +22,14 @@ module.exports = {
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
// do not allow console.logs etc...
|
||||
'no-console': 2
|
||||
'no-console': 2,
|
||||
'space-before-function-paren': [
|
||||
2,
|
||||
{
|
||||
anonymous: 'always',
|
||||
named: 'never'
|
||||
}
|
||||
],
|
||||
},
|
||||
globals: {}
|
||||
}
|
||||
|
33
.gitignore
vendored
33
.gitignore
vendored
@ -1,17 +1,21 @@
|
||||
# dependencies
|
||||
# Dependencies
|
||||
node_modules
|
||||
examples/**/*/yarn.lock
|
||||
jspm_packages
|
||||
package-lock.json
|
||||
|
||||
# logs
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# other
|
||||
# Other
|
||||
.nuxt
|
||||
.cache
|
||||
|
||||
# Dist folder
|
||||
dist
|
||||
|
||||
# dist example generation
|
||||
# Dist example generation
|
||||
examples/**/dist
|
||||
|
||||
# Coverage support
|
||||
@ -23,3 +27,24 @@ coverage
|
||||
# Intellij idea
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# OSX
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
11
.travis.yml
11
.travis.yml
@ -1,10 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "8.0"
|
||||
- "7.2"
|
||||
- "6.9"
|
||||
before_install:
|
||||
- if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
|
||||
- "8"
|
||||
- "6"
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- node_modules
|
||||
install:
|
||||
- yarn install
|
||||
- yarn run build
|
||||
|
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at team@nuxtjs.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
10
CONTRIBUTING.md
Normal file
10
CONTRIBUTING.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Contributing to Nuxt.js
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||
2. Install the dependencies: `npm install`.
|
||||
3. Run `npm link` to link the local repo to NPM.
|
||||
4. Run `npm run build` to build or `npm run watch` to build and watch for code changes.
|
||||
5. Then npm link this repo inside any example app with `npm link nuxt`.
|
||||
6. Then you can run your example app with the local version of Nuxt.js (You may need to re-run the example app as you change server side code in the Nuxt.js repository).
|
||||
|
||||
Make sure to add tests into `test/` directory and try them with `npm test` before making a pull request.
|
32
README.md
32
README.md
@ -2,7 +2,7 @@
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/nuxt/nuxt.js"><img src="https://img.shields.io/travis/nuxt/nuxt.js/master.svg" alt="Build Status"></a>
|
||||
<a href="https://ci.appveyor.com/project/Atinux/nuxt-js"><img src="https://ci.appveyor.com/api/projects/status/gwab06obc6srx9g4?svg=true" alt="Windows Build Status"></a>
|
||||
<a href="https://codecov.io/gh/nuxt/nuxt.js"><img src="https://img.shields.io/codecov/c/github/nuxt/nuxt.js/master.svg" alt="Coverage Status"></a>
|
||||
<a href="https://codecov.io/gh/nuxt/nuxt.js"><img src="https://img.shields.io/codecov/c/github/nuxt/nuxt.js/dev.svg" alt="Coverage Status"></a>
|
||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg" alt="Downloads"></a>
|
||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg" alt="Version"></a>
|
||||
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/l/nuxt.svg" alt="License"></a>
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
</p>
|
||||
|
||||
> Nuxt.js is a framework for server-rendered Vue applications (inspired by [Next.js](https://github.com/zeit/next.js))
|
||||
> Nuxt.js is a Versatile Vue.js Framework
|
||||
|
||||
## 🚧 Under active development, [1.0](https://github.com/nuxt/nuxt.js/projects/1) will be released soon :fire:
|
||||
|
||||
@ -98,6 +98,8 @@ Support us with a monthly donation and help us continue our activities. [[Become
|
||||
- 📘 Documentation: [https://nuxtjs.org](https://nuxtjs.org)
|
||||
- 🎬 Video: [1 minute demo](https://www.youtube.com/watch?v=kmf-p-pTi40)
|
||||
- 🐦 Twitter: [@nuxt_js](https://twitter.com/nuxt_js)
|
||||
- 👥 [Nuxt.js Community](https://github.com/nuxt-community)
|
||||
- 📦 [Nuxt.js Modules](https://github.com/nuxt-community/modules)
|
||||
- 👉 [Play with Nuxt.js online](https://glitch.com/edit/#!/nuxt-hello-world)
|
||||
|
||||
## Getting started
|
||||
@ -157,20 +159,29 @@ Learn more at [nuxtjs.org](https://nuxtjs.org).
|
||||
## Templates
|
||||
|
||||
You can start by using one of our starter templates:
|
||||
- [starter](https://github.com/nuxt/starter): Basic Nuxt.js project template
|
||||
- [express](https://github.com/nuxt/express): Nuxt.js + Express
|
||||
- [koa](https://github.com/nuxt/koa): Nuxt.js + Koa
|
||||
- [adonuxt](https://github.com/nuxt/adonuxt): Nuxt.js + AdonisJS
|
||||
- [starter](https://github.com/nuxt-community/starter-template): Basic Nuxt.js project template
|
||||
- [express](https://github.com/nuxt-community/express-template): Nuxt.js + Express
|
||||
- [koa](https://github.com/nuxt-community/koa-template): Nuxt.js + Koa
|
||||
- [adonuxt](https://github.com/nuxt-community/adonuxt-template): Nuxt.js + AdonisJS
|
||||
- [micro](https://github.com/nuxt-community/micro-template): Nuxt.js + Micro
|
||||
- [nuxtent](https://github.com/nuxt-community/nuxtent-template): Nuxt.js + Nuxtent module for content heavy sites
|
||||
|
||||
## Using nuxt.js programmatically
|
||||
|
||||
```js
|
||||
const Nuxt = require('nuxt')
|
||||
const { Nuxt, Builder } = require('nuxt')
|
||||
|
||||
// Launch nuxt build with given options
|
||||
// Import and set nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
let nuxt = new Nuxt(config)
|
||||
|
||||
// Start build process (only in development)
|
||||
if (config.dev) {
|
||||
new Builder(nuxt).build()
|
||||
}
|
||||
|
||||
// You can use nuxt.render(req, res) or nuxt.renderRoute(route, context)
|
||||
```
|
||||
|
||||
@ -240,4 +251,7 @@ Note: we recommend putting `.nuxt` in `.npmignore` or `.gitignore`.
|
||||
|
||||
## Roadmap
|
||||
|
||||
https://github.com/nuxt/nuxt.js/projects/1
|
||||
https://trello.com/b/lgy93IOl/nuxtjs-10
|
||||
|
||||
## Contributing
|
||||
Please see our [CONTRIBUTING.md](./CONTRIBUTING.md)
|
||||
|
@ -1,6 +1,12 @@
|
||||
# Test against the latest version of this Node.js version
|
||||
environment:
|
||||
nodejs_version: "6"
|
||||
matrix:
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
|
||||
cache:
|
||||
- "%LOCALAPPDATA%\\Yarn"
|
||||
- node_modules
|
||||
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
|
29
benchmarks/README.md
Normal file
29
benchmarks/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Nuxt.js server-side benchmarks
|
||||
|
||||
> Taken from [Next.js benchmarks](https://github.com/zeit/next.js/tree/master/bench), if you like React, we recommend you to try [Next.js](https://github.com/zeit/next.js).
|
||||
|
||||
## Installation
|
||||
|
||||
Follow the steps in [CONTRIBUTING.md](../CONTRIBUTING.md).
|
||||
|
||||
Both benchmarks use `ab`. So make sure you have it installed.
|
||||
|
||||
## Usage
|
||||
|
||||
Before running the test:
|
||||
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
|
||||
Then run one of these tests:
|
||||
|
||||
- Stateless application which renders `<h1>My component!</h1>`. Runs 3000 http requests.
|
||||
```
|
||||
npm run bench:stateless
|
||||
```
|
||||
|
||||
- Stateless application which renders `<li>This is row {i}</li>` 10.000 times. Runs 500 http requests.
|
||||
```
|
||||
npm run bench:stateless-big
|
||||
```
|
9
benchmarks/package.json
Normal file
9
benchmarks/package.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "nuxt-benchmarks",
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"start": "npm run build && nuxt start",
|
||||
"bench:stateless": "ab -c1 -n3000 http://127.0.0.1:3000/stateless",
|
||||
"bench:stateless-big": "ab -c1 -n500 http://127.0.0.1:3000/stateless-big"
|
||||
}
|
||||
}
|
5
benchmarks/pages/stateless-big.vue
Normal file
5
benchmarks/pages/stateless-big.vue
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="n in 10000" :key="n">This is row {{ n + 1 }}</li>
|
||||
</ul>
|
||||
</template>
|
3
benchmarks/pages/stateless.vue
Normal file
3
benchmarks/pages/stateless.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<h1>My component!</h1>
|
||||
</template>
|
9
bin/nuxt
9
bin/nuxt
@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var join = require('path').join
|
||||
const join = require('path').join
|
||||
require('../lib/common/cli/errors')
|
||||
|
||||
var defaultCommand = 'dev'
|
||||
var commands = new Set([
|
||||
const defaultCommand = 'dev'
|
||||
const commands = new Set([
|
||||
defaultCommand,
|
||||
'init',
|
||||
'build',
|
||||
@ -19,6 +20,6 @@ if (commands.has(cmd)) {
|
||||
cmd = defaultCommand
|
||||
}
|
||||
|
||||
var bin = join(__dirname, 'nuxt-' + cmd)
|
||||
const bin = join(__dirname, 'nuxt-' + cmd)
|
||||
|
||||
require(bin)
|
||||
|
118
bin/nuxt-build
118
bin/nuxt-build
@ -1,63 +1,91 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable no-console */
|
||||
|
||||
// Show logs
|
||||
process.env.DEBUG = 'nuxt:*'
|
||||
process.env.DEBUG = process.env.DEBUG || 'nuxt:*'
|
||||
|
||||
var fs = require('fs')
|
||||
var without = require('lodash').without
|
||||
var Nuxt = require('../')
|
||||
var resolve = require('path').resolve
|
||||
const fs = require('fs')
|
||||
const parseArgs = require('minimist')
|
||||
const { Nuxt, Builder, Generator } = require('../')
|
||||
const resolve = require('path').resolve
|
||||
const debug = require('debug')('nuxt:build')
|
||||
debug.color = 2 // Force green color
|
||||
|
||||
// --analyze option
|
||||
var analyzeBuild = false
|
||||
if (process.argv.indexOf('--analyze') !== -1 || process.argv.indexOf('-a') !== -1) {
|
||||
analyzeBuild = true
|
||||
process.argv = without(process.argv, '--analyze', '-a')
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
c: 'config-file',
|
||||
a: 'analyze',
|
||||
s: 'spa',
|
||||
u: 'universal'
|
||||
},
|
||||
boolean: ['h', 'a', 's', 'u'],
|
||||
string: ['c'],
|
||||
default: {
|
||||
c: 'nuxt.config.js'
|
||||
}
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Compiles the application for production deployment
|
||||
Usage
|
||||
$ nuxt build <dir>
|
||||
Options
|
||||
--analyze, -a Launch webpack-bundle-analyzer to optimize your bundles.
|
||||
--spa Launch in SPA mode
|
||||
--universal Launch in Universal mode (default)
|
||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
var nuxtConfigFileName = 'nuxt.config.js'
|
||||
|
||||
// --config-file option
|
||||
var indexOfConfig = false
|
||||
if (process.argv.indexOf('--config-file') !== -1) {
|
||||
indexOfConfig = process.argv.indexOf('--config-file')
|
||||
} else if (process.argv.indexOf('-c') !== -1) {
|
||||
indexOfConfig = process.argv.indexOf('-c')
|
||||
}
|
||||
|
||||
if (indexOfConfig !== false) {
|
||||
nuxtConfigFileName = process.argv.slice(indexOfConfig)[1]
|
||||
process.argv = without(process.argv, '--config-file', '-c', nuxtConfigFileName)
|
||||
}
|
||||
|
||||
// Root directory parameter
|
||||
var rootDir = resolve(process.argv.slice(2)[0] || '.')
|
||||
var nuxtConfigFilePath = resolve(rootDir, nuxtConfigFileName)
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFilePath)) {
|
||||
options = require(nuxtConfigFilePath)
|
||||
} else {
|
||||
console.log(`Could not locate ${nuxtConfigFilePath}`) // eslint-disable-line no-console
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Create production build when calling `nuxt build`
|
||||
// Create production build when calling `nuxt build`
|
||||
options.dev = false
|
||||
|
||||
// Nuxt Mode
|
||||
options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode
|
||||
|
||||
// Analyze option
|
||||
options.build = options.build || {}
|
||||
if (analyzeBuild) {
|
||||
options.build.analyze = analyzeBuild
|
||||
if (argv.analyze) {
|
||||
options.build.analyze = true
|
||||
}
|
||||
|
||||
console.log('[nuxt] Building...') // eslint-disable-line no-console
|
||||
var nuxt = module.exports = new Nuxt(options)
|
||||
nuxt.build()
|
||||
.then(() => {
|
||||
console.log('[nuxt] Building done') // eslint-disable-line no-console
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
debug('Building...')
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
|
||||
if (options.mode !== 'spa') {
|
||||
// Build for SSR app
|
||||
builder.build()
|
||||
.then(() => debug('Building done'))
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
} else {
|
||||
// Disable minify to get exact results of nuxt start
|
||||
nuxt.options.generate.minify = false
|
||||
// Generate on spa mode
|
||||
new Generator(nuxt, builder).generate({ build: true }).then(() => {
|
||||
if (!nuxt.options.dev) {
|
||||
console.log(`✓ You can now directly upload ${nuxt.options.generate.dir}/ or start server using "nuxt start"`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
175
bin/nuxt-dev
175
bin/nuxt-dev
@ -1,80 +1,129 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable no-console */
|
||||
|
||||
// Show logs
|
||||
process.env.DEBUG = 'nuxt:*'
|
||||
process.env.DEBUG = process.env.DEBUG || 'nuxt:*'
|
||||
|
||||
var _ = require('lodash')
|
||||
var debug = require('debug')('nuxt:build')
|
||||
const _ = require('lodash')
|
||||
const debug = require('debug')('nuxt:build')
|
||||
debug.color = 2 // force green color
|
||||
var fs = require('fs')
|
||||
var Nuxt = require('../')
|
||||
var chokidar = require('chokidar')
|
||||
var resolve = require('path').resolve
|
||||
var without = require('lodash').without
|
||||
const fs = require('fs')
|
||||
const parseArgs = require('minimist')
|
||||
const { Nuxt, Builder } = require('../')
|
||||
const chokidar = require('chokidar')
|
||||
const path = require('path')
|
||||
const resolve = path.resolve
|
||||
const pkg = require(path.join('..', 'package.json'))
|
||||
|
||||
var nuxtConfigFileName = 'nuxt.config.js'
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
H: 'hostname',
|
||||
p: 'port',
|
||||
c: 'config-file',
|
||||
s: 'spa',
|
||||
u: 'universal',
|
||||
v: 'version'
|
||||
},
|
||||
boolean: ['h', 's', 'u', 'v'],
|
||||
string: ['H', 'c'],
|
||||
default: {
|
||||
c: 'nuxt.config.js'
|
||||
}
|
||||
})
|
||||
|
||||
// --config-file option
|
||||
var indexOfConfig = false
|
||||
if (process.argv.indexOf('--config-file') !== -1) {
|
||||
indexOfConfig = process.argv.indexOf('--config-file')
|
||||
} else if (process.argv.indexOf('-c') !== -1) {
|
||||
indexOfConfig = process.argv.indexOf('-c')
|
||||
if (argv.version) {
|
||||
console.log(pkg.version)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (indexOfConfig !== false) {
|
||||
nuxtConfigFileName = process.argv.slice(indexOfConfig)[1]
|
||||
process.argv = without(process.argv, '--config-file', '-c', nuxtConfigFileName)
|
||||
if (argv.hostname === '') {
|
||||
console.error(`> Provided hostname argument has no value`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
var rootDir = resolve(process.argv.slice(2)[0] || '.')
|
||||
var nuxtConfigFile = resolve(rootDir, nuxtConfigFileName)
|
||||
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Starts the application in development mode (hot-code reloading, error
|
||||
reporting, etc)
|
||||
Usage
|
||||
$ nuxt dev <dir> -p <port number> -H <hostname>
|
||||
Options
|
||||
--port, -p A port number on which to start the application
|
||||
--hostname, -H Hostname on which to start the application
|
||||
--spa Launch in SPA mode
|
||||
--universal Launch in Universal mode (default)
|
||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = true // Add hot reloading and watching changes
|
||||
|
||||
var nuxt = module.exports = new Nuxt(options)
|
||||
var port = process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
var host = process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host)
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
listenOnConfigChanges(nuxt, server)
|
||||
// Load config once for chokidar
|
||||
const nuxtConfig = loadNuxtConfig()
|
||||
_.defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } })
|
||||
|
||||
function listenOnConfigChanges(nuxt, server) {
|
||||
// Listen on nuxt.config.js changes
|
||||
var build = _.debounce(() => {
|
||||
// Start dev
|
||||
let dev = startDev()
|
||||
|
||||
// Start watching for nuxt.config.js changes
|
||||
chokidar
|
||||
.watch(nuxtConfigFile, nuxtConfig.watchers.chokidar)
|
||||
.on('all', _.debounce(() => {
|
||||
debug('[nuxt.config.js] changed')
|
||||
delete require.cache[nuxtConfigFile]
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
try {
|
||||
options = require(nuxtConfigFile)
|
||||
} catch (e) {
|
||||
return console.error(e) // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
options.rootDir = rootDir
|
||||
nuxt.close()
|
||||
.then(() => {
|
||||
nuxt.renderer = null
|
||||
debug('Rebuilding the app...')
|
||||
return new Nuxt(options).build()
|
||||
})
|
||||
.then((nuxt) => {
|
||||
server.nuxt = nuxt
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error while rebuild the app:', error) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
}, 200)
|
||||
var nuxtConfigFile = resolve(rootDir, nuxtConfigFileName)
|
||||
chokidar.watch(nuxtConfigFile, Object.assign({}, nuxt.options.watchers.chokidar, {ignoreInitial: true}))
|
||||
.on('all', build)
|
||||
debug('Rebuilding the app...')
|
||||
dev = dev.then(startDev)
|
||||
}), 2500)
|
||||
|
||||
function startDev(oldNuxt) {
|
||||
// Get latest environment variables
|
||||
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
|
||||
// Load options
|
||||
let options = {}
|
||||
try {
|
||||
options = loadNuxtConfig()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return // Wait for next reload
|
||||
}
|
||||
|
||||
// Create nuxt and builder instance
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => builder.build()) // 1- Start build
|
||||
.then(() => oldNuxt ? oldNuxt.close() : Promise.resolve()) // 2- Close old nuxt after successful build
|
||||
.then(() => nuxt.listen(port, host)) // 3- Start listening
|
||||
.then(() => nuxt) // 4- Pass new nuxt to watch chain
|
||||
}
|
||||
|
||||
function loadNuxtConfig() {
|
||||
let options = {}
|
||||
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
delete require.cache[nuxtConfigFile]
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
|
||||
// Force development mode for add hot reloading and watching changes
|
||||
options.dev = true
|
||||
|
||||
// Nuxt Mode
|
||||
options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode
|
||||
|
||||
return options
|
||||
}
|
||||
|
@ -1,31 +1,82 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable no-console */
|
||||
|
||||
// Show logs
|
||||
process.env.DEBUG = 'nuxt:*'
|
||||
process.env.DEBUG = process.env.DEBUG || 'nuxt:*'
|
||||
|
||||
var fs = require('fs')
|
||||
var Nuxt = require('../')
|
||||
var resolve = require('path').resolve
|
||||
const fs = require('fs')
|
||||
const parseArgs = require('minimist')
|
||||
const debug = require('debug')('nuxt:generate')
|
||||
|
||||
var rootDir = resolve(process.argv.slice(2)[0] || '.')
|
||||
var nuxtConfigFile = resolve(rootDir, 'nuxt.config.js')
|
||||
const { Nuxt, Builder, Generator } = require('../')
|
||||
const resolve = require('path').resolve
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
c: 'config-file',
|
||||
s: 'spa',
|
||||
u: 'universal'
|
||||
},
|
||||
boolean: ['h', 's', 'u', 'build'],
|
||||
string: ['c'],
|
||||
default: {
|
||||
c: 'nuxt.config.js',
|
||||
build: true
|
||||
}
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Generate a static web application (server-rendered)
|
||||
Usage
|
||||
$ nuxt generate <dir>
|
||||
Options
|
||||
--spa Launch in SPA mode
|
||||
--spa Launch in SPA mode
|
||||
--universal Launch in Universal mode (default)
|
||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||
--help, -h Displays this message
|
||||
--no-build Just run generate for faster builds when just dynamic routes changed. Nuxt build is needed before this command.
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Force production mode (no webpack middleware called)
|
||||
|
||||
console.log('[nuxt] Generating...') // eslint-disable-line no-console
|
||||
var nuxt = module.exports = new Nuxt(options)
|
||||
nuxt.generate()
|
||||
// Nuxt Mode
|
||||
options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode
|
||||
|
||||
debug('Generating...')
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
const generator = new Generator(nuxt, builder)
|
||||
|
||||
const generateOptions = {
|
||||
init: true,
|
||||
build: argv['build']
|
||||
}
|
||||
|
||||
generator.generate(generateOptions)
|
||||
.then(() => {
|
||||
console.log('[nuxt] Generate done') // eslint-disable-line no-console
|
||||
debug('Generate done')
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err) // eslint-disable-line no-console
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
@ -1,22 +1,91 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable no-console */
|
||||
|
||||
var fs = require('fs')
|
||||
var Nuxt = require('../')
|
||||
var resolve = require('path').resolve
|
||||
const fs = require('fs')
|
||||
const parseArgs = require('minimist')
|
||||
const { Nuxt } = require('../')
|
||||
const { resolve } = require('path')
|
||||
|
||||
var rootDir = resolve(process.argv.slice(2)[0] || '.')
|
||||
var nuxtConfigFile = resolve(rootDir, 'nuxt.config.js')
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
H: 'hostname',
|
||||
p: 'port',
|
||||
c: 'config-file',
|
||||
s: 'spa',
|
||||
u: 'universal'
|
||||
},
|
||||
boolean: ['h', 's', 'u'],
|
||||
string: ['H', 'c'],
|
||||
default: {
|
||||
c: 'nuxt.config.js'
|
||||
}
|
||||
})
|
||||
|
||||
if (argv.hostname === '') {
|
||||
console.error(`> Provided hostname argument has no value`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Starts the application in production mode.
|
||||
The application should be compiled with \`nuxt build\` first.
|
||||
Usage
|
||||
$ nuxt start <dir> -p <port number> -H <hostname>
|
||||
Options
|
||||
--port, -p A port number on which to start the application
|
||||
--hostname, -H Hostname on which to start the application
|
||||
--spa Launch in SPA mode
|
||||
--universal Launch in Universal mode (default)
|
||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
let options = {}
|
||||
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Force production mode (no webpack middleware called)
|
||||
|
||||
var nuxt = module.exports = new Nuxt(options)
|
||||
var port = process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
var host = process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host)
|
||||
// Force production mode (no webpack middleware called)
|
||||
options.dev = false
|
||||
|
||||
// Nuxt Mode
|
||||
options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode
|
||||
|
||||
const nuxt = new Nuxt(options)
|
||||
|
||||
// Check if project is built for production
|
||||
const distDir = resolve(nuxt.options.rootDir, nuxt.options.buildDir || '.nuxt', 'dist')
|
||||
if (!fs.existsSync(distDir)) {
|
||||
console.error('> No build files found, please run `nuxt build` before launching `nuxt start`')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Check if SSR Bundle is required
|
||||
if (nuxt.options.render.ssr === true) {
|
||||
const ssrBundlePath = resolve(distDir, 'server-bundle.json')
|
||||
if (!fs.existsSync(ssrBundlePath)) {
|
||||
console.error('> No SSR build! Please start with `nuxt start --spa` or build using `nuxt build --universal`')
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
|
||||
nuxt.listen(port, host)
|
||||
|
116
build/rollup.config.js
Executable file
116
build/rollup.config.js
Executable file
@ -0,0 +1,116 @@
|
||||
// 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]))
|
||||
}
|
108
build/start.js
Executable file
108
build/start.js
Executable file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const now = Date.now()
|
||||
|
||||
const { readFileSync, readJSONSync, writeFileSync, copySync, removeSync } = require('fs-extra')
|
||||
const { resolve, relative } = require('path')
|
||||
|
||||
// Dirs
|
||||
const rootDir = resolve(__dirname, '..')
|
||||
const startDir = resolve(rootDir, 'start')
|
||||
|
||||
// Read main package.json
|
||||
const packageJSON = readJSONSync(resolve(rootDir, 'package.json'))
|
||||
|
||||
// Required and Excluded packages for start
|
||||
let requires = [
|
||||
'source-map-support',
|
||||
'pretty-error',
|
||||
'minimist'
|
||||
]
|
||||
|
||||
const excludes = [
|
||||
'path',
|
||||
'fs',
|
||||
'http',
|
||||
'module'
|
||||
].concat(Object.keys(packageJSON.devDependencies))
|
||||
|
||||
// Parse dist/core.js for all external dependencies
|
||||
const requireRegex = /require\('([-@/\w]+)'\)/g
|
||||
const rawCore = readFileSync(resolve(rootDir, 'dist/core.js'))
|
||||
let match = requireRegex.exec(rawCore)
|
||||
while (match) {
|
||||
requires.push(match[1])
|
||||
match = requireRegex.exec(rawCore)
|
||||
}
|
||||
|
||||
// Apply Excludes
|
||||
requires = requires.filter(r => excludes.indexOf(r) === -1)
|
||||
|
||||
// Resolve version constrains
|
||||
let dependencies = {}
|
||||
requires.forEach(r => {
|
||||
if (!packageJSON.dependencies[r]) {
|
||||
console.warn('Cannot resolve dependency version for ' + r)
|
||||
return
|
||||
}
|
||||
dependencies[r] = packageJSON.dependencies[r]
|
||||
})
|
||||
|
||||
// Drop fields
|
||||
let drops = ['devDependencies', 'scripts', 'nyc', 'types']
|
||||
drops.forEach(k => {
|
||||
delete packageJSON[k]
|
||||
})
|
||||
|
||||
// Update dependencies
|
||||
packageJSON.dependencies = dependencies
|
||||
|
||||
// Update package meta
|
||||
packageJSON.name = 'nuxt-start'
|
||||
packageJSON.description = 'runtime-only build for nuxt'
|
||||
packageJSON.bin = {
|
||||
'nuxt-start': './bin/nuxt-start'
|
||||
}
|
||||
|
||||
// Update package.json
|
||||
writeFileSync(resolve(startDir, 'package.json'), JSON.stringify(packageJSON, null, 2))
|
||||
|
||||
// Copy required files
|
||||
const excludeFiles = [
|
||||
'README.md',
|
||||
'.gitignore'
|
||||
]
|
||||
packageJSON.files.forEach(file => {
|
||||
if (excludeFiles.indexOf(file) !== -1) {
|
||||
return
|
||||
}
|
||||
let src = resolve(rootDir, file)
|
||||
let dst = resolve(startDir, file)
|
||||
// console.log(relative(rootDir, src), '~>', relative(rootDir, dst))
|
||||
removeSync(dst)
|
||||
copySync(src, dst)
|
||||
})
|
||||
|
||||
// Remove extras
|
||||
const extraFiles = [
|
||||
'bin/nuxt-build',
|
||||
'bin/nuxt-generate',
|
||||
'bin/nuxt-dev',
|
||||
'bin/nuxt',
|
||||
'dist/nuxt.js',
|
||||
'dist/nuxt.js.map'
|
||||
]
|
||||
extraFiles.forEach(file => {
|
||||
removeSync(resolve(startDir, file))
|
||||
})
|
||||
|
||||
// Patch index.js
|
||||
const startIndexjs = resolve(startDir, 'index.js')
|
||||
writeFileSync(startIndexjs, String(readFileSync(startIndexjs)).replace('./dist/nuxt', './dist/core'))
|
||||
|
||||
// Patch bin/nuxt-start
|
||||
const binStart = resolve(startDir, 'bin/nuxt-start')
|
||||
writeFileSync(binStart, String(readFileSync(binStart)).replace(/nuxt start/g, 'nuxt-start'))
|
||||
|
||||
const ms = Date.now() - now
|
||||
console.log(`Generated ${packageJSON.name}@${packageJSON.version} in ${ms}ms`)
|
69
examples/async-component-injection/assets/css/common.css
Normal file
69
examples/async-component-injection/assets/css/common.css
Normal file
@ -0,0 +1,69 @@
|
||||
body {
|
||||
font-family: "Roboto", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, serif;
|
||||
text-rendering: optimizelegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
word-spacing: 1px;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
.header {
|
||||
letter-spacing: 5px;
|
||||
margin: 50px auto 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.header a {
|
||||
font-size: 15px;
|
||||
color: #444;
|
||||
}
|
||||
.links {
|
||||
text-align: center;
|
||||
font-family: "Roboto", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, serif;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
.links a {
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
.links img {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
.header,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
color: #444;
|
||||
}
|
||||
.main {
|
||||
max-width: 600px;
|
||||
margin: 50px auto;
|
||||
padding: 0 30px 50px;
|
||||
position: relative;
|
||||
}
|
||||
@media screen and (max-width: 420px) {
|
||||
.header {
|
||||
margin: 40px auto 10px;
|
||||
}
|
||||
.header a {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
57
examples/async-component-injection/assets/css/index.css
Normal file
57
examples/async-component-injection/assets/css/index.css
Normal file
@ -0,0 +1,57 @@
|
||||
.main > ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.main > ul > li {
|
||||
position: relative;
|
||||
padding: 30px 0 30px;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
}
|
||||
.main > ul > li:first-child {
|
||||
margin-top: -30px;
|
||||
}
|
||||
.main h2,
|
||||
.main h3 {
|
||||
letter-spacing: 1px;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.main h2 {
|
||||
font-size: 20px;
|
||||
letter-spacing: 1px;
|
||||
margin-left: 120px;
|
||||
}
|
||||
.main h2 a {
|
||||
color: #444;
|
||||
}
|
||||
.main h2 a:hover {
|
||||
color: #f33;
|
||||
}
|
||||
.main h3 {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 33px;
|
||||
}
|
||||
@media screen and (max-width: 420px) {
|
||||
.main h2 {
|
||||
font-size: 16px;
|
||||
margin-left: 0;
|
||||
}
|
||||
.main h2 a:hover {
|
||||
color: #f66;
|
||||
}
|
||||
.main h3 {
|
||||
font-size: 11px;
|
||||
position: static;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.main ul li {
|
||||
padding: 18px 0 20px;
|
||||
}
|
||||
.main ul li:first-child {
|
||||
margin-top: -35px;
|
||||
}
|
||||
}
|
307
examples/async-component-injection/assets/css/post.css
Normal file
307
examples/async-component-injection/assets/css/post.css
Normal file
@ -0,0 +1,307 @@
|
||||
.gutter pre {
|
||||
color: #999;
|
||||
}
|
||||
pre {
|
||||
color: #525252;
|
||||
}
|
||||
pre .function .keyword,
|
||||
pre .constant {
|
||||
color: #0092db;
|
||||
}
|
||||
pre .keyword,
|
||||
pre .attribute {
|
||||
color: #e96900;
|
||||
}
|
||||
pre .number,
|
||||
pre .literal {
|
||||
color: #ae81ff;
|
||||
}
|
||||
pre .tag,
|
||||
pre .tag .title,
|
||||
pre .change,
|
||||
pre .winutils,
|
||||
pre .flow,
|
||||
pre .lisp .title,
|
||||
pre .clojure .built_in,
|
||||
pre .nginx .title,
|
||||
pre .tex .special {
|
||||
color: #2973b7;
|
||||
}
|
||||
pre .class .title {
|
||||
color: #fff;
|
||||
}
|
||||
pre .symbol,
|
||||
pre .symbol .string,
|
||||
pre .value,
|
||||
pre .regexp {
|
||||
color: #42b983;
|
||||
}
|
||||
pre .title {
|
||||
color: #a6e22e;
|
||||
}
|
||||
pre .tag .value,
|
||||
pre .string,
|
||||
pre .subst,
|
||||
pre .haskell .type,
|
||||
pre .preprocessor,
|
||||
pre .ruby .class .parent,
|
||||
pre .built_in,
|
||||
pre .sql .aggregate,
|
||||
pre .django .template_tag,
|
||||
pre .django .variable,
|
||||
pre .smalltalk .class,
|
||||
pre .javadoc,
|
||||
pre .django .filter .argument,
|
||||
pre .smalltalk .localvars,
|
||||
pre .smalltalk .array,
|
||||
pre .attr_selector,
|
||||
pre .pseudo,
|
||||
pre .addition,
|
||||
pre .stream,
|
||||
pre .envvar,
|
||||
pre .apache .tag,
|
||||
pre .apache .cbracket,
|
||||
pre .tex .command,
|
||||
pre .prompt {
|
||||
color: #42b983;
|
||||
}
|
||||
pre .comment,
|
||||
pre .java .annotation,
|
||||
pre .python .decorator,
|
||||
pre .template_comment,
|
||||
pre .pi,
|
||||
pre .doctype,
|
||||
pre .deletion,
|
||||
pre .shebang,
|
||||
pre .apache .sqbracket,
|
||||
pre .tex .formula {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
pre .coffeescript .javascript,
|
||||
pre .javascript .xml,
|
||||
pre .tex .formula,
|
||||
pre .xml .javascript,
|
||||
pre .xml .vbscript,
|
||||
pre .xml .css,
|
||||
pre .xml .cdata {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.main .post {
|
||||
position: relative;
|
||||
padding-bottom: 30px;
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
}
|
||||
.main .post h1,
|
||||
.main .post h2 {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
.main .post h1 a:hover,
|
||||
.main .post h2 a:hover {
|
||||
border-bottom: 3px solid #666;
|
||||
}
|
||||
.main .post h1 {
|
||||
font-size: 32px;
|
||||
margin: 0 0 45px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.main .post h2 {
|
||||
font-size: 24px;
|
||||
margin: 60px 0 30px;
|
||||
position: relative;
|
||||
}
|
||||
.main .post h2:before {
|
||||
content: '';
|
||||
border-left: 5px solid #41b883;
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
height: 75%;
|
||||
top: 12%;
|
||||
}
|
||||
.main .post h3 {
|
||||
margin: 30px 0 15px;
|
||||
}
|
||||
.main .post .date {
|
||||
font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
margin: 0 0 30px;
|
||||
letter-spacing: 1px;
|
||||
position: initial;
|
||||
text-transform: none;
|
||||
}
|
||||
.main .post .content {
|
||||
text-align: left;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
.main .post .content p,
|
||||
.main .post .content ul,
|
||||
.main .post .content ol {
|
||||
margin: 1em 0 1.5em;
|
||||
}
|
||||
.main .post .content strong {
|
||||
font-weight: 600;
|
||||
color: #444;
|
||||
}
|
||||
.main .post .content ol {
|
||||
padding-left: 1.6em;
|
||||
}
|
||||
.main .post .content ul {
|
||||
padding-left: 15px;
|
||||
list-style-type: none;
|
||||
}
|
||||
.main .post .content ul li:before {
|
||||
position: absolute;
|
||||
font-weight: 600;
|
||||
content: " · ";
|
||||
margin: 0;
|
||||
left: 0;
|
||||
}
|
||||
.main .post .content a {
|
||||
color: #41b883;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
.main .post .content a:hover {
|
||||
color: #41b883;
|
||||
border-bottom-color: #41b883;
|
||||
}
|
||||
.main .post .content .highlight,
|
||||
.main .post .content .highlight table {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.main .post .content .highlight {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.main .post .content .highlight table,
|
||||
.main .post .content .highlight tr,
|
||||
.main .post .content .highlight td {
|
||||
padding: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.main .post .content code {
|
||||
font-family: "Roboto Mono", "Menlo", "Consolas", monospace;
|
||||
font-size: 13px;
|
||||
background-color: #f6f6f6;
|
||||
padding: 3px 10px;
|
||||
margin: 0 5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.main .post .content pre {
|
||||
font-family: "Roboto Mono", "Menlo", "Consolas", monospace;
|
||||
font-size: 13px;
|
||||
overflow-x: auto;
|
||||
text-align: left;
|
||||
padding: 15px 25px;
|
||||
background-color: #f6f6f6;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
.main .post .content .code pre {
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
.main .post .content .gutter pre {
|
||||
padding: 15px 0 15px 15px;
|
||||
color: #75715e;
|
||||
border-top-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
}
|
||||
.main .post .content blockquote {
|
||||
margin: 2em 0;
|
||||
padding-left: 30px;
|
||||
border-left: 5px solid #e6e6e6;
|
||||
}
|
||||
.main .post .content blockquote p {
|
||||
font-size: 17px;
|
||||
font-style: italic;
|
||||
line-height: 1.8em;
|
||||
color: #999;
|
||||
}
|
||||
.main .post img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
.blog-nav {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
letter-spacing: 1px;
|
||||
border-bottom: 3px solid transparent;
|
||||
}
|
||||
.blog-nav:hover {
|
||||
color: #333;
|
||||
border-bottom-color: #333;
|
||||
}
|
||||
#newer {
|
||||
left: 40px;
|
||||
}
|
||||
#older {
|
||||
right: 40px;
|
||||
}
|
||||
.show-comments {
|
||||
font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
.show-comments a {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
}
|
||||
.show-comments a:hover {
|
||||
color: #666;
|
||||
}
|
||||
@media screen and (max-width: 900px) {
|
||||
.main .post {
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
.blog-nav {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
}
|
||||
#newer {
|
||||
left: 0;
|
||||
}
|
||||
#older {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 420px) {
|
||||
.main {
|
||||
margin-top: 32px;
|
||||
}
|
||||
.main .post h1 {
|
||||
font-size: 24px;
|
||||
margin: 0 0 30px;
|
||||
}
|
||||
.main .post h2 {
|
||||
font-size: 20px;
|
||||
margin: 30px 0 15px;
|
||||
}
|
||||
.main .post h3 {
|
||||
font-size: 16px;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
.main .post .date {
|
||||
font-size: 12px;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
.main .post .content {
|
||||
font-size: 15px;
|
||||
}
|
||||
.main .post .content pre {
|
||||
font-size: 12px;
|
||||
}
|
||||
.main .post .content blockquote p {
|
||||
font-size: 16px;
|
||||
}
|
||||
.blog-nav {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
}
|
||||
}
|
BIN
examples/async-component-injection/assets/img/github.png
Normal file
BIN
examples/async-component-injection/assets/img/github.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
examples/async-component-injection/assets/img/swimmer.jpg
Normal file
BIN
examples/async-component-injection/assets/img/swimmer.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
BIN
examples/async-component-injection/assets/img/twitter.png
Normal file
BIN
examples/async-component-injection/assets/img/twitter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
15
examples/async-component-injection/layouts/default.vue
Normal file
15
examples/async-component-injection/layouts/default.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<nuxt-link to="/">NUXT BLOG</nuxt-link>
|
||||
</div>
|
||||
<p class="links">
|
||||
<a href="https://twitter.com/nuxt_js" target="_blank"><img src="~/assets/img/twitter.png"></a>
|
||||
<a href="https://github.com/nuxt/nuxt.js/tree/dev/examples/async-component-injection" target="_blank"><img src="~/assets/img/github.png"></a>
|
||||
</p>
|
||||
<div class="main">
|
||||
<nuxt/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
22
examples/async-component-injection/nuxt.config.js
Normal file
22
examples/async-component-injection/nuxt.config.js
Normal file
@ -0,0 +1,22 @@
|
||||
module.exports = {
|
||||
head: {
|
||||
title: 'Nuxt Blog',
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' }
|
||||
],
|
||||
link: [
|
||||
{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' },
|
||||
{ rel: 'stylesheet', href: 'http://fonts.googleapis.com/css?family=Montserrat|Roboto:400,400italic,600|Roboto+Mono', type: 'text/css' }
|
||||
]
|
||||
},
|
||||
css: [
|
||||
'@/assets/css/common.css'
|
||||
],
|
||||
generate: {
|
||||
routes: [
|
||||
'/deep-dive-into-ocean',
|
||||
'/welcome-to-my-blog'
|
||||
]
|
||||
}
|
||||
}
|
11
examples/async-component-injection/package.json
Normal file
11
examples/async-component-injection/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "components-injection-nuxt",
|
||||
"dependencies": {
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt"
|
||||
}
|
||||
}
|
21
examples/async-component-injection/pages/_slug.vue
Normal file
21
examples/async-component-injection/pages/_slug.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="post">
|
||||
<component :is="component"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// See https://vuejs.org/v2/guide/components.html#Advanced-Async-Components
|
||||
const getPost = (slug) => ({
|
||||
component: import(`@/posts/${slug}`),
|
||||
error: require('@/posts/404')
|
||||
})
|
||||
|
||||
export default {
|
||||
beforeCreate() {
|
||||
this.component = () => getPost(this.$route.params.slug)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style src="@/assets/css/post.css"/>
|
22
examples/async-component-injection/pages/index.vue
Normal file
22
examples/async-component-injection/pages/index.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="(post, index) in posts" :key="index">
|
||||
<h3>{{ post.date }}</h3>
|
||||
<h2><nuxt-link :to="post.link">{{ post.title }}</nuxt-link></h2>
|
||||
</li>
|
||||
<li style="border:none;text-align: center;font-size: 14px;">Design from <a href="http://blog.evanyou.me" target="_blank">EvanYou.me</a></li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
posts: [
|
||||
{ date: 'Jul 10, 2017', title: 'Deep dive into the Ocean', link: '/deep-dive-into-ocean' },
|
||||
{ date: 'Jul 08, 2017', title: 'Welcome to my blog', link: '/welcome-to-my-blog' }
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style src="@/assets/css/index.css"/>
|
3
examples/async-component-injection/posts/404.vue
Normal file
3
examples/async-component-injection/posts/404.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<h1 style="text-align: center;">Article not found</h1>
|
||||
</template>
|
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="date">Jul 10, 2017</h3>
|
||||
<h1>Deep dive into the Ocean</h1>
|
||||
<div class="content">
|
||||
<img src="~/assets/img/swimmer.jpg">
|
||||
<h2>Subtitle #1</h2>
|
||||
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth. Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.</p>
|
||||
<h2>Another subtitle</h2>
|
||||
<ul>
|
||||
<li>Vue.js</li>
|
||||
<li>Nuxt.js</li>
|
||||
<li>= <3</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="date">Jul 08, 2017</h3>
|
||||
<h1>Welcome to my blog</h1>
|
||||
<div class="content">
|
||||
<h2>What is Lorem Ipsum?</h2>
|
||||
<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
BIN
examples/async-component-injection/static/favicon.ico
Normal file
BIN
examples/async-component-injection/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -6,5 +6,13 @@ module.exports = {
|
||||
color: '#4FC08D',
|
||||
failedColor: '#bf5050',
|
||||
duration: 1500
|
||||
},
|
||||
head: {
|
||||
title: 'Default title'
|
||||
},
|
||||
generate: {
|
||||
routes: [
|
||||
'/posts/1'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "nuxt-async-data",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"axios": "^0.15.2",
|
||||
"axios": "latest",
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -9,14 +9,9 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData ({ req }, callback) {
|
||||
setTimeout(function () {
|
||||
// callback(err, data)
|
||||
callback(null, {
|
||||
userAgent: (req ? req.headers['user-agent'] : navigator.userAgent)
|
||||
})
|
||||
}, 100)
|
||||
}
|
||||
asyncData: ({ req }) => ({
|
||||
userAgent: (req ? req.headers['user-agent'] : (typeof navigator !== 'undefined' ? navigator.userAgent : 'No user agent (generated)'))
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -11,12 +11,12 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
async asyncData ({ params }) {
|
||||
async asyncData({ params }) {
|
||||
// We can use async/await ES6 feature
|
||||
let { data } = await axios.get(`https://jsonplaceholder.typicode.com/posts/${params.id}`)
|
||||
return { post: data }
|
||||
},
|
||||
head () {
|
||||
head() {
|
||||
return {
|
||||
title: this.post.title
|
||||
}
|
||||
|
@ -15,12 +15,15 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
asyncData ({ req, params }) {
|
||||
asyncData({ req, params }) {
|
||||
// We can return a Promise instead of calling the callback
|
||||
return axios.get('https://jsonplaceholder.typicode.com/posts')
|
||||
.then((res) => {
|
||||
return { posts: res.data.slice(0, 5) }
|
||||
})
|
||||
.then((res) => {
|
||||
return { posts: res.data.slice(0, 5) }
|
||||
})
|
||||
},
|
||||
head: {
|
||||
title: 'List of posts'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
36
examples/auth-routes/api/index.js
Normal file
36
examples/auth-routes/api/index.js
Normal file
@ -0,0 +1,36 @@
|
||||
const express = require('express')
|
||||
|
||||
// Create express router
|
||||
const router = express.Router()
|
||||
|
||||
// Transform req & res to have the same API as express
|
||||
// So we can use res.status() & res.json()
|
||||
var app = express()
|
||||
router.use((req, res, next) => {
|
||||
Object.setPrototypeOf(req, app.request)
|
||||
Object.setPrototypeOf(res, app.response)
|
||||
req.res = res
|
||||
res.req = req
|
||||
next()
|
||||
})
|
||||
|
||||
// Add POST - /api/login
|
||||
router.post('/login', (req, res) => {
|
||||
if (req.body.username === 'demo' && req.body.password === 'demo') {
|
||||
req.session.authUser = { username: 'demo' }
|
||||
return res.json({ username: 'demo' })
|
||||
}
|
||||
res.status(401).json({ message: 'Bad credentials' })
|
||||
})
|
||||
|
||||
// Add POST - /api/logout
|
||||
router.post('/logout', (req, res) => {
|
||||
delete req.session.authUser
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// Export the server middleware
|
||||
module.exports = {
|
||||
path: '/api',
|
||||
handler: router
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
export default function ({ store, redirect, error }) {
|
||||
// If user not connected, redirect to /
|
||||
export default function ({ store, error }) {
|
||||
if (!store.state.authUser) {
|
||||
// return redirect('/')
|
||||
error({
|
||||
message: 'You are not connected',
|
||||
statusCode: 403
|
||||
|
@ -1,3 +1,6 @@
|
||||
const bodyParser = require('body-parser')
|
||||
const session = require('express-session')
|
||||
|
||||
module.exports = {
|
||||
head: {
|
||||
title: 'Auth Routes',
|
||||
@ -9,5 +12,24 @@ module.exports = {
|
||||
},
|
||||
build: {
|
||||
vendor: ['axios']
|
||||
}
|
||||
},
|
||||
/*
|
||||
** Add server middleware
|
||||
** Nuxt.js uses `connect` module as server
|
||||
** So most of express middleware works with nuxt.js server middleware
|
||||
*/
|
||||
serverMiddleware: [
|
||||
// body-parser middleware
|
||||
bodyParser.json(),
|
||||
// session middleware
|
||||
session({
|
||||
secret: 'super-secret-key',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: { maxAge: 60000 }
|
||||
}),
|
||||
// Api middleware
|
||||
// We add /api/login & /api/logout routes
|
||||
'~/api'
|
||||
]
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
{
|
||||
"name": "auth-routes",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"axios": "^0.16.1",
|
||||
"body-parser": "^1.17.2",
|
||||
"cross-env": "^5.0.0",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"nuxt": "^1.0.0-alpha1"
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "node server.js",
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "cross-env NODE_ENV=production node server.js"
|
||||
"start": "nuxt start"
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
formError: null,
|
||||
formUsername: '',
|
||||
@ -28,22 +28,25 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
login () {
|
||||
this.$store.dispatch('login', {
|
||||
username: this.formUsername,
|
||||
password: this.formPassword
|
||||
})
|
||||
.then(() => {
|
||||
async login() {
|
||||
try {
|
||||
await this.$store.dispatch('login', {
|
||||
username: this.formUsername,
|
||||
password: this.formPassword
|
||||
})
|
||||
this.formUsername = ''
|
||||
this.formPassword = ''
|
||||
this.formError = null
|
||||
})
|
||||
.catch((e) => {
|
||||
} catch (e) {
|
||||
this.formError = e.message
|
||||
})
|
||||
}
|
||||
},
|
||||
logout () {
|
||||
this.$store.dispatch('logout')
|
||||
async logout() {
|
||||
try {
|
||||
await this.$store.dispatch('logout')
|
||||
} catch (e) {
|
||||
this.formError = e.message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Super secret page</h1>
|
||||
<p>If you try to access this URL not connected, you will be redirected to the home page (server-side or client-side)</p>
|
||||
<p>If you try to access this URL not connected, you will see the error page telling your that you are not connected.</p>
|
||||
<nuxt-link to="/">Back to the home page</nuxt-link>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,56 +0,0 @@
|
||||
const Nuxt = require('nuxt')
|
||||
const bodyParser = require('body-parser')
|
||||
const session = require('express-session')
|
||||
const app = require('express')()
|
||||
|
||||
const host = process.env.HOST || '127.0.0.1'
|
||||
const port = process.env.PORT || '3000'
|
||||
|
||||
// Body parser, to access req.body
|
||||
app.use(bodyParser.json())
|
||||
|
||||
// Sessions to create req.session
|
||||
app.use(session({
|
||||
secret: 'super-secret-key',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: { maxAge: 60000 }
|
||||
}))
|
||||
|
||||
// POST /api/login to log in the user and add him to the req.session.authUser
|
||||
app.post('/api/login', function (req, res) {
|
||||
if (req.body.username === 'demo' && req.body.password === 'demo') {
|
||||
req.session.authUser = { username: 'demo' }
|
||||
return res.json({ username: 'demo' })
|
||||
}
|
||||
res.status(401).json({ message: 'Bad credentials' })
|
||||
})
|
||||
|
||||
// POST /api/logout to log out the user and remove it from the req.session
|
||||
app.post('/api/logout', function (req, res) {
|
||||
delete req.session.authUser
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// Import and Set Nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
// Init Nuxt.js
|
||||
new Nuxt(config)
|
||||
.then((nuxt) => {
|
||||
// nuxt middlware
|
||||
app.use(nuxt.render)
|
||||
// Build only in dev mode
|
||||
if (config.dev) {
|
||||
nuxt.build()
|
||||
.catch((error) => {
|
||||
console.error(error) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
}
|
||||
// Listen the server
|
||||
app.listen(port, host)
|
||||
console.log('Server listening on ' + host + ':' + port) // eslint-disable-line no-console
|
||||
})
|
||||
|
@ -11,31 +11,27 @@ export const mutations = {
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
nuxtServerInit ({ commit }, { req }) {
|
||||
// nuxtServerInit is called by Nuxt.js before server-rendering every page
|
||||
nuxtServerInit({ commit }, { req }) {
|
||||
if (req.session && req.session.authUser) {
|
||||
commit('SET_USER', req.session.authUser)
|
||||
}
|
||||
},
|
||||
login ({ commit }, { username, password }) {
|
||||
return axios.post('/api/login', {
|
||||
username,
|
||||
password
|
||||
})
|
||||
.then((res) => {
|
||||
commit('SET_USER', res.data)
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response.status === 401) {
|
||||
async login({ commit }, { username, password }) {
|
||||
try {
|
||||
const { data } = await axios.post('/api/login', { username, password })
|
||||
commit('SET_USER', data)
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 401) {
|
||||
throw new Error('Bad credentials')
|
||||
}
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
logout ({ commit }) {
|
||||
return axios.post('/api/logout')
|
||||
.then(() => {
|
||||
commit('SET_USER', null)
|
||||
})
|
||||
async logout({ commit }) {
|
||||
await axios.post('/api/logout')
|
||||
commit('SET_USER', null)
|
||||
}
|
||||
|
||||
}
|
||||
|
32
examples/axios/README.md
Normal file
32
examples/axios/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Axios Proxy Example
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
$ yarn add @nuxtjs/axios @nuxtjs/proxy
|
||||
```
|
||||
|
||||
## Nuxt.config.js
|
||||
|
||||
```json
|
||||
{
|
||||
modules: [
|
||||
'@nuxtjs/axios',
|
||||
'@nuxtjs/proxy'
|
||||
],
|
||||
proxy: [
|
||||
['/api/dog', { target: 'https://dog.ceo/', pathRewrite: { '^/api/dog': '/api/breeds/image/random' } }]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Use Axios
|
||||
|
||||
```js
|
||||
async asyncData({ app }) {
|
||||
const ip = await app.$axios.$get('http://icanhazip.com')
|
||||
return { ip }
|
||||
}
|
||||
```
|
||||
|
||||
More detail, please refer [axios-module](https://github.com/nuxt-community/axios-module).
|
9
examples/axios/nuxt.config.js
Normal file
9
examples/axios/nuxt.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
modules: [
|
||||
'@nuxtjs/axios',
|
||||
'@nuxtjs/proxy'
|
||||
],
|
||||
proxy: [
|
||||
['/api/dog', { target: 'https://dog.ceo/', pathRewrite: { '^/api/dog': '/api/breeds/image/random' } }]
|
||||
]
|
||||
}
|
14
examples/axios/package.json
Normal file
14
examples/axios/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "nuxt-proxy",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@nuxtjs/axios": "^4.4.0",
|
||||
"@nuxtjs/proxy": "^1.1.2",
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start"
|
||||
}
|
||||
}
|
17
examples/axios/pages/index.vue
Normal file
17
examples/axios/pages/index.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Dog</h1>
|
||||
<img :src="dog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
|
||||
async asyncData({ app }) {
|
||||
const { data: { message: dog } } = await app.$axios.get('/dog')
|
||||
return { dog }
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
build: {
|
||||
ssr: {
|
||||
render: {
|
||||
bundleRenderer: {
|
||||
cache: require('lru-cache')({
|
||||
max: 1000,
|
||||
maxAge: 1000 * 60 * 15
|
||||
|
@ -9,11 +9,11 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'date',
|
||||
serverCacheKey () {
|
||||
serverCacheKey() {
|
||||
// Will change every 10 secondes
|
||||
return Math.floor(Date.now() / 10000)
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return { date: Date.now() }
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,19 @@
|
||||
module.exports = {
|
||||
build: {
|
||||
filenames: {
|
||||
css: 'styles.[chunkhash].css', // default: common.[chunkhash].css
|
||||
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
||||
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
||||
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
||||
css: 'styles.[chunkhash].css', // default: common.[chunkhash].css
|
||||
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
||||
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
||||
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
||||
},
|
||||
vendor: ['lodash'],
|
||||
// Loaders config (Webpack 2)
|
||||
loaders: [
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 100000, // 100KO
|
||||
name: 'img/[name].[ext]?[hash]'
|
||||
}
|
||||
}
|
||||
],
|
||||
extend (config, { dev }) {
|
||||
if (dev) {
|
||||
config.devtool = (dev ? 'eval-source-map' : false)
|
||||
extend(config, { isDev }) {
|
||||
if (isDev) {
|
||||
config.devtool = 'eval-source-map'
|
||||
}
|
||||
const urlLoader = config.module.rules.find((loader) => loader.loader === 'url-loader')
|
||||
// Increase limit to 100KO
|
||||
urlLoader.query.limit = 100000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<p><img src="~assets/nuxt.png" /></p>
|
||||
<p><img src="~/assets/nuxt.png" /></p>
|
||||
<p>This image is included as data:image/png;base64...</p>
|
||||
<p>In the source code, the files generated are based on the build.filenames data.</p>
|
||||
<p>If you look at the <a href="/_nuxt/vendor.js">vendor.js</a>, lodash has been included (cmd/ctrl + F "lodash").</p>
|
||||
|
@ -5,6 +5,9 @@
|
||||
</template>
|
||||
|
||||
<style>
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
.dark {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -8,7 +8,7 @@
|
||||
<script>
|
||||
export default {
|
||||
layout: 'dark',
|
||||
asyncData ({ req }) {
|
||||
asyncData({ req }) {
|
||||
return {
|
||||
name: req ? 'server' : 'client'
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<template lang="html">
|
||||
<template>
|
||||
<div class="loading-page" v-if="loading">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
@ -10,10 +10,10 @@ export default {
|
||||
loading: false
|
||||
}),
|
||||
methods: {
|
||||
start () {
|
||||
start() {
|
||||
this.loading = true
|
||||
},
|
||||
finish () {
|
||||
finish() {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
loading: 'components/loading.vue'
|
||||
loading: '~/components/loading.vue'
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData () {
|
||||
asyncData() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(function () {
|
||||
resolve({})
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData () {
|
||||
asyncData() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(function () {
|
||||
resolve({ name: 'world' })
|
||||
|
@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "nuxt-custom-routes",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"axios": "^0.15.2",
|
||||
"axios": "latest",
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -13,11 +13,9 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
asyncData () {
|
||||
return axios.get('https://jsonplaceholder.typicode.com/users')
|
||||
.then((res) => {
|
||||
return { users: res.data }
|
||||
})
|
||||
async asyncData() {
|
||||
const { data } = await axios.get('https://jsonplaceholder.typicode.com/users')
|
||||
return { users: data }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -11,15 +11,16 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
validate ({ params }) {
|
||||
validate({ params }) {
|
||||
return !isNaN(+params.id)
|
||||
},
|
||||
asyncData ({ params, error }) {
|
||||
return axios.get(`https://jsonplaceholder.typicode.com/users/${+params.id}`)
|
||||
.then((res) => res.data)
|
||||
.catch(() => {
|
||||
async asyncData({ params, error }) {
|
||||
try {
|
||||
const { data } = await axios.get(`https://jsonplaceholder.typicode.com/users/${+params.id}`)
|
||||
return data
|
||||
} catch (e) {
|
||||
error({ message: 'User not found', statusCode: 404 })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
1
examples/custom-server/nuxt.config.js
Normal file
1
examples/custom-server/nuxt.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = {}
|
12
examples/custom-server/package.json
Normal file
12
examples/custom-server/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "nuxt-custom-server",
|
||||
"dependencies": {
|
||||
"express": "^4.15.3",
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "node server.js",
|
||||
"build": "nuxt build",
|
||||
"start": "NODE_ENV=production node server.js"
|
||||
}
|
||||
}
|
3
examples/custom-server/pages/index.vue
Normal file
3
examples/custom-server/pages/index.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<p>Please look at <code>server.js</code> to see how to use <a href="https://nuxtjs.org">Nuxt.js</a> programmatically.</p>
|
||||
</template>
|
23
examples/custom-server/server.js
Normal file
23
examples/custom-server/server.js
Normal file
@ -0,0 +1,23 @@
|
||||
const app = require('express')()
|
||||
const { Nuxt, Builder } = require('nuxt')
|
||||
|
||||
const host = process.env.HOST || '127.0.0.1'
|
||||
const port = process.env.PORT || 3000
|
||||
|
||||
// Import and set Nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
const nuxt = new Nuxt(config)
|
||||
|
||||
// Start build process in dev mode
|
||||
if (config.dev) {
|
||||
const builder = new Builder(nuxt)
|
||||
builder.build()
|
||||
}
|
||||
|
||||
// Give nuxt middleware to express
|
||||
app.use(nuxt.render)
|
||||
|
||||
// Start express server
|
||||
app.listen(port, host)
|
5
examples/dynamic-components/README.md
Normal file
5
examples/dynamic-components/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Dynamic Components with Nuxt.js
|
||||
|
||||
Demo: https://dynamic-components.nuxtjs.org/
|
||||
|
||||
Video: https://www.youtube.com/watch?v=HzDea5-PFaw
|
12
examples/dynamic-components/components/chart.js
Normal file
12
examples/dynamic-components/components/chart.js
Normal file
@ -0,0 +1,12 @@
|
||||
let VueChart = import('vue-chartjs' /* webpackChunkName: "vue-chartjs" */)
|
||||
|
||||
export default async () => {
|
||||
VueChart = await VueChart
|
||||
|
||||
return VueChart.Bar.extend({
|
||||
props: ['data'],
|
||||
mounted() {
|
||||
this.renderChart(this.data)
|
||||
}
|
||||
})
|
||||
}
|
20
examples/dynamic-components/components/code.vue
Normal file
20
examples/dynamic-components/components/code.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<pre>{{ data }}</pre>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
data: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
pre {
|
||||
background: #222;
|
||||
color: #eee;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
38
examples/dynamic-components/components/image.vue
Normal file
38
examples/dynamic-components/components/image.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<img v-if="loaded" :src="data" alt="image" />
|
||||
<svg v-else width="60px" height="60px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-ring"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><defs><filter id="uil-ring-shadow" x="-100%" y="-100%" width="300%" height="300%"><feOffset result="offOut" in="SourceGraphic" dx="0" dy="0"></feOffset><feGaussianBlur result="blurOut" in="offOut" stdDeviation="0"></feGaussianBlur><feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend></filter></defs><path d="M10,50c0,0,0,0.5,0.1,1.4c0,0.5,0.1,1,0.2,1.7c0,0.3,0.1,0.7,0.1,1.1c0.1,0.4,0.1,0.8,0.2,1.2c0.2,0.8,0.3,1.8,0.5,2.8 c0.3,1,0.6,2.1,0.9,3.2c0.3,1.1,0.9,2.3,1.4,3.5c0.5,1.2,1.2,2.4,1.8,3.7c0.3,0.6,0.8,1.2,1.2,1.9c0.4,0.6,0.8,1.3,1.3,1.9 c1,1.2,1.9,2.6,3.1,3.7c2.2,2.5,5,4.7,7.9,6.7c3,2,6.5,3.4,10.1,4.6c3.6,1.1,7.5,1.5,11.2,1.6c4-0.1,7.7-0.6,11.3-1.6 c3.6-1.2,7-2.6,10-4.6c3-2,5.8-4.2,7.9-6.7c1.2-1.2,2.1-2.5,3.1-3.7c0.5-0.6,0.9-1.3,1.3-1.9c0.4-0.6,0.8-1.3,1.2-1.9 c0.6-1.3,1.3-2.5,1.8-3.7c0.5-1.2,1-2.4,1.4-3.5c0.3-1.1,0.6-2.2,0.9-3.2c0.2-1,0.4-1.9,0.5-2.8c0.1-0.4,0.1-0.8,0.2-1.2 c0-0.4,0.1-0.7,0.1-1.1c0.1-0.7,0.1-1.2,0.2-1.7C90,50.5,90,50,90,50s0,0.5,0,1.4c0,0.5,0,1,0,1.7c0,0.3,0,0.7,0,1.1 c0,0.4-0.1,0.8-0.1,1.2c-0.1,0.9-0.2,1.8-0.4,2.8c-0.2,1-0.5,2.1-0.7,3.3c-0.3,1.2-0.8,2.4-1.2,3.7c-0.2,0.7-0.5,1.3-0.8,1.9 c-0.3,0.7-0.6,1.3-0.9,2c-0.3,0.7-0.7,1.3-1.1,2c-0.4,0.7-0.7,1.4-1.2,2c-1,1.3-1.9,2.7-3.1,4c-2.2,2.7-5,5-8.1,7.1 c-0.8,0.5-1.6,1-2.4,1.5c-0.8,0.5-1.7,0.9-2.6,1.3L66,87.7l-1.4,0.5c-0.9,0.3-1.8,0.7-2.8,1c-3.8,1.1-7.9,1.7-11.8,1.8L47,90.8 c-1,0-2-0.2-3-0.3l-1.5-0.2l-0.7-0.1L41.1,90c-1-0.3-1.9-0.5-2.9-0.7c-0.9-0.3-1.9-0.7-2.8-1L34,87.7l-1.3-0.6 c-0.9-0.4-1.8-0.8-2.6-1.3c-0.8-0.5-1.6-1-2.4-1.5c-3.1-2.1-5.9-4.5-8.1-7.1c-1.2-1.2-2.1-2.7-3.1-4c-0.5-0.6-0.8-1.4-1.2-2 c-0.4-0.7-0.8-1.3-1.1-2c-0.3-0.7-0.6-1.3-0.9-2c-0.3-0.7-0.6-1.3-0.8-1.9c-0.4-1.3-0.9-2.5-1.2-3.7c-0.3-1.2-0.5-2.3-0.7-3.3 c-0.2-1-0.3-2-0.4-2.8c-0.1-0.4-0.1-0.8-0.1-1.2c0-0.4,0-0.7,0-1.1c0-0.7,0-1.2,0-1.7C10,50.5,10,50,10,50z" fill="#59ebff" filter="url(#uil-ring-shadow)"><animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50" repeatCount="indefinite" dur="1s"></animateTransform></path></svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
data: String
|
||||
},
|
||||
data: () => ({
|
||||
loaded: false
|
||||
}),
|
||||
beforeMount() {
|
||||
// Preload image
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
this.loaded = true
|
||||
}
|
||||
img.src = this.data
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
img {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
svg {
|
||||
margin: 20px;
|
||||
margin-left: 50%;
|
||||
position: relative;
|
||||
left: -30px;
|
||||
}
|
||||
</style>
|
17
examples/dynamic-components/components/text.vue
Normal file
17
examples/dynamic-components/components/text.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>
|
27
examples/dynamic-components/js/messages.js
Normal file
27
examples/dynamic-components/js/messages.js
Normal file
@ -0,0 +1,27 @@
|
||||
export const messages = [
|
||||
{ component: 'vText', data: 'Welcome to the <b>Dynamic Component</b> demo!' },
|
||||
{ component: 'vImage', data: 'https://placeimg.com/350/200/animals' },
|
||||
{ component: 'vCode', data: 'var a = 1;\nvar b = 2;\nb = a;' },
|
||||
{
|
||||
component: 'vChart',
|
||||
data: {
|
||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Activity',
|
||||
backgroundColor: '#41b883',
|
||||
data: [40, 20, 12, 39, 10, 40, 39, 50, 40, 20, 12, 11]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{ component: 'vText', data: 'End of demo 🎉' }
|
||||
]
|
||||
|
||||
async function streamMessages(fn, i = 0) {
|
||||
if (i >= messages.length) return
|
||||
await fn(messages[i])
|
||||
setTimeout(() => streamMessages(fn, i + 1), 1500)
|
||||
}
|
||||
|
||||
export default streamMessages
|
9
examples/dynamic-components/nuxt.config.js
Normal file
9
examples/dynamic-components/nuxt.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
head: {
|
||||
titleTemplate: 'Nuxt.js - Dynamic Components',
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||
]
|
||||
}
|
||||
}
|
14
examples/dynamic-components/package.json
Normal file
14
examples/dynamic-components/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "dynamic-components-nuxt",
|
||||
"dependencies": {
|
||||
"chart.js": "^2.7.0",
|
||||
"nuxt": "latest",
|
||||
"vue-chartjs": "^2.8.7"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate"
|
||||
}
|
||||
}
|
71
examples/dynamic-components/pages/index.vue
Executable file
71
examples/dynamic-components/pages/index.vue
Executable file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Nuxt Chat</h1>
|
||||
<transition-group name="list" tag="ul">
|
||||
<li v-for="(message, index) in messages" :key="index">
|
||||
<component :is="message.component" :data="message.data"></component>
|
||||
</li>
|
||||
</transition-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import streamMessages from '@/js/messages.js'
|
||||
// Dynamic components
|
||||
const components = {
|
||||
vText: () => import('@/components/text.vue' /* webpackChunkName: "components/text" */),
|
||||
vImage: () => import('@/components/image.vue' /* webpackChunkName: "components/image" */),
|
||||
vCode: () => import('@/components/code.vue' /* webpackChunkName: "components/code" */),
|
||||
vChart: () => import('@/components/chart.js' /* webpackChunkName: "components/chart" */).then((m) => m.default())
|
||||
}
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
messages: []
|
||||
}),
|
||||
mounted() {
|
||||
// Listen for incoming messages
|
||||
streamMessages(async (message) => {
|
||||
// Wait for the component to load before displaying it
|
||||
await components[message.component]()
|
||||
// Add the message to the list
|
||||
this.messages.push(message)
|
||||
})
|
||||
},
|
||||
components
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
ul li {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 5px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
background: white;
|
||||
border: 1px #ddd solid;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
}
|
||||
.list-enter-active, .list-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.list-enter, .list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
</style>
|
63
examples/dynamic-components/pages/ssr.vue
Normal file
63
examples/dynamic-components/pages/ssr.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Nuxt Chat</h1>
|
||||
<transition-group name="list" tag="ul">
|
||||
<li v-for="(message, index) in messages" :key="index">
|
||||
<component :is="message.component" :data="message.data"></component>
|
||||
</li>
|
||||
</transition-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { messages } from '@/js/messages.js'
|
||||
|
||||
// Dynamic components
|
||||
const components = {
|
||||
vText: () => import('@/components/text.vue' /* webpackChunkName: "components/text" */),
|
||||
vImage: () => import('@/components/image.vue' /* webpackChunkName: "components/image" */),
|
||||
vCode: () => import('@/components/code.vue' /* webpackChunkName: "components/code" */),
|
||||
vChart: () => import('@/components/chart.js' /* webpackChunkName: "components/chart" */).then((m) => m.default())
|
||||
}
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
messages
|
||||
}),
|
||||
components
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
with: 100%;
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
ul li {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 5px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
background: white;
|
||||
border: 1px #ddd solid;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
}
|
||||
.list-enter-active, .list-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.list-enter, .list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
</style>
|
@ -8,7 +8,7 @@
|
||||
<script>
|
||||
export default {
|
||||
layout: ({ isMobile }) => isMobile ? 'mobile' : 'default',
|
||||
asyncData ({ req }) {
|
||||
asyncData({ req }) {
|
||||
return {
|
||||
name: req ? 'server' : 'client'
|
||||
}
|
||||
|
@ -7,6 +7,6 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
layout: ({ isMobile }) => isMobile ? 'mobile' : 'default',
|
||||
layout: ({ isMobile }) => isMobile ? 'mobile' : 'default'
|
||||
}
|
||||
</script>
|
||||
|
BIN
examples/global-css/assets/roboto.woff2
Normal file
BIN
examples/global-css/assets/roboto.woff2
Normal file
Binary file not shown.
@ -1,3 +1,11 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/roboto.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #eee;
|
||||
text-align: center;
|
||||
@ -7,6 +15,7 @@ body {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
.content {
|
||||
margin-top: 100px;
|
||||
|
@ -1,12 +1,20 @@
|
||||
const { join } = require('path')
|
||||
|
||||
module.exports = {
|
||||
head: {
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', name: 'description', content: 'Meta description' }
|
||||
]
|
||||
},
|
||||
css: [
|
||||
'hover.css/css/hover-min.css',
|
||||
'bulma/bulma.sass',
|
||||
join(__dirname, 'css/main.css')
|
||||
'bulma/css/bulma.css',
|
||||
'~/css/main.css'
|
||||
],
|
||||
build: {
|
||||
extractCSS: true
|
||||
render: {
|
||||
bundleRenderer: {
|
||||
shouldPreload: (file, type) => {
|
||||
return ['script', 'style', 'font'].includes(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
{
|
||||
"name": "nuxt-global-css",
|
||||
"dependencies": {
|
||||
"bulma": "^0.4.0",
|
||||
"hover.css": "^2.2.0",
|
||||
"node-sass": "^4.5.1",
|
||||
"nuxt": "^0.10.0",
|
||||
"sass-loader": "^6.0.3"
|
||||
"bulma": "^0.5.1",
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
|
@ -1,3 +0,0 @@
|
||||
# Updating headers with Nuxt.js
|
||||
|
||||
https://nuxtjs.org/examples/seo-html-head
|
@ -1,11 +1,11 @@
|
||||
<script>
|
||||
export default {
|
||||
asyncData ({ req }) {
|
||||
asyncData({ req }) {
|
||||
return {
|
||||
name: req ? 'server' : 'client'
|
||||
}
|
||||
},
|
||||
render (h) {
|
||||
render(h) {
|
||||
return <div>
|
||||
<p>Hi from {this.name}</p>
|
||||
<nuxt-link to="/">Home page</nuxt-link>
|
||||
|
@ -1,10 +1,8 @@
|
||||
<script>
|
||||
export default {
|
||||
render (h) {
|
||||
render(h) {
|
||||
return <div>
|
||||
<h1>Welcome!</h1>
|
||||
<h1>Welcome !</h1>
|
||||
<nuxt-link to="/about">About page</nuxt-link>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</script>
|
@ -4,6 +4,8 @@
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "nuxt"
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start"
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData ({ req }) {
|
||||
asyncData() {
|
||||
return {
|
||||
name: req ? 'server' : 'client'
|
||||
name: process.static ? 'static' : (process.server ? 'server' : 'client')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
path (url) {
|
||||
path(url) {
|
||||
return (this.$i18n.locale === 'en' ? url : '/' + this.$i18n.locale + url)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
export default function ({ app, store, route, params, error, redirect, hotReload }) {
|
||||
// Check if middleware called from hot-reloading, ignore
|
||||
if (hotReload) return
|
||||
export default function ({ isHMR, app, store, route, params, error, redirect }) {
|
||||
// If middleware is called from hot module replacement, ignore it
|
||||
if (isHMR) return
|
||||
// Get locale from params
|
||||
const locale = params.lang || 'en'
|
||||
if (store.state.locales.indexOf(locale) === -1) {
|
||||
|
@ -6,7 +6,7 @@ module.exports = {
|
||||
router: {
|
||||
middleware: 'i18n'
|
||||
},
|
||||
plugins: ['~plugins/i18n.js',],
|
||||
plugins: ['~/plugins/i18n.js'],
|
||||
generate: {
|
||||
routes: ['/', '/about', '/fr', '/fr/about']
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "nuxt-i18n",
|
||||
"dependencies": {
|
||||
"nuxt": "1.0.0-alpha.3",
|
||||
"vue-i18n": "^7.0.0"
|
||||
"nuxt": "latest",
|
||||
"vue-i18n": "^7.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
head () {
|
||||
head() {
|
||||
return { title: this.$t('about.title') }
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
head () {
|
||||
head() {
|
||||
return { title: this.$t('home.title') }
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script>
|
||||
import About from '~pages/_lang/about'
|
||||
import About from '~/pages/_lang/about'
|
||||
export default About
|
||||
</script>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script>
|
||||
import Index from '~pages/_lang/index'
|
||||
import Index from '~/pages/_lang/index'
|
||||
export default Index
|
||||
</script>
|
||||
|
@ -4,7 +4,7 @@ export const state = () => ({
|
||||
})
|
||||
|
||||
export const mutations = {
|
||||
SET_LANG (state, locale) {
|
||||
SET_LANG(state, locale) {
|
||||
if (state.locales.indexOf(locale) !== -1) {
|
||||
state.locale = locale
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user