- Make sure tests pass!
-- Commit messages must follow the [commit message convention](./commit-convention.md) so that changelogs can be automatically generated. Commit messages are automatically validated before commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)).
+- Commit messages must follow the [commit message convention](./commit-convention.md) so that the changelog can be automatically generated. Commit messages are automatically validated before commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)).
- No need to worry about code style as long as you have installed the dev dependencies - modified files are automatically formatted with Prettier on commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)).
Vue Router source code can be found in the `src` directory:
-- `src/components`: RouterLink and RouterView components.
- `src/history`: history implementations that are instantiable with `create*History()`. This folder contains code related to using the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API).
-- `src/matcher`: RouteMatcher implementation. Contains the code that transforms paths like `/users/:id` into regexes and handle the transformation of locations like `{ name: 'UserDetail', params: { id: '2' } }` to strings. It contains path ranking logic and the part of dynamic routing that concerns matching urls in the right order.
-- `src/utils`: contains util functions that are used accross other sections of the router but are not contained by them.
+- `src/matcher`: RouteMatcher implementation. Contains the code that transforms paths like `/users/:id` into regexps and handle the transformation of locations like `{ name: 'UserDetail', params: { id: '2' } }` to strings. It contains path ranking logic and the part of dynamic routing that concerns matching urls in the right order.
+- `src/utils`: contains small utility functions that are used across other sections of the router but are not contained by them.
- `src/router`: contains the router creation, navigation execution, using the matcher, the history implementation. It runs navigation guards.
+- `src/location`: helpers related to route location and urls
+- `src/encoding`: helpers related to url encoding
+- `src/errors`: different internal and external errors with their messages
- `src/index`: contains all public API as exports.
- `src/types`: contains global types that are used across multiple sections of the router.
/**
* @jest-environment jsdom
*/
-import { RouterLink } from '../src/components/Link'
+import { RouterLink } from '../src/RouterLink'
import {
START_LOCATION_NORMALIZED,
RouteQueryAndHash,
import { mount, createMockedRoute } from './mount'
import { nextTick } from 'vue'
import { RouteRecordNormalized } from '../src/matcher/types'
-import { routerKey } from '../src/utils/injectionSymbols'
+import { routerKey } from '../src/injectionSymbols'
const records = {
home: {} as RouteRecordNormalized,
/**
* @jest-environment jsdom
*/
-import { RouterView } from '../src/components/View'
+import { RouterView } from '../src/RouterView'
import { components, RouteLocationNormalizedLoose } from './utils'
import { START_LOCATION_NORMALIZED } from '../src/types'
import { markRaw } from 'vue'
encodeParam,
encodeQueryProperty,
// decode,
-} from '../src/utils/encoding'
+} from '../src/encoding'
describe('Encoding', () => {
// all ascii chars with a non ascii char at the beginning
import { normalizeHistoryLocation as normalizeLocation } from '../src/history/common'
-import { parseQuery, stringifyQuery } from '../src/utils/query'
+import { parseQuery, stringifyQuery } from '../src/query'
import {
parseURL as originalParseURL,
stringifyURL as originalStringifyURL,
stripBase,
isSameLocationObject,
-} from '../src/utils/location'
+} from '../src/location'
describe('parseURL', () => {
let parseURL = originalParseURL.bind(null, parseQuery)
import { compile } from '@vue/compiler-dom'
import * as runtimeDom from '@vue/runtime-dom'
import { RouteLocationNormalizedLoose } from './utils'
-import { routeLocationKey } from '../src/utils/injectionSymbols'
+import { routeLocationKey } from '../src/injectionSymbols'
export interface MountOptions {
propsData: Record<string, any>
-import { parseQuery } from '../src/utils/query'
+import { parseQuery } from '../src/query'
import { mockWarn } from 'jest-mock-warn'
describe('parseQuery', () => {
-import { stringifyQuery } from '../src/utils/query'
+import { stringifyQuery } from '../src/query'
import { mockWarn } from 'jest-mock-warn'
describe('stringifyQuery', () => {
import { components } from './utils'
import { RouteRecordRaw } from '../src/types'
import { createMemoryHistory } from '../src'
-import * as encoding from '../src/utils/encoding'
+import * as encoding from '../src/encoding'
jest.mock('../src/utils/encoding')
unref,
Component,
} from 'vue'
-import { RouteLocationRaw, VueUseOptions, RouteLocation } from '../types'
-import { isSameLocationObject, isSameRouteRecord } from '../utils/location'
-import { routerKey, routeLocationKey } from '../utils/injectionSymbols'
-import { RouteRecord } from '../matcher/types'
+import { RouteLocationRaw, VueUseOptions, RouteLocation } from './types'
+import { isSameLocationObject, isSameRouteRecord } from './location'
+import { routerKey, routeLocationKey } from './injectionSymbols'
+import { RouteRecord } from './matcher/types'
interface LinkProps {
to: RouteLocationRaw
ComponentPublicInstance,
Component,
} from 'vue'
-import { RouteLocationNormalizedLoaded } from '../types'
+import { RouteLocationNormalizedLoaded } from './types'
import {
matchedRouteKey,
viewDepthKey,
routeLocationKey,
-} from '../utils/injectionSymbols'
+} from './injectionSymbols'
export const RouterView = (defineComponent({
name: 'RouterView',
ScrollPositionCoordinates,
} from '../scrollBehavior'
import { warn } from 'vue'
-import { stripBase } from '../utils/location'
+import { stripBase } from '../location'
type PopStateListener = (this: Window, ev: PopStateEvent) => any
stringifyQuery,
LocationQueryRaw,
LocationQueryValue,
-} from './utils/query'
+} from './query'
export { RouterHistory } from './history/common'
export { NavigationFailureType, NavigationFailure } from './errors'
export { onBeforeRouteLeave } from './navigationGuards'
-export { RouterLink, useLink } from './components/Link'
-export { RouterView } from './components/View'
+export { RouterLink, useLink } from './RouterLink'
+export { RouterView } from './RouterView'
export { createWebHistory, createMemoryHistory, createWebHashHistory }
import { InjectionKey, ComputedRef } from 'vue'
-import { RouteLocationNormalizedLoaded } from '../types'
-import { Router } from '../router'
-import { RouteRecordNormalized } from '../matcher/types'
+import { RouteLocationNormalizedLoaded } from './types'
+import { Router } from './router'
+import { RouteRecordNormalized } from './matcher/types'
export const hasSymbol =
typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'
import { App, ComputedRef, reactive } from 'vue'
import { Router } from './router'
-import { RouterLink } from './components/Link'
-import { RouterView } from './components/View'
+import { RouterLink } from './RouterLink'
+import { RouterView } from './RouterView'
import { isBrowser } from './utils'
import {
START_LOCATION_NORMALIZED,
NavigationGuardWithThis,
NavigationGuard,
} from './types'
-import { routerKey, routeLocationKey } from './utils/injectionSymbols'
+import { routerKey, routeLocationKey } from './injectionSymbols'
declare module '@vue/runtime-core' {
interface ComponentCustomOptions {
RouteLocation,
RouteLocationNormalized,
RouteParamValue,
-} from '../types'
-import { RouteRecord } from '../matcher/types'
+} from './types'
+import { RouteRecord } from './matcher/types'
/**
* Location object returned by {@link `parseURL`}.
} from './errors'
import { ComponentPublicInstance } from 'vue'
import { inject, getCurrentInstance, warn } from 'vue'
-import { matchedRouteKey } from './utils/injectionSymbols'
+import { matchedRouteKey } from './injectionSymbols'
import { RouteRecordNormalized } from './matcher/types'
import { isESModule } from './utils'
)
guards.push(async () => {
const resolved = await componentPromise
- if (!resolved) throw new Error('TODO: error while fetching')
+ if (!resolved)
+ throw new Error(
+ `Couldn't resolve component "${name}" for the following record with path "${record.path}"`
+ )
const resolvedComponent = isESModule(resolved)
? resolved.default
: resolved
-import { decode, encodeQueryProperty } from '../utils/encoding'
+import { decode, encodeQueryProperty } from './encoding'
/**
* Possible values in normalized {@link LocationQuery}
} from './errors'
import { applyToParams, isBrowser } from './utils'
import { useCallbacks } from './utils/callbacks'
-import { encodeParam, decode } from './utils/encoding'
+import { encodeParam, decode } from './encoding'
import {
normalizeQuery,
parseQuery as originalParseQuery,
stringifyQuery as originalStringifyQuery,
-} from './utils/query'
+} from './query'
import { ref, Ref, markRaw, nextTick, App, warn } from 'vue'
import { RouteRecord, RouteRecordNormalized } from './matcher/types'
-import { parseURL, stringifyURL, isSameRouteLocation } from './utils/location'
+import { parseURL, stringifyURL, isSameRouteLocation } from './location'
import { extractComponentsGuards, guardToPromiseFn } from './navigationGuards'
import { applyRouterPlugin } from './install'
-import { LocationQuery, LocationQueryRaw } from '../utils/query'
+import { LocationQuery, LocationQueryRaw } from '../query'
import { PathParserOptions } from '../matcher/pathParserRanker'
import { markRaw, Ref, ComputedRef, ComponentOptions } from 'vue'
import { RouteRecord, RouteRecordNormalized } from '../matcher/types'
import { inject } from 'vue'
-import { routerKey, routeLocationKey } from './utils/injectionSymbols'
+import { routerKey, routeLocationKey } from './injectionSymbols'
import { Router } from './router'
import { RouteLocationNormalizedLoaded } from './types'
import { RouteParams, RouteComponent } from '../types'
-import { hasSymbol } from './injectionSymbols'
+import { hasSymbol } from '../injectionSymbols'
export * from './env'