Merge branch 'dev' of github.com:Atinux/nuxt.js into dev

This commit is contained in:
Sébastien Chopin 2017-07-02 20:16:58 +02:00
commit 97e873bb6b
23 changed files with 119 additions and 80 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -15,7 +15,7 @@
</p> </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: ## 🚧 Under active development, [1.0](https://github.com/nuxt/nuxt.js/projects/1) will be released soon :fire:

View File

@ -7,7 +7,7 @@
// Node Source Map Support // Node Source Map Support
// https://github.com/evanw/node-source-map-support // https://github.com/evanw/node-source-map-support
require('source-map-support').install(); require('source-map-support').install()
// Fix babel flag // Fix babel flag
/* istanbul ignore else */ /* istanbul ignore else */

View File

@ -6,7 +6,7 @@
<script> <script>
import Vue from 'vue' import Vue from 'vue'
import NuxtChild from './nuxt-child' import NuxtChild from './nuxt-child'
import NuxtError from '<%= components.ErrorPage ? (components.ErrorPage.includes('~') ? components.ErrorPage : "../" + components.ErrorPage) : "./nuxt-error.vue" %>' import NuxtError from '<%= components.ErrorPage ? ((components.ErrorPage.includes('~') || components.ErrorPage.includes('@')) ? components.ErrorPage : "../" + components.ErrorPage) : "./nuxt-error.vue" %>'
export default { export default {
name: 'nuxt', name: 'nuxt',

View File

@ -23,7 +23,7 @@ if (process.browser) {
// Import SSR plugins // Import SSR plugins
<% plugins.forEach(function (plugin) { if (plugin.ssr) <% plugins.forEach(function (plugin) { if (plugin.ssr)
{ %>let <%= plugin.name %> = require('<%= relative(plugin.src) %>') { %>let <%= plugin.name %> = require('<%= relativeToBuild(plugin.src) %>')
<%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %> <%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %>
<% }}) %> <% }}) %>
@ -132,7 +132,7 @@ async function createApp (ssrContext) {
} }
<% } else { %> <% } else { %>
if (process.browser) { if (process.browser) {
let <%= plugin.name %> = require('<%= relative(plugin.src) %>') let <%= plugin.name %> = require('<%= relativeToBuild(plugin.src) %>')
<%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %> <%= plugin.name %> = <%= plugin.name %>.default || <%= plugin.name %>
if (typeof <%= plugin.name %> === 'function') { if (typeof <%= plugin.name %> === 'function') {
await <%= plugin.name %>(ctx) await <%= plugin.name %>(ctx)

View File

@ -1,5 +1,5 @@
<% if (middleware) { %> <% if (middleware) { %>
let files = require.context('~/middleware', false, /^\.\/.*\.(js|ts)$/) let files = require.context('@/middleware', false, /^\.\/.*\.(js|ts)$/)
let filenames = files.keys() let filenames = files.keys()
function getModule (filename) { function getModule (filename) {

View File

@ -23,7 +23,7 @@ function recursiveRoutes(routes, tab, components) {
var _components = [] var _components = []
var _routes = recursiveRoutes(router.routes, '\t\t', _components) var _routes = recursiveRoutes(router.routes, '\t\t', _components)
uniqBy(_components, '_name').forEach((route) => { %> uniqBy(_components, '_name').forEach((route) => { %>
const <%= route._name %> = () => import('<%= relative(route.component) %>' /* webpackChunkName: "pages/<%= route.name %>" */) const <%= route._name %> = () => import('<%= relativeToBuild(route.component) %>' /* webpackChunkName: "pages/<%= route.name %>" */)
<% }) %> <% }) %>
<% if (router.scrollBehavior) { %> <% if (router.scrollBehavior) { %>

View File

@ -3,8 +3,8 @@ import Vuex from 'vuex'
Vue.use(Vuex) Vue.use(Vuex)
// Recursive find files in ~/store // Recursive find files in {srcDir}/store
const files = require.context('~/store', true, /^\.\/.*\.(js|ts)$/) const files = require.context('@/store', true, /^\.\/.*\.(js|ts)$/)
const filenames = files.keys() const filenames = files.keys()
// Store // Store

View File

@ -5,12 +5,12 @@ import hash from 'hash-sum'
import pify from 'pify' import pify from 'pify'
import webpack from 'webpack' import webpack from 'webpack'
import serialize from 'serialize-javascript' import serialize from 'serialize-javascript'
import { join, resolve, basename, dirname, relative } from 'path' import { join, resolve, basename, dirname } from 'path'
import Tapable from 'tappable' import Tapable from 'tappable'
import MFS from 'memory-fs' import MFS from 'memory-fs'
import webpackDevMiddleware from 'webpack-dev-middleware' import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
import { r, wp, createRoutes, parallel } from 'utils' import { r, wp, createRoutes, parallel, relativeTo } from 'utils'
import Debug from 'debug' import Debug from 'debug'
import Glob from 'glob' import Glob from 'glob'
import clientWebpackConfig from './webpack/client.config.js' import clientWebpackConfig from './webpack/client.config.js'
@ -40,6 +40,9 @@ export default class Builder extends Tapable {
colors: true colors: true
} }
// Helper to resolve build paths
this.relativeToBuild = (...args) => relativeTo(this.options.buildDir, ...args)
this._buildStatus = STATUS.INITIAL this._buildStatus = STATUS.INITIAL
} }
@ -134,10 +137,10 @@ export default class Builder extends Tapable {
}), }),
appPath: './App.vue', appPath: './App.vue',
layouts: Object.assign({}, this.options.layouts), layouts: Object.assign({}, this.options.layouts),
loading: typeof this.options.loading === 'string' ? this.relative(r(this.options.srcDir, this.options.loading)) : this.options.loading, loading: typeof this.options.loading === 'string' ? this.relativeToBuild(this.options.srcDir, this.options.loading) : this.options.loading,
transition: this.options.transition, transition: this.options.transition,
components: { components: {
ErrorPage: this.options.ErrorPage ? this.relative(r(this.options.ErrorPage)) : null ErrorPage: this.options.ErrorPage ? this.relativeToBuild(this.options.ErrorPage) : null
} }
} }
@ -147,10 +150,10 @@ export default class Builder extends Tapable {
layoutsFiles.forEach((file) => { layoutsFiles.forEach((file) => {
let name = file.split('/').slice(-1)[0].replace('.vue', '') let name = file.split('/').slice(-1)[0].replace('.vue', '')
if (name === 'error') return if (name === 'error') return
templateVars.layouts[name] = this.relative(r(this.options.srcDir, file)) templateVars.layouts[name] = this.relativeToBuild(this.options.srcDir, file)
}) })
if (layoutsFiles.includes('layouts/error.vue') && !templateVars.components.ErrorPage) { if (layoutsFiles.includes('layouts/error.vue') && !templateVars.components.ErrorPage) {
templateVars.components.ErrorPage = this.relative(r(this.options.srcDir, 'layouts/error.vue')) templateVars.components.ErrorPage = this.relativeToBuild(this.options.srcDir, 'layouts/error.vue')
} }
} }
// If no default layout, create its folder and add the default folder // If no default layout, create its folder and add the default folder
@ -225,7 +228,7 @@ export default class Builder extends Tapable {
hash, hash,
r, r,
wp, wp,
relative: this.relative.bind(this) relativeToBuild: this.relativeToBuild
} }
}) })
const content = template(Object.assign({}, templateVars, { const content = template(Object.assign({}, templateVars, {
@ -408,17 +411,6 @@ export default class Builder extends Tapable {
customFilesWatcher.close() customFilesWatcher.close()
}) })
} }
relative (dest) {
if (dest && dest.includes('~')) {
return dest
}
let rp = relative(this.options.buildDir, dest)
if (rp[0] !== '.') {
rp = './' + rp
}
return wp(rp)
}
} }
const STATUS = { const STATUS = {

View File

@ -109,6 +109,7 @@ export default class Generator extends Tapable {
} }
} }
let path = join(route, sep, 'index.html') // /about -> /about/index.html let path = join(route, sep, 'index.html') // /about -> /about/index.html
path = (path === '/404/index.html') ? '/404.html' : path // /404 -> /404.html
debug('Generate file: ' + path) debug('Generate file: ' + path)
path = join(distPath, path) path = join(distPath, path)
// Make sure the sub folders are created // Make sure the sub folders are created

