Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(builder): validate vue-app dependencies and suggest fix #4669

Merged
merged 5 commits into from Jan 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/builder/package.json
Expand Up @@ -18,6 +18,7 @@
"hash-sum": "^1.0.2",
"lodash": "^4.17.11",
"pify": "^4.0.1",
"semver": "^5.6.0",
"serialize-javascript": "^1.6.1",
"upath": "^1.1.0"
},
Expand Down
55 changes: 50 additions & 5 deletions packages/builder/src/builder.js
Expand Up @@ -7,6 +7,7 @@ import hash from 'hash-sum'
import pify from 'pify'
import serialize from 'serialize-javascript'
import upath from 'upath'
import semver from 'semver'

import debounce from 'lodash/debounce'
import omit from 'lodash/omit'
Expand Down Expand Up @@ -75,7 +76,7 @@ export default class Builder {
// Resolve template
this.template = this.options.build.template || '@nuxt/vue-app'
if (typeof this.template === 'string') {
this.template = this.nuxt.resolver.requireModule(this.template)
this.template = this.nuxt.resolver.requireModule(this.template).template
}

// if(!this.options.dev) {
Expand Down Expand Up @@ -205,6 +206,13 @@ export default class Builder {
}
}

// Validate template
try {
this.validateTemplate()
} catch (err) {
consola.fatal(err)
}

consola.success('Builder initialized')

consola.debug(`App root: ${this.options.srcDir}`)
Expand Down Expand Up @@ -237,14 +245,51 @@ export default class Builder {
return this
}

validateTemplate() {
// Validate template dependencies
const templateDependencies = this.template.dependencies
const dpendencyFixes = []
for (const depName in templateDependencies) {
const depVersion = templateDependencies[depName]
const requiredVersion = `${depName}@${depVersion}`

// Load installed version
const pkg = this.nuxt.resolver.requireModule(path.join(depName, 'package.json'))
if (pkg) {
const validVersion = semver.satisfies(pkg.version, depVersion)
if (!validVersion) {
consola.warn(`${requiredVersion} is required but ${depName}@${pkg.version} is installed!`)
dpendencyFixes.push(requiredVersion)
}
} else {
consola.warn(`${depName}@${depVersion} is required but not installed!`)
dpendencyFixes.push(requiredVersion)
}
}

// Suggest dependency fixes (TODO: automate me)
if (dpendencyFixes.length) {
consola.error(
`Please install missing dependencies:\n`,
'\n',
`Using yarn:\n`,
`yarn add ${dpendencyFixes.join(' ')}\n`,
'\n',
`Using npm:\n`,
`npm i ${dpendencyFixes.join(' ')}\n`
)
throw new Error('Missing Template Dependencies')
}
}

async generateRoutesAndFiles() {
consola.debug(`Generating nuxt files`)

// Plugins
this.plugins = Array.from(this.normalizePlugins())

// -- Templates --
let templatesFiles = Array.from(this.template.templatesFiles)
let templatesFiles = Array.from(this.template.files)

const templateVars = {
options: this.options,
Expand Down Expand Up @@ -325,7 +370,7 @@ export default class Builder {
if (this._defaultPage) {
templateVars.router.routes = createRoutes(
['index.vue'],
this.template.templatesDir + '/pages',
this.template.dir + '/pages',
'',
this.options.router.routeNameSplitter
)
Expand Down Expand Up @@ -396,7 +441,7 @@ export default class Builder {
const customFileExists = fsExtra.existsSync(customPath)

return {
src: customFileExists ? customPath : r(this.template.templatesDir, file),
src: customFileExists ? customPath : r(this.template.dir, file),
dst: file,
custom: customFileExists
}
Expand All @@ -421,7 +466,7 @@ export default class Builder {
// -- Loading indicator --
if (this.options.loadingIndicator.name) {
const indicatorPath1 = path.resolve(
this.template.templatesDir,
this.template.dir,
'views/loading',
this.options.loadingIndicator.name + '.html'
)
Expand Down
8 changes: 0 additions & 8 deletions packages/config/src/options.js
Expand Up @@ -253,14 +253,6 @@ export function getNuxtConfig(_options) {
delete options.render.gzip
}

if (options.nuxtAppDir) {
consola.warn('nuxtAppDir is deprecated and will be removed in a future version! Please switch to build.template')
options.build.template = {
templatesDir: options.nuxtAppDir
}
delete options.nuxtAppDir
}

// Apply mode preset
const modePreset = options.modes[options.mode || 'universal']

Expand Down
48 changes: 24 additions & 24 deletions packages/vue-app/src/index.js
@@ -1,26 +1,26 @@
import path from 'path'
import pkg from '../package.json'
import { dependencies } from '../package.json'

export const meta = pkg

export const templatesDir = path.join(__dirname, '..', 'template')

export const templatesFiles = [
'App.js',
'client.js',
'index.js',
'middleware.js',
'router.js',
'server.js',
'utils.js',
'empty.js',
'components/nuxt-error.vue',
'components/nuxt-loading.vue',
'components/nuxt-child.js',
'components/nuxt-link.server.js',
'components/nuxt-link.client.js',
'components/nuxt.js',
'components/no-ssr.js',
'views/app.template.html',
'views/error.html'
]
export const template = {
clarkdo marked this conversation as resolved.
Show resolved Hide resolved
dependencies,
dir: path.join(__dirname, '..', 'template'),
files: [
'App.js',
'client.js',
'index.js',
'middleware.js',
'router.js',
'server.js',
'utils.js',
'empty.js',
'components/nuxt-error.vue',
'components/nuxt-loading.vue',
'components/nuxt-child.js',
'components/nuxt-link.server.js',
'components/nuxt-link.client.js',
'components/nuxt.js',
'components/no-ssr.js',
'views/app.template.html',
'views/error.html'
]
}
6 changes: 0 additions & 6 deletions packages/vue-app/template/router.js
Expand Up @@ -81,12 +81,6 @@ const _routes = recursiveRoutes(router.routes, ' ', _components, 2)
}).join('\n')%>

Vue.use(Router)
// router-view was changed to RouterView in vue-router 3.0.2
// Fix: Vue.component('RouterLink') is undefined in vue-router 3.0.0
if (!Vue.component('RouterLink')) {
Vue.options.components['RouterView'] = Vue.component('router-view')
Vue.options.components['RouterLink'] = Vue.component('router-link')
}

<% if (router.scrollBehavior) { %>
const scrollBehavior = <%= serializeFunction(router.scrollBehavior) %>
Expand Down