mirror of
https://github.com/nuxt/nuxt.git
synced 2025-03-09 03:03:18 +00:00
Merge branch 'dev' of https://github.com/nuxt/nuxt.js into route-html-minifier
This commit is contained in:
commit
1b0a476f14
148
README.md
148
README.md
@ -12,13 +12,87 @@
|
||||
<a href="#backers" alt="sponsors on Open Collective"><img src="https://opencollective.com/nuxtjs/backers/badge.svg" /></a>
|
||||
<a href="#sponsors" alt="Sponsors on Open Collective"><img src="https://opencollective.com/nuxtjs/sponsors/badge.svg" /></a>
|
||||
<a href="https://opencollective.com/nuxtjs"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
> Nuxt.js is a framework for server-rendered Vue applications (inspired by [Next.js](https://github.com/zeit/next.js))
|
||||
|
||||
## 🚧 Under active development, [1.0](https://github.com/nuxt/nuxt.js/projects/1) will be released soon :fire:
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/nuxtjs#sponsor)]
|
||||
|
||||
<p>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/0/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/1/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/2/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/3/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/4/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/5/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/6/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/7/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/8/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/9/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/10/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/11/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/12/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/13/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/14/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/15/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/16/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/17/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/18/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/19/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/20/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/21/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/22/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/23/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/24/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/25/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/26/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/27/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/28/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/29/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/sponsor/29/avatar.svg"></a>
|
||||
</p>
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/nuxtjs#backer)]
|
||||
|
||||
<p>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/0/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/1/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/2/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/3/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/4/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/5/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/6/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/7/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/8/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/9/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/10/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/11/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/12/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/13/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/14/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/15/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/16/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/17/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/18/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/19/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/20/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/21/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/22/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/23/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/24/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/25/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/26/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/27/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/28/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/29/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/nuxtjs/backer/29/avatar.svg"></a>
|
||||
</p>
|
||||
|
||||
## Links
|
||||
|
||||
- 📘 Documentation: [https://nuxtjs.org](https://nuxtjs.org)
|
||||
@ -172,75 +246,3 @@ Note: we recommend putting `.nuxt` in `.npmignore` or `.gitignore`.
|
||||
## Roadmap
|
||||
|
||||
https://github.com/nuxt/nuxt.js/projects/1
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/nuxtjs#backer)]
|
||||
|
||||
<a href="https://opencollective.com/nuxtjs/backer/0/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/1/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/2/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/3/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/4/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/5/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/6/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/7/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/8/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/9/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/10/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/11/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/12/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/13/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/14/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/15/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/16/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/17/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/18/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/19/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/20/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/21/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/22/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/23/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/24/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/25/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/26/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/27/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/28/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/backer/29/website" target="_blank"><img src="https://opencollective.com/nuxtjs/backer/29/avatar.svg"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/nuxtjs#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/1/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/2/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/3/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/4/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/5/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/6/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/7/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/8/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/9/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/10/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/11/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/12/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/13/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/14/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/15/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/16/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/17/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/18/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/19/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/20/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/21/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/22/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/23/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/24/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/25/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/26/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/27/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/28/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/nuxtjs/sponsor/29/website" target="_blank"><img src="https://opencollective.com/nuxtjs/sponsor/29/avatar.svg"></a>
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
export default function ({ i18n, store, route, params, error, redirect }) {
|
||||
export default function ({ app, store, route, params, error, redirect }) {
|
||||
const locale = params.lang || 'en'
|
||||
if (store.state.locales.indexOf(locale) === -1) {
|
||||
return error({ message: 'This page could not be found.', statusCode: 404 })
|
||||
}
|
||||
// Set locale
|
||||
store.commit('SET_LANG', locale)
|
||||
i18n.locale = store.state.locale
|
||||
app.i18n.locale = store.state.locale
|
||||
// If route is /en/... -> redirect to /...
|
||||
if (locale === 'en' && route.fullPath.indexOf('/en') === 0) {
|
||||
redirect(route.fullPath.replace(/^\/en/, '/'))
|
||||
|
@ -1,16 +1,22 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import store from '~store'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: store.state.locale,
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
'en': require('~/locales/en.json'),
|
||||
'fr': require('~/locales/fr.json')
|
||||
export default ({ isClient, app, store, route, error, redirect }) => {
|
||||
console.log(route.path)
|
||||
if (isClient && route.path === '/fr/about') {
|
||||
return redirect('/about')
|
||||
}
|
||||
})
|
||||
|
||||
export default i18n
|
||||
console.log(error)
|
||||
// Set i18n instance on app
|
||||
// This way we can use it in middleware and pages asyncData/fetch
|
||||
app.i18n = new VueI18n({
|
||||
locale: store.state.locale,
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
'en': require('~/locales/en.json'),
|
||||
'fr': require('~/locales/fr.json')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
export const state = {
|
||||
export const state = () => ({
|
||||
locales: ['en', 'fr'],
|
||||
locale: 'en'
|
||||
}
|
||||
})
|
||||
|
||||
export const mutations = {
|
||||
SET_LANG (state, locale) {
|
||||
|
@ -3,13 +3,15 @@
|
||||
import Vue from 'vue'
|
||||
import middleware from './middleware'
|
||||
import { createApp, NuxtError } from './index'
|
||||
import { applyAsyncData, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, middlewareSeries, promisify, getLocation, compile } from './utils'
|
||||
import { applyAsyncData, sanitizeComponent, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, middlewareSeries, promisify, getLocation, compile } from './utils'
|
||||
const noopData = () => { return {} }
|
||||
const noopFetch = () => {}
|
||||
let _lastPaths = []
|
||||
let _lastComponentsFiles = []
|
||||
|
||||
const { app, router<%= (store ? ', store' : '') %> } = createApp()
|
||||
let app
|
||||
let router
|
||||
<%= (store ? 'let store' : '') %>
|
||||
|
||||
function mapTransitions(Components, to, from) {
|
||||
return Components.map((Component) => {
|
||||
@ -26,20 +28,16 @@ function loadAsyncComponents (to, from, next) {
|
||||
if (typeof Component === 'function' && !Component.options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const _resolve = (Component) => {
|
||||
if (!Component.options) {
|
||||
Component = Vue.extend(Component) // fix issue #6
|
||||
Component._Ctor = Component
|
||||
} else {
|
||||
Component._Ctor = Component
|
||||
Component.extendOptions = Component.options
|
||||
}
|
||||
Component = sanitizeComponent(Component)
|
||||
match.components[key] = Component
|
||||
resolve(Component)
|
||||
}
|
||||
Component().then(_resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
return Component
|
||||
Component = sanitizeComponent(Component)
|
||||
match.components[key] = Component
|
||||
return match.components[key]
|
||||
})
|
||||
const fromPath = from.fullPath.split('#')[0]
|
||||
const toPath = to.fullPath.split('#')[0]
|
||||
@ -323,29 +321,27 @@ if (!NUXT) {
|
||||
throw new Error('[nuxt.js] cannot find the global variable __NUXT__, make sure the server is working.')
|
||||
}
|
||||
// Get matched components
|
||||
const path = getLocation(router.options.base)
|
||||
const resolveComponents = flatMapComponents(router.match(path), (Component, _, match, key, index) => {
|
||||
if (typeof Component === 'function' && !Component.options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const _resolve = (Component) => {
|
||||
if (!Component.options) {
|
||||
Component = Vue.extend(Component) // fix issue #6
|
||||
Component._Ctor = Component
|
||||
} else {
|
||||
Component._Ctor = Component
|
||||
Component.extendOptions = Component.options
|
||||
const resolveComponents = function (router) {
|
||||
const path = getLocation(router.options.base)
|
||||
return flatMapComponents(router.match(path), (Component, _, match, key, index) => {
|
||||
if (typeof Component === 'function' && !Component.options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const _resolve = (Component) => {
|
||||
Component = sanitizeComponent(Component)
|
||||
if (NUXT.serverRendered) {
|
||||
applyAsyncData(Component, NUXT.data[index])
|
||||
}
|
||||
match.components[key] = Component
|
||||
resolve(Component)
|
||||
}
|
||||
if (NUXT.serverRendered) {
|
||||
applyAsyncData(Component, NUXT.data[index])
|
||||
}
|
||||
match.components[key] = Component
|
||||
resolve(Component)
|
||||
}
|
||||
Component().then(_resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
return Component
|
||||
})
|
||||
Component().then(_resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
Component = sanitizeComponent(Component)
|
||||
match.components[key] = Component
|
||||
return Component
|
||||
})
|
||||
}
|
||||
|
||||
function nuxtReady (app) {
|
||||
window._nuxtReadyCbs.forEach((cb) => {
|
||||
@ -359,7 +355,13 @@ function nuxtReady (app) {
|
||||
})
|
||||
}
|
||||
|
||||
Promise.all(resolveComponents)
|
||||
createApp()
|
||||
.then((__app) => {
|
||||
app = __app.app
|
||||
router = __app.router
|
||||
<%= (store ? 'store = __app.store' : '') %>
|
||||
return Promise.all(resolveComponents(router))
|
||||
})
|
||||
.then((Components) => {
|
||||
const _app = new Vue(app)
|
||||
|
||||
|
@ -10,6 +10,8 @@ import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./comp
|
||||
import Nuxt from './components/nuxt.vue'
|
||||
import App from '<%= appPath %>'
|
||||
|
||||
import { getContext } from './utils'
|
||||
|
||||
// Component: <nuxt-child>
|
||||
Vue.component(NuxtChild.name, NuxtChild)
|
||||
// Component: <nuxt-link>
|
||||
@ -32,12 +34,18 @@ const defaultTransition = <%=
|
||||
.replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(')
|
||||
%>
|
||||
|
||||
function createApp (ssrContext) {
|
||||
async function createApp (ssrContext) {
|
||||
<% if (store) { %>
|
||||
const store = createStore()
|
||||
<% } %>
|
||||
const router = createRouter()
|
||||
|
||||
if (process.server && ssrContext && ssrContext.url) {
|
||||
await new Promise((resolve, reject) => {
|
||||
router.push(ssrContext.url, resolve, reject)
|
||||
})
|
||||
}
|
||||
|
||||
if (process.browser) {
|
||||
<% if (store) { %>
|
||||
// Replace store state before calling plugins
|
||||
@ -59,7 +67,6 @@ function createApp (ssrContext) {
|
||||
let app = {
|
||||
router,
|
||||
<%= (store ? 'store,' : '') %>
|
||||
ssrContext,
|
||||
_nuxt: {
|
||||
defaultTransition: defaultTransition,
|
||||
transitions: [ defaultTransition ],
|
||||
@ -95,22 +102,32 @@ function createApp (ssrContext) {
|
||||
...App
|
||||
}
|
||||
|
||||
const ctx = getContext({
|
||||
isServer: !!ssrContext,
|
||||
isClient: !ssrContext,
|
||||
route: router.currentRoute,
|
||||
<%= (store ? 'store,' : '') %>
|
||||
req: ssrContext ? ssrContext.req : undefined,
|
||||
res: ssrContext ? ssrContext.res : undefined,
|
||||
}, app)
|
||||
delete ctx.redirect
|
||||
delete ctx.error
|
||||
|
||||
// Includes & Inject external plugins
|
||||
<% plugins.forEach(function (plugin) {
|
||||
if (plugin.ssr) { %>
|
||||
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
||||
<% if (plugin.injectAs) { %>
|
||||
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
||||
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
||||
<% }
|
||||
} else { %>
|
||||
let <%= plugin.name %> = require('<%= plugin.src %>')
|
||||
<%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %>
|
||||
if (typeof <%= plugin.name %> === 'function') {
|
||||
<%= plugin.name %>(ctx)
|
||||
}
|
||||
<% } else { %>
|
||||
if (process.browser) {
|
||||
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
||||
<% if (plugin.injectAs) { %>
|
||||
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
||||
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
||||
<% } %>
|
||||
let <%= plugin.name %> = require('<%= plugin.src %>')
|
||||
<%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %>
|
||||
if (typeof <%= plugin.name %> === 'function') {
|
||||
<%= plugin.name %>(ctx)
|
||||
}
|
||||
}
|
||||
<% }
|
||||
}) %>
|
||||
|
@ -17,10 +17,12 @@ const isDev = <%= isDev %>
|
||||
// Since data fetching is async, this function is expected to
|
||||
// return a Promise that resolves to the app instance.
|
||||
export default async (context) => {
|
||||
const { app, router<%= (store ? ', store' : '') %> } = createApp(context)
|
||||
const { app, router<%= (store ? ', store' : '') %> } = await createApp(context)
|
||||
const _app = new Vue(app)
|
||||
// Add store to the context
|
||||
<%= (store ? 'context.store = store' : '') %>
|
||||
// Add route to the context
|
||||
context.route = router.currentRoute
|
||||
// Nuxt object
|
||||
context.nuxt = { layout: 'default', data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true }
|
||||
// create context.next for simulate next() of beforeEach() when wanted to redirect
|
||||
@ -46,10 +48,11 @@ export default async (context) => {
|
||||
context.error = _app.$options._nuxt.error.bind(_app)
|
||||
|
||||
<%= (isDev ? 'const s = isDev && Date.now()' : '') %>
|
||||
let ctx = null
|
||||
let ctx = getContext(context, app)
|
||||
let Components = []
|
||||
let promises = getMatchedComponents(router.match(context.url)).map((Component) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof Component !== 'function') return resolve(sanitizeComponent(Component))
|
||||
const _resolve = (Component) => resolve(sanitizeComponent(Component))
|
||||
Component().then(_resolve).catch(reject)
|
||||
})
|
||||
@ -60,14 +63,6 @@ export default async (context) => {
|
||||
// Throw back error to renderRoute()
|
||||
throw err
|
||||
}
|
||||
// set router's location
|
||||
await new Promise((resolve) => {
|
||||
router.push(context.url, resolve)
|
||||
})
|
||||
// Add route to the context
|
||||
context.route = router.currentRoute
|
||||
// Update context
|
||||
ctx = getContext(context, app)
|
||||
// nuxtServerInit
|
||||
<% if (store) { %>
|
||||
let promise = (store._actions && store._actions.nuxtServerInit ? store.dispatch('nuxtServerInit', omit(getContext(context, app), 'redirect', 'error')) : null)
|
||||
|
@ -58,6 +58,7 @@ export function getContext (context, app) {
|
||||
isServer: !!context.isServer,
|
||||
isClient: !!context.isClient,
|
||||
isDev: <%= isDev %>,
|
||||
app: app,
|
||||
<%= (store ? 'store: context.store,' : '') %>
|
||||
route: (context.to ? context.to : context.route),
|
||||
error: context.error,
|
||||
@ -84,16 +85,6 @@ export function getContext (context, app) {
|
||||
}
|
||||
if (context.req) ctx.req = context.req
|
||||
if (context.res) ctx.res = context.res
|
||||
// Inject external plugins in context
|
||||
<% plugins.forEach(function (plugin) {
|
||||
if (plugin.injectAs && plugin.ssr) { %>
|
||||
ctx['<%= plugin.injectAs %>'] = app['<%= plugin.injectAs %>']
|
||||
<% } else if (plugin.injectAs) { %>
|
||||
if (process.browser) {
|
||||
ctx['<%= plugin.injectAs %>'] = app['<%= plugin.injectAs %>']
|
||||
}
|
||||
<% } %>
|
||||
<% }) %>
|
||||
return ctx
|
||||
}
|
||||
|
||||
|
50
lib/build.js
50
lib/build.js
@ -97,8 +97,9 @@ export function options () {
|
||||
}
|
||||
|
||||
export async function build () {
|
||||
this._nuxtPages = typeof this.createRoutes !== 'function'
|
||||
// Check if pages dir exists and warn if not
|
||||
if (typeof this.createRoutes !== 'function') {
|
||||
if (this._nuxtPages) {
|
||||
if (!fs.existsSync(join(this.srcDir, 'pages'))) {
|
||||
if (fs.existsSync(join(this.srcDir, '..', 'pages'))) {
|
||||
console.error('> No `pages` directory found. Did you mean to run `nuxt` in the parent (`../`) directory?') // eslint-disable-line no-console
|
||||
@ -128,7 +129,7 @@ async function buildFiles () {
|
||||
debug('Adding webpack middleware...')
|
||||
createWebpackMiddleware.call(this)
|
||||
webpackWatchAndUpdate.call(this)
|
||||
watchPages.call(this)
|
||||
watchFiles.call(this)
|
||||
} else {
|
||||
debug('Building files...')
|
||||
await webpackRunClient.call(this)
|
||||
@ -172,6 +173,7 @@ async function generateRoutesAndFiles () {
|
||||
base: this.options.router.base,
|
||||
middleware: this.options.router.middleware,
|
||||
linkActiveClass: this.options.router.linkActiveClass,
|
||||
linkExactActiveClass: this.options.router.linkExactActiveClass,
|
||||
scrollBehavior: this.options.router.scrollBehavior
|
||||
},
|
||||
env: this.options.env,
|
||||
@ -179,11 +181,10 @@ async function generateRoutesAndFiles () {
|
||||
middleware: fs.existsSync(join(this.srcDir, 'middleware')),
|
||||
store: this.options.store || fs.existsSync(join(this.srcDir, 'store')),
|
||||
css: this.options.css,
|
||||
plugins: this.options.plugins.map((p) => {
|
||||
if (typeof p === 'string') {
|
||||
return { src: r(this.srcDir, p), ssr: true }
|
||||
}
|
||||
return { src: r(this.srcDir, p.src), ssr: (p.ssr !== false), injectAs: (p.injectAs || false) }
|
||||
plugins: this.options.plugins.map((p, i) => {
|
||||
if (typeof p === 'string') p = { src: p }
|
||||
p.src = r(this.srcDir, p.src)
|
||||
return { src: p.src, ssr: (p.ssr !== false), name: `plugin${i}` }
|
||||
}),
|
||||
appPath: './App.vue',
|
||||
layouts: Object.assign({}, this.options.layouts),
|
||||
@ -215,20 +216,21 @@ async function generateRoutesAndFiles () {
|
||||
|
||||
// -- Routes --
|
||||
debug('Generating routes...')
|
||||
// Format routes for the lib/app/router.js template
|
||||
if (typeof this.createRoutes !== 'function') {
|
||||
// Use internal createRoutes
|
||||
// If user defined a custom method to create routes
|
||||
if (this._nuxtPages) {
|
||||
// Use nuxt.js createRoutes bases on pages/
|
||||
const files = await glob('pages/**/*.vue', {cwd: this.srcDir})
|
||||
templateVars.router.routes = createRoutes(files, this.srcDir)
|
||||
} else {
|
||||
templateVars.router.routes = this.createRoutes(this.srcDir)
|
||||
}
|
||||
// router.extendRoutes method
|
||||
if (typeof this.options.router.extendRoutes === 'function') {
|
||||
// let the user extend the routes
|
||||
this.options.router.extendRoutes.call(this, templateVars.router.routes, r)
|
||||
this.options.router.extendRoutes.call(this, templateVars.router.routes || [], r)
|
||||
}
|
||||
// Routes for generate command
|
||||
this.routes = flatRoutes(templateVars.router.routes)
|
||||
this.routes = flatRoutes(templateVars.router.routes || [])
|
||||
|
||||
// -- Store --
|
||||
// Add store if needed
|
||||
@ -239,13 +241,13 @@ async function generateRoutesAndFiles () {
|
||||
// Resolve template files
|
||||
const customTemplateFiles = this.options.build.templates.map(t => t.dst || basename(t.src || t))
|
||||
templatesFiles = templatesFiles.map(file => {
|
||||
// Skip if custom file was already provided in build.templates[]
|
||||
if (customTemplateFiles.indexOf(file) !== -1) {
|
||||
return
|
||||
}
|
||||
// Allow override templates using a file with same name in ${srcDir}/app
|
||||
const customPath = r(this.srcDir, 'app', file)
|
||||
const customFileExists = fs.existsSync(customPath)
|
||||
// Skip if custom file was already provided in build.templates[]
|
||||
if (customTemplateFiles.indexOf(file) !== -1 && !customFileExists) {
|
||||
return
|
||||
}
|
||||
return {
|
||||
src: customFileExists ? customPath : r(__dirname, 'app', file),
|
||||
dst: file,
|
||||
@ -264,7 +266,7 @@ async function generateRoutesAndFiles () {
|
||||
}))
|
||||
|
||||
// Interpret and move template files to .nuxt/
|
||||
return Promise.all(templatesFiles.map(async ({src, dst, options, custom}) => {
|
||||
return Promise.all(templatesFiles.map(async ({ src, dst, options, custom }) => {
|
||||
// Add template to watchers
|
||||
this.options.build.watch.push(src)
|
||||
// Render template to dst
|
||||
@ -513,17 +515,19 @@ function createRenderer (bundle, manifest) {
|
||||
this.renderToStream = this.renderer.renderToStream
|
||||
}
|
||||
|
||||
function watchPages () {
|
||||
function watchFiles () {
|
||||
const patterns = [
|
||||
r(this.srcDir, 'pages'),
|
||||
r(this.srcDir, 'layouts'),
|
||||
r(this.srcDir, 'store'),
|
||||
r(this.srcDir, 'middleware'),
|
||||
r(this.srcDir, 'pages/*.vue'),
|
||||
r(this.srcDir, 'pages/**/*.vue'),
|
||||
r(this.srcDir, 'layouts/*.vue'),
|
||||
r(this.srcDir, 'layouts/**/*.vue')
|
||||
]
|
||||
if (this._nuxtPages) {
|
||||
patterns.push(r(this.srcDir, 'pages'))
|
||||
patterns.push(r(this.srcDir, 'pages/*.vue'))
|
||||
patterns.push(r(this.srcDir, 'pages/**/*.vue'))
|
||||
}
|
||||
const options = Object.assign({}, this.options.watchers.chokidar, {
|
||||
ignoreInitial: true
|
||||
})
|
||||
@ -532,10 +536,10 @@ function watchPages () {
|
||||
await generateRoutesAndFiles.call(this)
|
||||
}, 200)
|
||||
// Watch for internals
|
||||
this.pagesFilesWatcher = chokidar.watch(patterns, options)
|
||||
this.filesWatcher = chokidar.watch(patterns, options)
|
||||
.on('add', refreshFiles)
|
||||
.on('unlink', refreshFiles)
|
||||
// Watch for custom provided files
|
||||
this.customFilesWatcher = chokidar.watch(_.uniq(this.options.build.watch), options)
|
||||
.on('change', refreshFiles)
|
||||
.on('change', refreshFiles)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class Module {
|
||||
/* istanbul ignore if */
|
||||
if (!src || typeof src !== 'string' || !fs.existsSync(src)) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[Nuxt] invalid template', template)
|
||||
console.warn('[nuxt] invalid template', template)
|
||||
return
|
||||
}
|
||||
// Generate unique and human readable dst filename
|
||||
@ -45,22 +45,15 @@ class Module {
|
||||
options: template.options
|
||||
}
|
||||
this.options.build.templates.push(templateObj)
|
||||
// Watch template for changes
|
||||
this.addWatch(src)
|
||||
return templateObj
|
||||
}
|
||||
|
||||
addWatch (pattern) {
|
||||
this.options.build.watch.push(pattern)
|
||||
}
|
||||
|
||||
addPlugin (template) {
|
||||
const {dst} = this.addTemplate(template)
|
||||
// Add to nuxt plugins
|
||||
this.options.plugins.push({
|
||||
src: '~/.nuxt/' + dst,
|
||||
ssr: template.ssr,
|
||||
injectAs: template.injectAs
|
||||
ssr: template.ssr
|
||||
})
|
||||
}
|
||||
|
||||
@ -80,6 +73,7 @@ class Module {
|
||||
if (this.modules.indexOf(moduleOpts) !== -1 || this.modules.indexOf(moduleOpts.src) !== -1) {
|
||||
return false
|
||||
}
|
||||
this.modules.push(moduleOpts.src || moduleOpts)
|
||||
return this.addModule(moduleOpts)
|
||||
}
|
||||
|
||||
@ -90,33 +84,33 @@ class Module {
|
||||
}
|
||||
// Allows passing runtime options to each module
|
||||
const options = moduleOpts.options || {}
|
||||
let src = moduleOpts.src || moduleOpts
|
||||
const originalSrc = moduleOpts.src || moduleOpts
|
||||
let src = originalSrc
|
||||
// Resolve module
|
||||
let module
|
||||
try {
|
||||
if (typeof src === 'string') {
|
||||
// Using ~ shorthand modules are resolved from project srcDir
|
||||
if (src.indexOf('~') === 0) {
|
||||
src = path.resolve(this.options.srcDir, src.substr(1))
|
||||
// Using ~ or ./ shorthand modules are resolved from project srcDir
|
||||
if (src.indexOf('~') === 0 || src.indexOf('./') === 0) {
|
||||
src = path.join(this.options.srcDir, src.substr(1))
|
||||
}
|
||||
// eslint-disable-next-line no-eval
|
||||
module = eval('require')(src)
|
||||
}
|
||||
} catch (e) /* istanbul ignore next */ {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('[Nuxt] Unable to resolve module', src)
|
||||
console.error('[nuxt] Unable to resolve module', src)
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e)
|
||||
return
|
||||
process.exit(0)
|
||||
}
|
||||
// Validate module
|
||||
/* istanbul ignore if */
|
||||
if (!(module instanceof Function)) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('[Nuxt] Module should be a function', module)
|
||||
console.error(`[nuxt] Module [${originalSrc}] should export a function`)
|
||||
process.exit(1)
|
||||
}
|
||||
// Add module to this.modules
|
||||
this.modules.push(module)
|
||||
// Call module with `this` context and pass options
|
||||
return new Promise((resolve, reject) => {
|
||||
const result = module.call(this, options, err => {
|
||||
@ -126,9 +120,14 @@ class Module {
|
||||
}
|
||||
resolve(module)
|
||||
})
|
||||
// If module send back a promise
|
||||
if (result && result.then instanceof Function) {
|
||||
return result.then(resolve)
|
||||
}
|
||||
// If not expecting a callback but returns no promise (=synchronous)
|
||||
if (module.length < 2) {
|
||||
return resolve(module)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
16
lib/nuxt.js
16
lib/nuxt.js
@ -120,12 +120,12 @@ class Nuxt {
|
||||
this.module = new Module(this)
|
||||
// Install all modules in sequence and then return `this` instance
|
||||
return utils.sequence(options.modules, this.module.addModule.bind(this.module))
|
||||
.then(() => this)
|
||||
.catch(/* istanbul ignore next */ (err) => {
|
||||
console.error('[nuxt] error while initializing modules') // eslint-disable-line no-console
|
||||
console.error(err) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
.then(() => this)
|
||||
.catch(/* istanbul ignore next */ (err) => {
|
||||
console.error('[nuxt] error while initializing modules') // eslint-disable-line no-console
|
||||
console.error(err) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
}
|
||||
|
||||
close (callback) {
|
||||
@ -145,8 +145,8 @@ class Nuxt {
|
||||
promises.push(p)
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (this.pagesFilesWatcher) {
|
||||
this.pagesFilesWatcher.close()
|
||||
if (this.filesWatcher) {
|
||||
this.filesWatcher.close()
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (this.customFilesWatcher) {
|
||||
|
@ -19,7 +19,6 @@ export async function render (req, res) {
|
||||
if (!this.renderer || !this.appTemplate) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
// debug('Waiting for renderer to be ready')
|
||||
resolve(this.render(req, res))
|
||||
}, 1000)
|
||||
})
|
||||
|
@ -23,9 +23,9 @@ class Server {
|
||||
// Require if needed
|
||||
if (typeof m === 'string') {
|
||||
let src = m
|
||||
// Using ~ shorthand to resolve from project srcDir
|
||||
if (src.indexOf('~') === 0) {
|
||||
src = path.resolve(this.nuxt.options.srcDir, src.substr(1))
|
||||
// Using ~ or ./ shorthand to resolve from project srcDir
|
||||
if (src.indexOf('~') === 0 || src.indexOf('./') === 0) {
|
||||
src = path.join(this.nuxt.options.srcDir, src.substr(1))
|
||||
}
|
||||
// eslint-disable-next-line no-eval
|
||||
m = eval('require')(src)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nuxt",
|
||||
"version": "0.10.7",
|
||||
"version": "1.0.0-alpha1",
|
||||
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
|
||||
"contributors": [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
const port = 4005
|
||||
const port = 4001
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
@ -38,5 +38,5 @@ test('/_nuxt/test.hot-update.json should returns empty html', async t => {
|
||||
// Close server and ask nuxt to stop listening to file changes
|
||||
test.after('Closing server and nuxt.js', t => {
|
||||
server.close()
|
||||
nuxt.close()
|
||||
nuxt.close(() => {})
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ import http from 'http'
|
||||
import serveStatic from 'serve-static'
|
||||
import finalhandler from 'finalhandler'
|
||||
import rp from 'request-promise-native'
|
||||
const port = 4003
|
||||
const port = 4002
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
|
@ -3,7 +3,7 @@ import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
import stdMocks from 'std-mocks'
|
||||
|
||||
const port = 4000
|
||||
const port = 4003
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
@ -144,6 +144,15 @@ test('/redirect2 status code', async t => {
|
||||
t.true(output.stderr[0].includes('Error: NOPE!'))
|
||||
})
|
||||
|
||||
test('ETag Header', async t => {
|
||||
const {headers: {etag}} = await rp(url('/stateless'), {resolveWithFullResponse: true})
|
||||
// Validate etag
|
||||
t.regex(etag, /W\/".*"$/)
|
||||
// Verify functionality
|
||||
const error = await t.throws(rp(url('/stateless'), {headers: {'If-None-Match': etag}}))
|
||||
t.is(error.statusCode, 304)
|
||||
})
|
||||
|
||||
// Close server and ask nuxt to stop listening to file changes
|
||||
test.after('Closing server and nuxt.js', t => {
|
||||
server.close()
|
||||
|
@ -1,6 +1,6 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
const port = 4001
|
||||
const port = 4004
|
||||
// const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
|
@ -4,7 +4,6 @@ import fs from 'fs'
|
||||
import pify from 'pify'
|
||||
const readFile = pify(fs.readFile)
|
||||
|
||||
// Init nuxt.js and create server listening on localhost:4000
|
||||
test.before('Init Nuxt.js', async t => {
|
||||
const Nuxt = require('../')
|
||||
const nuxt = await new Nuxt({
|
||||
|
@ -1,6 +1,6 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
const port = 4002
|
||||
const port = 4005
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
|
8
test/fixtures/module/modules/basic/index.js
vendored
8
test/fixtures/module/modules/basic/index.js
vendored
@ -8,12 +8,12 @@ module.exports = function basicModule (options, resolve) {
|
||||
this.addPlugin(path.resolve(__dirname, 'reverse.js'))
|
||||
|
||||
// Extend build
|
||||
this.extendBuild(({isClient, isServer}) => {
|
||||
this.extendBuild((config, { isClient, isServer }) => {
|
||||
// Do nothing!
|
||||
})
|
||||
|
||||
// Extend build again
|
||||
this.extendBuild(({isClient, isServer}) => {
|
||||
this.extendBuild((config, { isClient, isServer }) => {
|
||||
// Do nothing!
|
||||
})
|
||||
|
||||
@ -22,5 +22,9 @@ module.exports = function basicModule (options, resolve) {
|
||||
// Do nothing!
|
||||
})
|
||||
|
||||
// Require same module twice
|
||||
this.requireModule('~/modules/empty/index.js')
|
||||
this.requireModule('~/modules/empty/index.js')
|
||||
|
||||
resolve()
|
||||
}
|
||||
|
@ -7,5 +7,3 @@ function $reverseStr (str) {
|
||||
}
|
||||
|
||||
Vue.prototype.$reverseStr = $reverseStr
|
||||
|
||||
export default $reverseStr
|
||||
|
4
test/fixtures/module/modules/empty/index.js
vendored
Executable file
4
test/fixtures/module/modules/empty/index.js
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
|
||||
module.exports = function middlewareModule (options) {
|
||||
// Empty module
|
||||
}
|
@ -8,11 +8,15 @@ module.exports = function middlewareModule (options) {
|
||||
res.end('It works!')
|
||||
}
|
||||
})
|
||||
// Add local middleware js
|
||||
this.addServerMiddleware('~/modules/middleware/log.js')
|
||||
// Add plain middleware
|
||||
this.addServerMiddleware((req, res, next) => {
|
||||
res.setHeader('x-nuxt', 'hello')
|
||||
next()
|
||||
})
|
||||
// Resolve
|
||||
// Add file middleware
|
||||
this.addServerMiddleware('~/modules/middleware/midd1')
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
5
test/fixtures/module/modules/middleware/log.js
vendored
Executable file
5
test/fixtures/module/modules/middleware/log.js
vendored
Executable file
@ -0,0 +1,5 @@
|
||||
module.exports = function (req, res, next) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(req.url)
|
||||
next()
|
||||
}
|
4
test/fixtures/module/modules/middleware/midd1.js
vendored
Normal file
4
test/fixtures/module/modules/middleware/midd1.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = function (req, res, next) {
|
||||
res.setHeader('x-midd-1', 'ok')
|
||||
next()
|
||||
}
|
4
test/fixtures/module/modules/middleware/midd2.js
vendored
Normal file
4
test/fixtures/module/modules/middleware/midd2.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = function (req, res, next) {
|
||||
res.setHeader('x-midd-2', 'ok')
|
||||
next()
|
||||
}
|
11
test/fixtures/module/modules/template/index.js
vendored
Normal file
11
test/fixtures/module/modules/template/index.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
const path = require('path')
|
||||
|
||||
module.exports = function () {
|
||||
// Disable parsing pages/
|
||||
this.nuxt.createRoutes = () => {}
|
||||
// Add /api endpoint
|
||||
this.addTemplate({
|
||||
fileName: 'router.js',
|
||||
src: path.resolve(this.nuxt.srcDir, 'router.js')
|
||||
})
|
||||
}
|
7
test/fixtures/module/nuxt.config.js
vendored
7
test/fixtures/module/nuxt.config.js
vendored
@ -1,6 +1,11 @@
|
||||
module.exports = {
|
||||
loading: true,
|
||||
modules: [
|
||||
'~modules/basic',
|
||||
'~modules/middleware'
|
||||
'~/modules/middleware',
|
||||
'./modules/template'
|
||||
],
|
||||
serverMiddleware: [
|
||||
'./modules/middleware/midd2'
|
||||
]
|
||||
}
|
||||
|
22
test/fixtures/module/router.js
vendored
Normal file
22
test/fixtures/module/router.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export function createRouter () {
|
||||
return new Router({
|
||||
mode: 'history',
|
||||
routes: [
|
||||
{
|
||||
path: "/",
|
||||
component: require('~/views/index.vue'),
|
||||
name: "index"
|
||||
},
|
||||
{
|
||||
path: "/about",
|
||||
component: require('~/views/about.vue'),
|
||||
name: "about"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
6
test/fixtures/module/views/about.vue
vendored
Normal file
6
test/fixtures/module/views/about.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>About page</h1>
|
||||
<nuxt-link to="/">Home page</nuxt-link>
|
||||
</div>
|
||||
</template>
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ $reverseStr('NUXT') }}</h1>
|
||||
<nuxt-link to="/about">About page</nuxt-link>
|
||||
</div>
|
||||
</template>
|
3
test/fixtures/with-config/middleware/noop.js
vendored
Normal file
3
test/fixtures/with-config/middleware/noop.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default function () {
|
||||
// NOOP!
|
||||
}
|
4
test/fixtures/with-config/nuxt.config.js
vendored
4
test/fixtures/with-config/nuxt.config.js
vendored
@ -1,6 +1,8 @@
|
||||
module.exports = {
|
||||
srcDir: __dirname,
|
||||
router: {
|
||||
base: '/test/',
|
||||
middleware: 'noop',
|
||||
extendRoutes (routes) {
|
||||
routes.push({
|
||||
name: 'about-bis',
|
||||
@ -9,7 +11,7 @@ module.exports = {
|
||||
})
|
||||
}
|
||||
},
|
||||
cache: true,
|
||||
transition: 'test',
|
||||
offline: true,
|
||||
plugins: [
|
||||
'~plugins/test.js',
|
||||
|
@ -2,7 +2,7 @@ import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
|
||||
const port = 4000
|
||||
const port = 4006
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
|
@ -32,6 +32,7 @@ test('waitFor', async (t) => {
|
||||
let s = Date.now()
|
||||
await utils.waitFor(100)
|
||||
t.true(Date.now() - s >= 100)
|
||||
await utils.waitFor()
|
||||
})
|
||||
|
||||
test('urlJoin', t => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
const port = 4004
|
||||
const port = 4007
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
|
||||
let nuxt = null
|
||||
|
Loading…
Reference in New Issue
Block a user