View File

@ -46,8 +46,16 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
}, },
resolve: { resolve: {
extensions: ['.js', '.json', '.vue', '.ts'], extensions: ['.js', '.json', '.vue', '.ts'],
// Disable for now
alias: { alias: {
'@@': join(this.options.rootDir),
'@': join(this.options.srcDir),
'@static': join(this.options.srcDir, 'static'),
'@assets': join(this.options.srcDir, 'assets'),
'@plugins': join(this.options.srcDir, 'plugins'),
'@pages': join(this.options.srcDir, 'pages'),
'@components': join(this.options.srcDir, 'components'),
'@middleware': join(this.options.srcDir, 'middleware'),
// Legacy support
'~': join(this.options.srcDir), '~': join(this.options.srcDir),
'static': join(this.options.srcDir, 'static'), // use in template with <img src="~static/nuxt.png" /> 'static': join(this.options.srcDir, 'static'), // use in template with <img src="~static/nuxt.png" />
'~static': join(this.options.srcDir, 'static'), '~static': join(this.options.srcDir, 'static'),
@ -55,7 +63,8 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
'~assets': join(this.options.srcDir, 'assets'), '~assets': join(this.options.srcDir, 'assets'),
'~plugins': join(this.options.srcDir, 'plugins'), '~plugins': join(this.options.srcDir, 'plugins'),
'~pages': join(this.options.srcDir, 'pages'), '~pages': join(this.options.srcDir, 'pages'),
'~components': join(this.options.srcDir, 'components') '~components': join(this.options.srcDir, 'components'),
'~middleware': join(this.options.srcDir, 'middleware')
}, },
modules: [ modules: [
join(this.options.rootDir, 'node_modules'), join(this.options.rootDir, 'node_modules'),

View File

@ -1,4 +1,4 @@
import { resolve, sep } from 'path' import { resolve, relative, sep } from 'path'
import _ from 'lodash' import _ from 'lodash'
export function encodeHtml (str) { export function encodeHtml (str) {
@ -94,12 +94,40 @@ const normalize = string => string.replace(reqSep, sysSep)
export function r () { export function r () {
let args = Array.prototype.slice.apply(arguments) let args = Array.prototype.slice.apply(arguments)
let lastArg = _.last(args)
if (_.last(args).includes('~')) { if (lastArg.includes('@')) {
return wp(_.last(args)) return wp(lastArg)
} }
args = args.map(normalize)
return wp(resolve.apply(null, args)) if (lastArg.includes('~')) {
// eslint-disable-next-line no-console
console.warn('[nuxt] Aliases using `~` are deprecated, please use `@/` instead.',
lastArg, '->', lastArg.replace('~/', '@/').replace('~', '@/'))
return wp(lastArg)
}
return wp(resolve(...args.map(normalize)))
}
export function relativeTo () {
let args = Array.prototype.slice.apply(arguments)
let dir = args.shift()
// Resolve path
let path = r(...args)
// Check if path is an alias
if (path.includes('@') || path.includes('~')) {
return path
}
// Make correct relative path
let rp = relative(dir, path)
if (rp[0] !== '.') {
rp = './' + rp
}
return wp(rp)
} }
export function flatRoutes (router, path = '', routes = []) { export function flatRoutes (router, path = '', routes = []) {

View File

@ -100,11 +100,7 @@ export default class ModuleContainer extends Tapable {
let module = originalSrc let module = originalSrc
if (typeof module === 'string') { if (typeof module === 'string') {
// Using ~ or ./ shorthand modules are resolved from project srcDir module = require(this.nuxt.resolvePath(module))
if (module.indexOf('~') === 0 || module.indexOf('./') === 0) {
module = path.join(this.options.srcDir, module.substr(1))
}
module = require(module)
} }
// Validate module // Validate module

View File

@ -5,6 +5,7 @@ import Renderer from './renderer'
import Options from './options' import Options from './options'
import Debug from 'debug' import Debug from 'debug'
import enableDestroy from 'server-destroy' import enableDestroy from 'server-destroy'
import { join, resolve } from 'path'
const debug = Debug('nuxt:') const debug = Debug('nuxt:')
debug.color = 5 debug.color = 5
@ -92,6 +93,28 @@ export default class Nuxt extends Tapable {
process.exit(1) process.exit(1)
} }
resolvePath (path) {
// Try to resolve using NPM resolve path first
// Fixes problems with scopped modules
try {
let resolvedPath = require.resolve(path)
return resolvedPath
} catch (e) {
// Just continue
}
// Shorthand to resolve from project srcDir
if (path.indexOf('@') === 0 || path.indexOf('~') === 0) {
if (path.indexOf('~') === 0) {
// eslint-disable-next-line no-console
console.warn('[nuxt] Aliases using `~` are deprecated, please use `@/` instead.',
path, '->', path.replace('~/', '@/').replace('~', '@/'))
}
return join(this.options.srcDir, path.substr(1))
}
return resolve(this.options.srcDir, path)
}
async close (callback) { async close (callback) {
await this.applyPluginsAsync('close') await this.applyPluginsAsync('close')

View File

@ -146,12 +146,7 @@ export default class Renderer extends Tapable {
useMiddleware (m) { useMiddleware (m) {
// Resolve // Resolve
if (typeof m === 'string') { if (typeof m === 'string') {
let src = m m = require(this.nuxt.resolvePath(m))
// Using ~ or ./ shorthand to resolve from project srcDir
if (src.indexOf('~') === 0 || src.indexOf('./') === 0) {
src = join(this.nuxt.options.srcDir, src.substr(1))
}
m = require(src)
} }
// Use middleware // Use middleware
if (m instanceof Function) { if (m instanceof Function) {

View File

@ -7,7 +7,7 @@
// Node Source Map Support // Node Source Map Support
// https://github.com/evanw/node-source-map-support // https://github.com/evanw/node-source-map-support
require('source-map-support').install(); require('source-map-support').install()
// Fix babel flag // Fix babel flag
/* istanbul ignore else */ /* istanbul ignore else */

View File

@ -23,8 +23,8 @@ module.exports = function basicModule (options, resolve) {
}) })
// Require same module twice // Require same module twice
this.requireModule('~/modules/empty/index.js') this.requireModule('@/modules/empty/index.js')
this.requireModule('~/modules/empty/index.js') this.requireModule('@/modules/empty/index.js')
resolve() resolve()
} }

View File

@ -9,14 +9,14 @@ module.exports = function middlewareModule (options) {
} }
}) })
// Add local middleware js // Add local middleware js
this.addServerMiddleware('~/modules/middleware/log.js') this.addServerMiddleware('@modules/middleware/log.js')
// Add plain middleware // Add plain middleware
this.addServerMiddleware((req, res, next) => { this.addServerMiddleware((req, res, next) => {
res.setHeader('x-nuxt', 'hello') res.setHeader('x-nuxt', 'hello')
next() next()
}) })
// Add file middleware // Add file middleware
this.addServerMiddleware('~/modules/middleware/midd1') this.addServerMiddleware('@modules/middleware/midd1')
resolve() resolve()
}) })
} }

