mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
refactor: use more functional programming (#3612)
This commit is contained in:
parent
18802c9a5f
commit
76b10d2d3f
@ -109,7 +109,7 @@ function mapTransitions(Components, to, from) {
|
||||
if (from && from.matched.length && from.matched[0].components.default) {
|
||||
const from_transitions = componentTransitions(from.matched[0].components.default)
|
||||
Object.keys(from_transitions)
|
||||
.filter((key) => from_transitions[key] && key.toLowerCase().indexOf('leave') !== -1)
|
||||
.filter((key) => from_transitions[key] && key.toLowerCase().includes('leave'))
|
||||
.forEach((key) => { transitions[key] = from_transitions[key] })
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ export default {
|
||||
transitionProps[key] = transition[key]
|
||||
}
|
||||
})
|
||||
|
||||
let listeners = {}
|
||||
listenersKeys.forEach((key) => {
|
||||
if (typeof transition[key] === 'function') {
|
||||
@ -30,7 +31,7 @@ export default {
|
||||
}
|
||||
})
|
||||
// Add triggerScroll event on beforeEnter (fix #1376)
|
||||
let beforeEnter = listeners.beforeEnter
|
||||
const beforeEnter = listeners.beforeEnter
|
||||
listeners.beforeEnter = (el) => {
|
||||
// Ensure to trigger scroll event after calling scrollBehavior
|
||||
window.<%= globals.nuxt %>.$nextTick(() => {
|
||||
|
@ -1,18 +1,16 @@
|
||||
<% if (middleware) { %>
|
||||
let files = require.context('@/<%= dir.middleware %>', false, /^\.\/(?!<%= ignorePrefix %>)[^.]+\.(<%= extensions %>)$/)
|
||||
let filenames = files.keys()
|
||||
const files = require.context('@/<%= dir.middleware %>', false, /^\.\/(?!<%= ignorePrefix %>)[^.]+\.(<%= extensions %>)$/)
|
||||
const filenames = files.keys()
|
||||
|
||||
function getModule (filename) {
|
||||
let file = files(filename)
|
||||
return file.default
|
||||
? file.default
|
||||
: file
|
||||
const file = files(filename)
|
||||
return file.default || file
|
||||
}
|
||||
let middleware = {}
|
||||
const middleware = {}
|
||||
|
||||
// Generate the middleware
|
||||
for (let filename of filenames) {
|
||||
let name = filename.replace(/^\.\//, '').replace(/\.(<%= extensions %>)$/, '')
|
||||
for (const filename of filenames) {
|
||||
const name = filename.replace(/^\.\//, '').replace(/\.(<%= extensions %>)$/, '')
|
||||
middleware[name] = getModule(filename)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ const createNext = (ssrContext) => (opts) => {
|
||||
}
|
||||
opts.query = stringify(opts.query)
|
||||
opts.path = opts.path + (opts.query ? '?' + opts.query : '')
|
||||
if (opts.path.indexOf('http') !== 0 && ('<%= router.base %>' !== '/' && opts.path.indexOf('<%= router.base %>') !== 0)) {
|
||||
if (!opts.path.startsWith('http') && ('<%= router.base %>' !== '/' && !opts.path.startsWith('<%= router.base %>'))) {
|
||||
opts.path = urlJoin('<%= router.base %>', opts.path)
|
||||
}
|
||||
// Avoid loop redirect
|
||||
|
@ -10,7 +10,7 @@ const filenames = files.keys()
|
||||
let storeData = {}
|
||||
|
||||
// Check if {dir.store}/index.js exists
|
||||
const indexFilename = filenames.find(name => name.includes('./index.'))
|
||||
const indexFilename = filenames.find(filename => filename.includes('./index.'))
|
||||
|
||||
if (indexFilename) {
|
||||
storeData = getModule(indexFilename)
|
||||
|
@ -496,7 +496,7 @@ function formatUrl (url, query) {
|
||||
if (index !== -1) {
|
||||
protocol = url.substring(0, index)
|
||||
url = url.substring(index + 3)
|
||||
} else if (url.indexOf('//') === 0) {
|
||||
} else if (url.startsWith('//')) {
|
||||
url = url.substring(2)
|
||||
}
|
||||
|
||||
|
@ -318,7 +318,6 @@ export default class Builder {
|
||||
templateVars.router.routes,
|
||||
r
|
||||
)
|
||||
|
||||
// router.extendRoutes method
|
||||
if (typeof this.options.router.extendRoutes === 'function') {
|
||||
// let the user extend the routes
|
||||
@ -349,7 +348,7 @@ export default class Builder {
|
||||
templatesFiles = templatesFiles
|
||||
.map((file) => {
|
||||
// Skip if custom file was already provided in build.templates[]
|
||||
if (customTemplateFiles.indexOf(file) !== -1) {
|
||||
if (customTemplateFiles.includes(file)) {
|
||||
return
|
||||
}
|
||||
// Allow override templates using a file with same name in ${srcDir}/app
|
||||
|
@ -1,10 +1,9 @@
|
||||
import path from 'path'
|
||||
import _ from 'lodash'
|
||||
import htmlMinifier from 'html-minifier'
|
||||
import Chalk from 'chalk'
|
||||
import fsExtra from 'fs-extra'
|
||||
import consola from 'consola'
|
||||
import { flatRoutes, isUrl, promisifyRoute, waitFor } from '../common/utils'
|
||||
import { flatRoutes, isUrl, promisifyRoute, waitFor, isString } from '../common/utils'
|
||||
|
||||
export default class Generator {
|
||||
constructor(nuxt, builder) {
|
||||
@ -187,13 +186,13 @@ export default class Generator {
|
||||
// Fill routeMap with given generate.routes
|
||||
generateRoutes.forEach((route) => {
|
||||
// route is either a string or like { route : '/my_route/1', payload: {} }
|
||||
const path = _.isString(route) ? route : route.route
|
||||
const path = isString(route) ? route : route.route
|
||||
routeMap[path] = {
|
||||
route: path,
|
||||
payload: route.payload || null
|
||||
}
|
||||
})
|
||||
return _.values(routeMap)
|
||||
return Object.values(routeMap)
|
||||
}
|
||||
|
||||
async generateRoute({ route, payload = {}, errors = [] }) {
|
||||
|
@ -76,9 +76,9 @@ export default class WebpackBaseConfig {
|
||||
'process.mode': JSON.stringify(this.options.mode),
|
||||
'process.static': this.isStatic
|
||||
}
|
||||
_.each(this.options.env, (value, key) => {
|
||||
Object.entries(this.options.env).forEach(([key, value]) => {
|
||||
env['process.env.' + key] =
|
||||
['boolean', 'number'].indexOf(typeof value) !== -1
|
||||
['boolean', 'number'].includes(typeof value)
|
||||
? value
|
||||
: JSON.stringify(value)
|
||||
})
|
||||
@ -153,15 +153,14 @@ export default class WebpackBaseConfig {
|
||||
test: /\.jsx?$/,
|
||||
exclude: (file) => {
|
||||
// not exclude files outside node_modules
|
||||
if (/node_modules/.test(file)) {
|
||||
for (const module of [/\.vue\.js/].concat(this.options.build.transpile)) {
|
||||
// item in transpile can be string or regex object
|
||||
if (module.test(file)) {
|
||||
if (!/node_modules/.test(file)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// item in transpile can be string or regex object
|
||||
const modulesToTranspile = [/\.vue\.js/].concat(this.options.build.transpile)
|
||||
|
||||
return !modulesToTranspile.some(module => module.test(file))
|
||||
},
|
||||
use: perfLoader.pool('js', {
|
||||
loader: 'babel-loader',
|
||||
|
@ -23,7 +23,7 @@ export default class VueSSRClientPlugin {
|
||||
|
||||
const asyncFiles = allFiles
|
||||
.filter(file => isJS(file) || isCSS(file))
|
||||
.filter(file => initialFiles.indexOf(file) < 0)
|
||||
.filter(file => !initialFiles.includes(file))
|
||||
|
||||
const manifest = {
|
||||
publicPath: stats.publicPath,
|
||||
|
@ -13,7 +13,7 @@ export default class WebpackServerConfig extends BaseConfig {
|
||||
}
|
||||
|
||||
devtool() {
|
||||
return 'cheap-source-map'
|
||||
return 'cheap-module-inline-source-map'
|
||||
}
|
||||
|
||||
env() {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
import { wrapArray } from '../../../common/utils'
|
||||
import PostcssConfig from './postcss'
|
||||
|
||||
export default class StyleLoader {
|
||||
@ -19,7 +20,7 @@ export default class StyleLoader {
|
||||
}
|
||||
|
||||
normalize(loaders) {
|
||||
loaders = Array.isArray(loaders) ? loaders : [loaders]
|
||||
loaders = wrapArray(loaders)
|
||||
return loaders.map(loader => (typeof loader === 'string' ? { loader } : loader))
|
||||
}
|
||||
|
||||
@ -28,9 +29,7 @@ export default class StyleLoader {
|
||||
// style-resources-loader
|
||||
// https://github.com/yenshih/style-resources-loader
|
||||
if (extResource) {
|
||||
const patterns = Array.isArray(extResource)
|
||||
? extResource
|
||||
: [extResource]
|
||||
const patterns = wrapArray(extResource)
|
||||
|
||||
return {
|
||||
loader: 'style-resources-loader',
|
||||
|
@ -97,18 +97,14 @@ Options.from = function (_options) {
|
||||
// Populate modulesDir
|
||||
options.modulesDir = []
|
||||
.concat(options.modulesDir)
|
||||
.concat(path.join(options.nuxtDir, 'node_modules'))
|
||||
.filter(hasValue)
|
||||
.concat(path.join(options.nuxtDir, 'node_modules')).filter(hasValue)
|
||||
.map(dir => path.resolve(options.rootDir, dir))
|
||||
|
||||
// Sanitize extensions
|
||||
if (options.extensions.indexOf('js') === -1) {
|
||||
options.extensions.unshift('js')
|
||||
}
|
||||
const mandatoryExtensions = ['js', 'mjs']
|
||||
|
||||
if (options.extensions.indexOf('mjs') === -1) {
|
||||
options.extensions.unshift('mjs')
|
||||
}
|
||||
options.extensions = mandatoryExtensions
|
||||
.filter(ext => !options.extensions.includes(ext))
|
||||
.concat(options.extensions)
|
||||
|
||||
// If app.html is defined, set the template path to the user template
|
||||
if (options.appTemplatePath === undefined) {
|
||||
|
@ -14,6 +14,15 @@ export const waitFor = function waitFor(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms || 0))
|
||||
}
|
||||
|
||||
export const isString = function isString(obj) {
|
||||
return typeof obj === 'string' || obj instanceof String
|
||||
}
|
||||
export const startsWithAlias = aliasArray => str => aliasArray.some(c => str.startsWith(c))
|
||||
|
||||
export const startsWithSrcAlias = startsWithAlias(['@', '~'])
|
||||
|
||||
export const startsWithRootAlias = startsWithAlias(['@@', '~~'])
|
||||
|
||||
async function promiseFinally(fn, finalFn) {
|
||||
let result
|
||||
try {
|
||||
@ -46,7 +55,7 @@ export const urlJoin = function urlJoin() {
|
||||
}
|
||||
|
||||
export const isUrl = function isUrl(url) {
|
||||
return url.indexOf('http') === 0 || url.indexOf('//') === 0
|
||||
return ['http', '//'].some(str => url.startsWith(str))
|
||||
}
|
||||
|
||||
export const promisifyRoute = function promisifyRoute(fn, ...args) {
|
||||
@ -139,11 +148,10 @@ const reqSep = /\//g
|
||||
const sysSep = _.escapeRegExp(path.sep)
|
||||
const normalize = string => string.replace(reqSep, sysSep)
|
||||
|
||||
export const r = function r() {
|
||||
const args = Array.prototype.slice.apply(arguments)
|
||||
const lastArg = _.last(args)
|
||||
export const r = function r(...args) {
|
||||
const lastArg = args[args.length - 1]
|
||||
|
||||
if (lastArg.indexOf('@') === 0 || lastArg.indexOf('~') === 0) {
|
||||
if (startsWithSrcAlias(lastArg)) {
|
||||
return wp(lastArg)
|
||||
}
|
||||
|
||||
@ -155,7 +163,7 @@ export const relativeTo = function relativeTo() {
|
||||
const dir = args.shift()
|
||||
|
||||
// Keep webpack inline loader intact
|
||||
if (args[0].indexOf('!') !== -1) {
|
||||
if (args[0].includes('!')) {
|
||||
const loaders = args.shift().split('!')
|
||||
|
||||
return loaders.concat(relativeTo(dir, loaders.pop(), ...args)).join('!')
|
||||
@ -165,7 +173,7 @@ export const relativeTo = function relativeTo() {
|
||||
const _path = r(...args)
|
||||
|
||||
// Check if path is an alias
|
||||
if (_path.indexOf('@') === 0 || _path.indexOf('~') === 0) {
|
||||
if (startsWithSrcAlias(_path)) {
|
||||
return _path
|
||||
}
|
||||
|
||||
@ -180,22 +188,22 @@ export const relativeTo = function relativeTo() {
|
||||
|
||||
export const flatRoutes = function flatRoutes(router, _path = '', routes = []) {
|
||||
router.forEach((r) => {
|
||||
if (!r.path.includes(':') && !r.path.includes('*')) {
|
||||
if ([':', '*'].some(c => r.path.includes(c))) {
|
||||
return
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (r.children) {
|
||||
if (_path === '' && r.path === '/') {
|
||||
routes.push('/')
|
||||
}
|
||||
flatRoutes(r.children, _path + r.path + '/', routes)
|
||||
} else {
|
||||
return flatRoutes(r.children, _path + r.path + '/', routes)
|
||||
}
|
||||
_path = _path.replace(/^\/+$/, '/')
|
||||
routes.push(
|
||||
(r.path === '' && _path[_path.length - 1] === '/'
|
||||
? _path.slice(0, -1)
|
||||
: _path) + r.path
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
return routes
|
||||
}
|
||||
@ -214,7 +222,7 @@ function cleanChildrenRoutes(routes, isChild = false) {
|
||||
})
|
||||
routes.forEach((route) => {
|
||||
route.path = isChild ? route.path.replace('/', '') : route.path
|
||||
if (route.path.indexOf('?') > -1) {
|
||||
if (route.path.includes('?')) {
|
||||
const names = route.name.split('-')
|
||||
const paths = route.path.split('/')
|
||||
if (!isChild) {
|
||||
@ -259,15 +267,15 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
|
||||
let parent = routes
|
||||
keys.forEach((key, i) => {
|
||||
// remove underscore only, if its the prefix
|
||||
const sanitizedKey = key.indexOf('_') === 0
|
||||
? key.replace('_', '')
|
||||
: key
|
||||
const sanitizedKey = key.startsWith('_') ? key.substr(1) : key
|
||||
|
||||
route.name = route.name
|
||||
? route.name + '-' + sanitizedKey
|
||||
: sanitizedKey
|
||||
route.name += key === '_' ? 'all' : ''
|
||||
route.chunkName = file.replace(/\.(vue|js)$/, '')
|
||||
const child = _.find(parent, { name: route.name })
|
||||
const child = parent.find(parentRoute => parentRoute.name === route.name)
|
||||
|
||||
if (child) {
|
||||
child.children = child.children || []
|
||||
parent = child.children
|
||||
@ -275,13 +283,9 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
|
||||
} else if (key === 'index' && i + 1 === keys.length) {
|
||||
route.path += i > 0 ? '' : '/'
|
||||
} else {
|
||||
route.path += '/' +
|
||||
(key === '_'
|
||||
? '*'
|
||||
: key.indexOf('_') === 0
|
||||
? key.replace('_', ':')
|
||||
: key)
|
||||
if (key !== '_' && key.indexOf('_') === 0) {
|
||||
route.path += '/' + getRoutePathExtension(key)
|
||||
|
||||
if (key.startsWith('_') && key.length > 1) {
|
||||
route.path += '?'
|
||||
}
|
||||
}
|
||||
@ -298,12 +302,13 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
|
||||
// Order: /static, /index, /:dynamic
|
||||
// Match exact route before index: /login before /index/_slug
|
||||
if (a.path === '/') {
|
||||
return /^\/(:|\*)/.test(b.path) ? -1 : 1
|
||||
return DYNAMIC_ROUTE_REGEX.test(b.path) ? -1 : 1
|
||||
}
|
||||
if (b.path === '/') {
|
||||
return /^\/(:|\*)/.test(a.path) ? 1 : -1
|
||||
return DYNAMIC_ROUTE_REGEX.test(a.path) ? 1 : -1
|
||||
}
|
||||
let i = 0
|
||||
|
||||
let i
|
||||
let res = 0
|
||||
let y = 0
|
||||
let z = 0
|
||||
@ -313,8 +318,8 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
|
||||
if (res !== 0) {
|
||||
break
|
||||
}
|
||||
y = _a[i] === '*' ? 2 : _a[i].indexOf(':') > -1 ? 1 : 0
|
||||
z = _b[i] === '*' ? 2 : _b[i].indexOf(':') > -1 ? 1 : 0
|
||||
y = _a[i] === '*' ? 2 : _a[i].includes(':') ? 1 : 0
|
||||
z = _b[i] === '*' ? 2 : _b[i].includes(':') ? 1 : 0
|
||||
res = y - z
|
||||
// If a.length >= b.length
|
||||
if (i === _b.length - 1 && res === 0) {
|
||||
@ -361,3 +366,25 @@ export const determineGlobals = function determineGlobals(globalName, globals) {
|
||||
}
|
||||
return _globals
|
||||
}
|
||||
|
||||
const getRoutePathExtension = (key) => {
|
||||
if (key === '_') {
|
||||
return '*'
|
||||
}
|
||||
|
||||
if (key.startsWith('_')) {
|
||||
return `:${key.substr(1)}`
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
const DYNAMIC_ROUTE_REGEX = /^\/(:|\*)/
|
||||
|
||||
/**
|
||||
* Wraps value in array if it is not already an array
|
||||
*
|
||||
* @param {any} value
|
||||
* @return {array}
|
||||
*/
|
||||
export const wrapArray = value => Array.isArray(value) ? value : [value]
|
||||
|
@ -11,7 +11,7 @@ import esm from 'esm'
|
||||
import ip from 'ip'
|
||||
|
||||
import Options from '../common/options'
|
||||
import { sequence } from '../common/utils'
|
||||
import { sequence, startsWithRootAlias, startsWithSrcAlias } from '../common/utils'
|
||||
import packageJSON from '../../package.json'
|
||||
|
||||
import ModuleContainer from './module'
|
||||
@ -254,11 +254,11 @@ export default class Nuxt {
|
||||
return modulePath
|
||||
}
|
||||
|
||||
if (path.indexOf('@@') === 0 || path.indexOf('~~') === 0) {
|
||||
if (startsWithRootAlias(path)) {
|
||||
return join(this.options.rootDir, path.substr(2))
|
||||
}
|
||||
|
||||
if (path.indexOf('@') === 0 || path.indexOf('~') === 0) {
|
||||
if (startsWithSrcAlias(path)) {
|
||||
return join(this.options.srcDir, path.substr(1))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user