refactor: use more functional programming (#3612)

This commit is contained in:
Alexander Lichter 2018-10-12 23:31:19 +01:00 committed by Pooya Parsa
parent 18802c9a5f
commit 76b10d2d3f
15 changed files with 105 additions and 87 deletions

View File

@ -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] })
}

View File

@ -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(() => {

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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 = [] }) {

View File

@ -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',

View File

@ -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,

View File

@ -13,7 +13,7 @@ export default class WebpackServerConfig extends BaseConfig {
}
devtool() {
return 'cheap-source-map'
return 'cheap-module-inline-source-map'
}
env() {

View File

@ -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',

View File

@ -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) {

View File

@ -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]

View File

@ -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))
}