View File

@ -1,9 +1,9 @@
module.exports = { module.exports = {
loading: true, loading: true,
modules: [ modules: [
'~modules/basic', '~modules/basic', // Use ~ for deprication warning coverage
{ {
src: '~/modules/middleware', src: '@/modules/middleware',
options: { options: {
foo: 'bar' foo: 'bar'
} }

View File

@ -8,14 +8,14 @@ export function createRouter () {
mode: 'history', mode: 'history',
routes: [ routes: [
{ {
path: "/", path: '/',
component: require('~/views/index.vue'), component: require('~/views/index.vue'),
name: "index" name: 'index'
}, },
{ {
path: "/about", path: '/about',
component: require('~/views/about.vue'), component: require('~/views/about.vue'),
name: "about" name: 'about'
} }
] ]
}) })

View File

@ -7,18 +7,17 @@ module.exports = {
routes.push({ routes.push({
name: 'about-bis', name: 'about-bis',
path: '/about-bis', path: '/about-bis',
component: '~pages/about.vue' component: '@pages/about.vue'
}) })
} }
}, },
transition: 'test', transition: 'test',
offline: true, offline: true,
plugins: [ plugins: [
'~plugins/test.js', '~plugins/test.js', // Use ~ for deprication warning coverage
{ src: '~plugins/offline.js', ssr: false }, { src: '@plugins/only-client.js', ssr: false }
{ src: '~plugins/only-client.js', ssr: false }
], ],
loading: '~components/loading', loading: '@components/loading',
env: { env: {
bool: true, bool: true,
num: 23, num: 23,
@ -36,7 +35,7 @@ module.exports = {
} }
}, },
css: [ css: [
{ src: '~/assets/app.css' } { src: '@assets/app.css' }
], ],
render: { render: {
http2: { http2: {

View File

@ -1,4 +0,0 @@
if (process.env.NODE_ENV === 'production') {
var OfflinePlugin = require('offline-plugin/runtime')
OfflinePlugin.install()
}