docs(kit): initial documentation (#86)

This commit is contained in:
Daniel Roe 2021-04-15 19:49:29 +01:00 committed by GitHub
parent 6a30a6fd10
commit ce72ce6b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1717 additions and 37 deletions

View File

@ -2,11 +2,25 @@
"globals": { "globals": {
"NodeJS": true "NodeJS": true
}, },
"plugins": ["jsdoc"],
"extends": [ "extends": [
"plugin:jsdoc/recommended",
"@nuxtjs/eslint-config-typescript" "@nuxtjs/eslint-config-typescript"
], ],
"rules": { "rules": {
"no-console": "off", "no-console": "off",
"vue/one-component-per-file": "off" "vue/one-component-per-file": "off",
"jsdoc/require-jsdoc": "off",
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"jsdoc/require-param-type": "off"
},
"settings": {
"jsdoc": {
"tagNamePreference": {
"warning": "warning",
"note": "note"
}
}
} }
} }

View File

@ -23,6 +23,7 @@
"@types/jest": "^26.0.22", "@types/jest": "^26.0.22",
"@types/node": "^14.14.37", "@types/node": "^14.14.37",
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-plugin-jsdoc": "^32.3.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"jiti": "^1.9.1", "jiti": "^1.9.1",
"lerna": "^4.0.0", "lerna": "^4.0.0",

View File

@ -13,6 +13,7 @@ export function ensureReactive<
/** /**
* Returns a unique string suitable for syncing data between server and client. * Returns a unique string suitable for syncing data between server and client.
*
* @param nuxt (optional) A Nuxt instance * @param nuxt (optional) A Nuxt instance
* @param vm (optional) A Vue component - by default it will use the current instance * @param vm (optional) A Vue component - by default it will use the current instance
*/ */
@ -37,6 +38,7 @@ export function useSSRRef (nuxt = useNuxt(), vm = getCurrentInstance()): string
/** /**
* Allows accessing reactive data that can be synced between server and client. * Allows accessing reactive data that can be synced between server and client.
*
* @param nuxt (optional) A Nuxt instance * @param nuxt (optional) A Nuxt instance
* @param vm (optional) A Vue component - by default it will use the current instance * @param vm (optional) A Vue component - by default it will use the current instance
*/ */
@ -53,6 +55,7 @@ export function useData<T = Record<string, any>> (
/** /**
* Allows accessing reactive global data that can be synced between server and client. * Allows accessing reactive global data that can be synced between server and client.
*
* @param nuxt - (optional) A Nuxt instance * @param nuxt - (optional) A Nuxt instance
*/ */
export function useGlobalData (nuxt = useNuxt()): Record<string, any> { export function useGlobalData (nuxt = useNuxt()): Record<string, any> {

View File

@ -2,6 +2,7 @@ import { useNuxt } from '@nuxt/app'
/** /**
* Allows full control of the hydration cycle to set and receive data from the server. * Allows full control of the hydration cycle to set and receive data from the server.
*
* @param key a unique key to identify the data in the Nuxt payload * @param key a unique key to identify the data in the Nuxt payload
* @param get a function that returns the value to set the initial data * @param get a function that returns the value to set the initial data
* @param set a function that will receive the data on the client-side * @param set a function that will receive the data on the client-side

View File

@ -101,6 +101,7 @@ export const setNuxtInstance = (nuxt: Nuxt | null) => {
/** /**
* Ensures that the setup function passed in has access to the Nuxt instance via `useNuxt`. * Ensures that the setup function passed in has access to the Nuxt instance via `useNuxt`.
*
* @param nuxt A Nuxt instance * @param nuxt A Nuxt instance
* @param setup The function to call * @param setup The function to call
*/ */

View File

@ -3,15 +3,37 @@ import { existsSync, promises as fsp } from 'fs'
import dotenv from 'dotenv' import dotenv from 'dotenv'
export interface LoadDotEnvOptions { export interface LoadDotEnvOptions {
/** The project root directory (either absolute or relative to the current working directory). */
rootDir: string rootDir: string
/**
* What file to look in for environment variables (either absolute or relative
* to the current working directory). For example, `.env`.
*/
dotenvFile: string dotenvFile: string
/**
* Whether to interpolate variables within .env.
*
* @example
* ```env
* BASE_DIR="/test"
* # resolves to "/test/further"
* ANOTHER_DIR="${BASE_DIR}/further"
* ```
*/
expand: boolean expand: boolean
env: typeof process.env /** An object describing environment variables (key, value pairs). */
env: NodeJS.ProcessEnv
} }
export async function loadEnv (rootDir) { /**
* Load and interpolate environment variables into `process.env`.
* If you need more control (or access to the values), consider using `loadDotenv` instead
*
* @param rootDir - The project root directory (either absolute or relative to the current working directory).
*/
export async function loadEnv (rootDir: string) {
// Load env // Load env
const env = await loalDotenv({ const env = await loadDotenv({
rootDir, rootDir,
dotenvFile: '.env', dotenvFile: '.env',
env: process.env, env: process.env,
@ -26,12 +48,13 @@ export async function loadEnv (rootDir) {
} }
} }
export async function loalDotenv (opts: LoadDotEnvOptions) { /** Load environment variables into an object. */
export async function loadDotenv (opts: LoadDotEnvOptions) {
const env = Object.create(null) const env = Object.create(null)
const dotenvFile = resolve(opts.rootDir, opts.dotenvFile) const dotenvFile = resolve(opts.rootDir, opts.dotenvFile)
if (await existsSync(dotenvFile)) { if (existsSync(dotenvFile)) {
const parsed = dotenv.parse(await fsp.readFile(dotenvFile, 'utf-8')) const parsed = dotenv.parse(await fsp.readFile(dotenvFile, 'utf-8'))
Object.assign(env, parsed) Object.assign(env, parsed)
} }
@ -51,13 +74,13 @@ export async function loalDotenv (opts: LoadDotEnvOptions) {
} }
// Based on https://github.com/motdotla/dotenv-expand // Based on https://github.com/motdotla/dotenv-expand
function expand (target, source = {}, parse = v => v) { function expand (target: Record<string, any>, source: Record<string, any> = {}, parse = (v: any) => v) {
function getValue (key) { function getValue (key: string) {
// Source value 'wins' over target value // Source value 'wins' over target value
return source[key] !== undefined ? source[key] : target[key] return source[key] !== undefined ? source[key] : target[key]
} }
function interpolate (value, parents = []) { function interpolate (value: unknown, parents: string[] = []) {
if (typeof value !== 'string') { if (typeof value !== 'string') {
return value return value
} }
@ -66,7 +89,7 @@ function expand (target, source = {}, parse = v => v) {
const parts = /(.?)\${?([a-zA-Z0-9_:]+)?}?/g.exec(match) const parts = /(.?)\${?([a-zA-Z0-9_:]+)?}?/g.exec(match)
const prefix = parts[1] const prefix = parts[1]
let value, replacePart let value, replacePart: string
if (prefix === '\\') { if (prefix === '\\') {
replacePart = parts[0] replacePart = parts[0]

View File

@ -7,9 +7,12 @@ import { NuxtOptions } from '../types/config'
import nuxtConfigSchema from './schema' import nuxtConfigSchema from './schema'
export interface LoadNuxtConfigOptions { export interface LoadNuxtConfigOptions {
/** Your project root directory (either absolute or relative to the current working directory). */
rootDir?: string rootDir?: string
/** The path to your `nuxt.config` file (either absolute or relative to your project `rootDir`). */
configFile?: string configFile?: string
config?: any /** Any overrides to your Nuxt configuration. */
config?: Record<string, any>
} }
export function loadNuxtConfig (opts: LoadNuxtConfigOptions): NuxtOptions { export function loadNuxtConfig (opts: LoadNuxtConfigOptions): NuxtOptions {

View File

@ -4,16 +4,23 @@ import defu from 'defu'
import { isRelative, joinURL, hasProtocol } from 'ufo' import { isRelative, joinURL, hasProtocol } from 'ufo'
export default { export default {
/** /** Vue.js config */
* Vue.js configuration
*/
vue: { vue: {
/**
* Properties that will be set directly on `Vue.config` for vue@2 and `app.config` for vue@3.
*
* @see [vue@2 Documentation](https://vuejs.org/v2/api/#Global-Config)
* @see [vue@3 Documentation](https://v3.vuejs.org/api/application-config.html)
*/
config: { config: {
silent: { $resolve: (val, get) => val ?? get('dev') }, silent: { $resolve: (val, get) => val ?? get('dev') },
performance: { $resolve: (val, get) => val ?? get('dev') } performance: { $resolve: (val, get) => val ?? get('dev') }
} }
}, },
/**
* Nuxt App configuration.
*/
app: { app: {
$resolve: (val, get) => { $resolve: (val, get) => {
const useCDN = hasProtocol(get('build.publicPath'), true) && !get('dev') const useCDN = hasProtocol(get('build.publicPath'), true) && !get('dev')
@ -27,7 +34,21 @@ export default {
}, },
/** /**
* Uses {srcDir}/app.html if exists by default otherwise nuxt default * The path to a templated HTML file for rendering Nuxt responses.
* Uses `<srcDir>/app.html` if it exists or the Nuxt default template if not.
*
* @example
* ```html
* <!DOCTYPE html>
* <html {{ HTML_ATTRS }}>
* <head {{ HEAD_ATTRS }}>
* {{ HEAD }}
* </head>
* <body {{ BODY_ATTRS }}>
* {{ APP }}
* </body>
* </html>
* ```
*/ */
appTemplatePath: { appTemplatePath: {
$resolve: (val, get) => { $resolve: (val, get) => {
@ -41,6 +62,10 @@ export default {
} }
}, },
/**
* Enable or disable vuex store.
* By default is enbled if there is store / directory
*/
store: { store: {
$resolve: (val, get) => val !== false && $resolve: (val, get) => val !== false &&
existsSync(join(get('srcDir'), get('dir.store'))) && existsSync(join(get('srcDir'), get('dir.store'))) &&
@ -49,47 +74,145 @@ export default {
}, },
/** /**
* debug errorss * Options to pass directly to `vue-meta`.
*
* @see [documentation](https://vue-meta.nuxtjs.org/api/#plugin-options).
*/ */
debug: {
$resolve: (val, get) => val ?? get('dev')
},
vueMeta: null, vueMeta: null,
/**
* Set default configuration for `<head>` on every page.
*
* @see [documentation](https://vue-meta.nuxtjs.org/api/#metainfo-properties) for specifics.
*/
head: { head: {
/** Each item in the array maps to a newly-created <meta> element, where object properties map to attributes. */
meta: [], meta: [],
/** Each item in the array maps to a newly-created <link> element, where object properties map to attributes. */
link: [], link: [],
/** Each item in the array maps to a newly-created <style> element, where object properties map to attributes. */
style: [], style: [],
/** Each item in the array maps to a newly-created <script> element, where object properties map to attributes. */
script: [] script: []
}, },
/**
* Configuration for the Nuxt `fetch()` hook.
*/
fetch: { fetch: {
/** Whether to enable `fetch()` on the server. */
server: true, server: true,
/** Whether to enable `fetch()` on the client. */
client: true client: true
}, },
/**
* An array of nuxt app plugins.
*
* Each plugin can be a string (which can be an absolute or relative path to a file).
* If it ends with `.client` or `.server` then it will be automatically loaded only
* in the appropriate context.
*
* It can also be an object with `src` and `mode` keys.
*
* @example
* ```js
* plugins: [
* '~/plugins/foo.client.js', // only in client side
* '~/plugins/bar.server.js', // only in server side
* '~/plugins/baz.js', // both client & server
* { src: '~/plugins/both-sides.js' },
* { src: '~/plugins/client-only.js', mode: 'client' }, // only on client side
* { src: '~/plugins/server-only.js', mode: 'server' } // only on server side
* ]
* ```
*/
plugins: [], plugins: [],
/**
* You may want to extend plugins or change their order. For this, you can pass
* a function using `extendPlugins`. It accepts an array of plugin objects and
* should return an array of plugin objects.
*/
extendPlugins: null, extendPlugins: null,
/**
* You can define the CSS files/modules/libraries you want to set globally
* (included in every page).
*
* Nuxt will automatically guess the file type by its extension and use the
* appropriate pre-processor. You will still need to install the required
* loader if you need to use them.
*
* @example
* ```js
* css: [
* // Load a Node.js module directly (here it's a Sass file)
* 'bulma',
* // CSS file in the project
* '@/assets/css/main.css',
* // SCSS file in the project
* '@/assets/css/main.scss'
* ]
* ```
*/
css: [], css: [],
/**
* An object where each key name maps to a path to a layout .vue file.
*
* Normally there is no need to configure this directly.
*/
layouts: {}, layouts: {},
/**
* Set a custom error page layout.
*
* Normally there is no need to configure this directly.
*/
ErrorPage: null, ErrorPage: null,
/**
* Configure the Nuxt loading progress bar component that's shown between
* routes. Set to `false` to disable. You can also customize it or create
* your own component.
*/
loading: { loading: {
/** CSS color of the progress bar */
color: 'black', color: 'black',
/**
* CSS color of the progress bar when an error appended while rendering
* the route (if data or fetch sent back an error for example).
*/
failedColor: 'red', failedColor: 'red',
/** Height of the progress bar (used in the style property of the progress bar). */
height: '2px', height: '2px',
/**
* In ms, wait for the specified time before displaying the progress bar.
* Useful for preventing the bar from flashing.
*/
throttle: 200, throttle: 200,
/**
* In ms, the maximum duration of the progress bar, Nuxt assumes that the
* route will be rendered before 5 seconds.
*/
duration: 5000, duration: 5000,
/** Keep animating progress bar when loading takes longer than duration. */
continuous: false, continuous: false,
/** Set the direction of the progress bar from right to left. */
rtl: false, rtl: false,
/** Set to false to remove default progress bar styles (and add your own). */
css: true css: true
}, },
/**
* Show a loading spinner while the page is loading (only when `ssr: false`).
*
* Set to `false` to disable. Alternatively, you can pass a string name or an object for more
* configuration. The name can refer to an indicator from [SpinKit](https://tobiasahlin.com/spinkit/)
* or a path to an HTML template of the indicator source code (in this case, all the
* other options will be passed to the template.)
*/
loadingIndicator: { loadingIndicator: {
$resolve: (val, get) => { $resolve: (val, get) => {
if (typeof val === 'string') { if (typeof val === 'string') {
@ -107,6 +230,15 @@ export default {
} }
}, },
/**
* Used to set the default properties of the page transitions.
*
* You can either pass a string (the transition name) or an object with properties to bind
* to the `<Transition>` component that will wrap your pages.
*
* @see [vue@2 documentation](https://vuejs.org/v2/guide/transitions.html)
* @see [vue@3 documentation](https://v3.vuejs.org/guide/transitions-enterleave.html)
*/
pageTransition: { pageTransition: {
$resolve: val => typeof val === 'string' ? { name: val } : val, $resolve: val => typeof val === 'string' ? { name: val } : val,
name: 'page', name: 'page',
@ -117,25 +249,50 @@ export default {
appearToClass: 'appear-to' appearToClass: 'appear-to'
}, },
/**
* Used to set the default properties of the layout transitions.
*
* You can either pass a string (the transition name) or an object with properties to bind
* to the `<Transition>` component that will wrap your layouts.
*
* @see [vue@2 documentation](https://vuejs.org/v2/guide/transitions.html)
* @see [vue@3 documentation](https://v3.vuejs.org/guide/transitions-enterleave.html)
*/
layoutTransition: { layoutTransition: {
$resolve: val => typeof val === 'string' ? { name: val } : val, $resolve: val => typeof val === 'string' ? { name: val } : val,
name: 'layout', name: 'layout',
mode: 'out-in' mode: 'out-in'
}, },
/**
* You can disable specific Nuxt features that you do not want.
*/
features: { features: {
/** Set to false to disable Nuxt vuex integration */
store: true, store: true,
/** Set to false to disable layouts */
layouts: true, layouts: true,
/** Set to false to disable Nuxt integration with `vue-meta` and the `head` property */
meta: true, meta: true,
/** Set to false to disable middleware */
middleware: true, middleware: true,
/** Set to false to disable transitions */
transitions: true, transitions: true,
/** Set to false to disable support for deprecated features and aliases */
deprecations: true, deprecations: true,
/** Set to false to disable the Nuxt `validate()` hook */
validate: true, validate: true,
/** Set to false to disable the Nuxt `asyncData()` hook */
asyncData: true, asyncData: true,
/** Set to false to disable the Nuxt `fetch()` hook */
fetch: true, fetch: true,
/** Set to false to disable `$nuxt.isOnline` */
clientOnline: true, clientOnline: true,
/** Set to false to disable prefetching behavior in `<NuxtLink>` */
clientPrefetch: true, clientPrefetch: true,
/** Set to false to disable extra component aliases like `<NLink>` and `<NChild>` */
componentAliases: true, componentAliases: true,
/** Set to false to disable the `<ClientOnly>` component (see [docs](https://github.com/egoist/vue-client-only)) */
componentClientOnly: true componentClientOnly: true
} }
} }

View File

@ -5,21 +5,101 @@ import { pascalCase } from 'scule'
import jiti from 'jiti' import jiti from 'jiti'
export default { export default {
/**
* Define the workspace directory of your application.
*
* This property can be overwritten (for example, running `nuxt ./my-app/`
* will set the `rootDir` to the absolute path of `./my-app/` from the
* current/working directory.
*
* It is normally not needed to configure this option.
*/
rootDir: { rootDir: {
$resolve: val => typeof val === 'string' ? resolve(val) : process.cwd() $resolve: val => typeof val === 'string' ? resolve(val) : process.cwd()
}, },
/**
* Define the source directory of your Nuxt application.
*
* If a relative path is specified it will be relative to the `rootDir`.
*
* @example
* ```js
* export default {
* srcDir: 'client/'
* }
* ```
* This would work with the following folder structure:
* ```bash
* -| app/
* ---| node_modules/
* ---| nuxt.config.js
* ---| package.json
* ---| client/
* ------| assets/
* ------| components/
* ------| layouts/
* ------| middleware/
* ------| pages/
* ------| plugins/
* ------| static/
* ------| store/
* ```
*/
srcDir: { srcDir: {
$resolve: (val, get) => resolve(get('rootDir'), val || '.') $resolve: (val, get) => resolve(get('rootDir'), val || '.')
}, },
/**
* Define the directory where your built Nuxt files will be placed.
*
* Many tools assume that `.nuxt` is a hidden directory (because it starts
* with a `.`). If that is a problem, you can use this option to prevent that.
*
* @example
* ```js
* export default {
* buildDir: 'nuxt-build'
* }
* ```
*/
buildDir: { buildDir: {
$resolve: (val, get) => resolve(get('rootDir'), val || '.nuxt') $resolve: (val, get) => resolve(get('rootDir'), val || '.nuxt')
}, },
/**
* Whether Nuxt is running in development mode.
*
* Normally you should not need to set this.
*/
dev: Boolean(env.dev), dev: Boolean(env.dev),
/**
* Whether your app is being unit tested
*/
test: Boolean(env.test), test: Boolean(env.test),
debug: undefined,
/**
* Set to true to enable debug mode.
* By default it's only enabled in development mode.
*/
debug: {
$resolve: (val, get) => val ?? get('dev')
},
/**
* The env property defines environment variables that should be available
* throughout your app (server- and client-side). They can be assigned using
* server side environment variables.
*
* **Note**: Nuxt uses webpack's `definePlugin` to define these environment variables.
* This means that the actual `process` or `process.env` from Node.js is neither
* available nor defined. Each of the `env` properties defined here is individually
* mapped to `process.env.xxxx` and converted during compilation.
*
* **Note**: Environment variables starting with `NUXT_ENV_` are automatically injected
* into the process environment.
*/
env: { env: {
$resolve: (val) => { $resolve: (val) => {
val = { ...val } val = { ...val }
@ -32,6 +112,12 @@ export default {
} }
}, },
/**
* Set the method Nuxt uses to require modules, such as loading `nuxt.config`, server
* middleware, and so on - defaulting to `jiti` (which has support for TypeScript and ESM syntax).
*
* @see [jiti](https://github.com/unjs/jiti)
*/
createRequire: { createRequire: {
$resolve: (val: any) => { $resolve: (val: any) => {
val = process.env.NUXT_CREATE_REQUIRE || val || val = process.env.NUXT_CREATE_REQUIRE || val ||
@ -46,27 +132,130 @@ export default {
} }
}, },
/**
* Whether your Nuxt app should be built to be served by the Nuxt server (`server`)
* or as static HTML files suitable for a CDN or other static file server (`static`).
*
* This is unrelated to `ssr`.
*/
target: { target: {
$resolve: val => ['server', 'static'].includes(val) ? val : 'server' $resolve: val => ['server', 'static'].includes(val) ? val : 'server'
}, },
/**
* Whether to enable rendering of HTML - either dynamically (in server mode) or at generate time.
* If set to `false` and combined with `static` target, generated pages will simply display
* a loading screen with no content.
*/
ssr: true, ssr: true,
/**
* @deprecated use ssr option
*/
mode: { mode: {
$resolve: (val, get) => val || (get('ssr') ? 'spa' : 'universal'), $resolve: (val, get) => val || (get('ssr') ? 'spa' : 'universal'),
$schema: { deprecated: '`mode` option is deprecated' } $schema: { deprecated: '`mode` option is deprecated' }
}, },
/**
* Whether to produce a separate modern build targeting browsers that support ES modules.
*
* Set to `'server'` to enable server mode, where the Nuxt server checks
* browser version based on the user agent and serves the correct bundle.
*
* Set to `'client'` to serve both the modern bundle with `<script type="module">`
* and the legacy bundle with `<script nomodule>`. It will also provide a
* `<link rel="modulepreload">` for the modern bundle. Every browser that understands
* the module type will load the modern bundle while older browsers fall back to the
* legacy (transpiled) bundle.
*
* If you have set `modern: true` and are generating your app or have `ssr: false`,
* modern will be set to `'client'`.
*
* If you have set `modern: true` and are serving your app, modern will be set to `'server'`.
*
* @see [concept of modern mode](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/)
*/
modern: undefined, modern: undefined,
/**
* Modules are Nuxt extensions which can extend its core functionality and add endless integrations
*
* Each module is either a string (which can refer to a package, or be a path to a file), a
* tuple with the module as first string and the options as a second object, or an inline module function.
*
* Nuxt tries to resolve each item in the modules array using node require path
* (in `node_modules`) and then will be resolved from project `srcDir` if `~` alias is used.
*
* **Note**: Modules are executed sequentially so the order is important.
*
* @example
* ```js
* modules: [
* // Using package name
* '@nuxtjs/axios',
* // Relative to your project srcDir
* '~/modules/awesome.js',
* // Providing options
* ['@nuxtjs/google-analytics', { ua: 'X1234567' }],
* // Inline definition
* function () {}
* ]
* ```
*/
modules: [], modules: [],
/**
* Modules that are only required during development and build time.
*
* Modules are Nuxt extensions which can extend its core functionality and add endless integrations
*
* Each module is either a string (which can refer to a package, or be a path to a file), a
* tuple with the module as first string and the options as a second object, or an inline module function.
*
* Nuxt tries to resolve each item in the modules array using node require path
* (in `node_modules`) and then will be resolved from project `srcDir` if `~` alias is used.
*
* **Note**: Modules are executed sequentially so the order is important.
*
* @example
* ```js
* modules: [
* // Using package name
* '@nuxtjs/axios',
* // Relative to your project srcDir
* '~/modules/awesome.js',
* // Providing options
* ['@nuxtjs/google-analytics', { ua: 'X1234567' }],
* // Inline definition
* function () {}
* ]
* ```
*
* **Note**: Using `buildModules` helps to make production startup faster and also significantly
* decreases the size of `node_modules` in production deployments. Please refer to each
* module's documentation to see if it is recommended to use `modules` or `buildModules`.
*/
buildModules: [], buildModules: [],
/**
* Built-in ah-hoc modules
*
* @private
*/
_modules: [], _modules: [],
/**
* Allows customizing the global ID used in the main HTML template as well as the main
* Vue instance name and other options.
*/
globalName: { globalName: {
$resolve: val => (typeof val === 'string' && /^[a-zA-Z]+$/.test(val)) ? val.toLocaleLowerCase() : 'nuxt' $resolve: val => (typeof val === 'string' && /^[a-zA-Z]+$/.test(val)) ? val.toLocaleLowerCase() : 'nuxt'
}, },
/**
* Customizes specific global names (they are based on `globalName` by default).
*/
globals: { globals: {
id: globalName => `__${globalName}`, id: globalName => `__${globalName}`,
nuxt: globalName => `$${globalName}`, nuxt: globalName => `$${globalName}`,
@ -76,6 +265,70 @@ export default {
loadedCallback: globalName => `_on${pascalCase(globalName)}Loaded` loadedCallback: globalName => `_on${pascalCase(globalName)}Loaded`
}, },
/**
* Server middleware are connect/express/h3-shaped functions that handle server-side requests. They
* run on the server and before the Vue renderer.
*
* By adding entries to `serverMiddleware` you can register additional routes or modify `req`/`res`
* objects without the need for an external server.
*
* You can pass a string, which can be the name of a node dependency or a path to a file. You
* can also pass an object with `path` and `handler` keys. (`handler` can be a path or a
* function.)
*
* @example
* ```js
* serverMiddleware: [
* // Will register redirect-ssl npm package
* 'redirect-ssl',
* // Will register file from project server-middleware directory to handle /server-middleware/* requires
* { path: '/server-middleware', handler: '~/server-middleware/index.js' },
* // We can create custom instances too
* { path: '/static2', handler: serveStatic(__dirname + '/static2') }
* ]
* ```
*
* **Note**: If you don't want middleware to run on all routes you should use the object
* form with a specific path.
*
* If you pass a string handler, Nuxt will expect that file to export a default function
* that handles `(req, res, next) => void`.
*
* @example
* ```js
* export default function (req, res, next) {
* // req is the Node.js http request object
* console.log(req.url)
* // res is the Node.js http response object
* // next is a function to call to invoke the next middleware
* // Don't forget to call next at the end if your middleware is not an endpoint!
* next()
* }
* ```
*
* Alternatively, it can export a connect/express/h3-type app instance.
* @example
* ```js
* const bodyParser = require('body-parser')
* const app = require('express')()
* app.use(bodyParser.json())
* app.all('/getJSON', (req, res) => {
* res.json({ data: 'data' })
* })
* module.exports = app
* ```
*
* Alternatively, instead of passing an array of `serverMiddleware`, you can pass an object
* whose keys are the paths and whose values are the handlers (string or function).
* @example
* ```js
* serverMiddleware: {
* '/a': '~/server-middleware/a.js',
* '/b': '~/server-middleware/b.js',
* '/c': '~/server-middleware/c.js'
* }
* ```
*/
serverMiddleware: { serverMiddleware: {
$resolve: (val: any) => { $resolve: (val: any) => {
if (!val) { if (!val) {
@ -88,6 +341,21 @@ export default {
} }
}, },
/**
* Used to set the modules directories for path resolving (for example, webpack's
* `resolveLoading`, `nodeExternals` and `postcss`).
*
* The configuration path is relative to `options.rootDir` (default is current working directory).
*
* Setting this field may be necessary if your project is organized as a yarn workspace-styled mono-repository.
*
* @example
* ```js
* export default {
* modulesDir: ['../../node_modules']
* }
* ```
*/
modulesDir: { modulesDir: {
$default: ['node_modules'], $default: ['node_modules'],
$resolve: (val, get) => [].concat( $resolve: (val, get) => [].concat(
@ -96,22 +364,84 @@ export default {
) )
}, },
/**
* Customize default directory structure used by nuxt.
* It is better to stick with defaults unless needed.
*/
dir: { dir: {
/** The assets directory (aliased as `~assets` in your build) */
assets: 'assets', assets: 'assets',
/** The directory containing app template files like `app.html` and `router.scrollBehavior.js` */
app: 'app', app: 'app',
/** The layouts directory, each file of which will be auto-registered as a Nuxt layout. */
layouts: 'layouts', layouts: 'layouts',
/** The middleware directory, each file of which will be auto-registered as a Nuxt middleware. */
middleware: 'middleware', middleware: 'middleware',
/** The directory which will be processed to auto-generate your application page routes. */
pages: 'pages', pages: 'pages',
/**
* Your static directory, which will be directly accessible via the Nuxt server and copied
* across into your `dist` folder when your app is generated.
*/
static: 'static', static: 'static',
/** The folder which will be used to auto-generate your Vuex store structure. */
store: 'store' store: 'store'
}, },
/**
* The extensions that should be resolved by the Nuxt resolver.
*/
extensions: { extensions: {
$resolve: val => ['.js', '.mjs', '.ts', '.tsx', '.vue'].concat(val).filter(Boolean) $resolve: val => ['.js', '.mjs', '.ts', '.tsx', '.vue'].concat(val).filter(Boolean)
}, },
/**
* The style extensions that should be resolved by the Nuxt resolver (for example, in `css` property).
*/
styleExtensions: ['.css', '.pcss', '.postcss', '.styl', '.stylus', '.scss', '.sass', '.less'], styleExtensions: ['.css', '.pcss', '.postcss', '.styl', '.stylus', '.scss', '.sass', '.less'],
/**
* You can improve your DX by defining additional aliases to access custom directories
* within your JavaScript and CSS.
*
* **Note**: Within a webpack context (image sources, CSS - but not JavaScript) you _must_ access
* your alias by prefixing it with `~`.
*
* **Note**: If you are using TypeScript and want to use the alias you define within
* your TypeScript files, you will need to add the aliases to your `paths` object within `tsconfig.json` .
*
* @example
* ```js
* import { resolve } from 'path'
* export default {
* alias: {
* 'images': resolve(__dirname, './assets/images'),
* 'style': resolve(__dirname, './assets/style'),
* 'data': resolve(__dirname, './assets/other/data')
* }
* }
* ```
*
* ```html
* <template>
* <img src="~images/main-bg.jpg">
* </template>
*
* <script>
* import data from 'data/test.json'
* </script>
*
* <style>
* // Uncomment the below
* //@import '~style/variables.scss';
* //@import '~style/utils.scss';
* //@import '~style/base.scss';
* body {
* background-image: url('~images/main-bg.jpg');
* }
* </style>
* ```
*/
alias: { alias: {
$resolve: (val, get) => ({ $resolve: (val, get) => ({
'~~': get('rootDir'), '~~': get('rootDir'),
@ -124,8 +454,30 @@ export default {
}) })
}, },
/**
* Pass options directly to `node-ignore` (which is used by Nuxt to ignore files).
*
* @see [node-ignore](https://github.com/kaelzhang/node-ignore)
*
* @example
* ```js
* ignoreOptions: {
* ignorecase: false
* }
* ```
*/
ignoreOptions: undefined, ignoreOptions: undefined,
/**
* Any file in `pages/`, `layouts/`, `middleware/` or `store/` will be ignored during
* building if its filename starts with the prefix specified by `ignorePrefix`.
*/
ignorePrefix: '-', ignorePrefix: '-',
/**
* More customizable than `ignorePrefix`: all files matching glob patterns specified
* inside the `ignore` array will be ignored in building.
*/
ignore: { ignore: {
$resolve: (val, get) => [ $resolve: (val, get) => [
'**/*.test.*', '**/*.test.*',
@ -134,28 +486,135 @@ export default {
].concat(val).filter(Boolean) ].concat(val).filter(Boolean)
}, },
/**
* The watch property lets you watch custom files for restarting the server.
*
* `chokidar` is used to set up the watchers. To learn more about its pattern
* options, see chokidar documentation.
*
* @see [chokidar](https://github.com/paulmillr/chokidar#api)
*
* @example
* ```js
* watch: ['~/custom/*.js']
* ```
*/
watch: { watch: {
$resolve: (val, get) => [].concat(val, get('_nuxtConfigFiles')).filter(Boolean) $resolve: (val, get) => [].concat(val, get('_nuxtConfigFiles')).filter(Boolean)
}, },
/**
* The watchers property lets you overwrite watchers configuration in your `nuxt.config`.
*/
watchers: { watchers: {
/** An array of event types, which, when received, will cause the watcher to restart. */
rewatchOnRawEvents: undefined, rewatchOnRawEvents: undefined,
/**
* `watchOptions` to pass directly to webpack.
*
* @see [webpack@4 watch options](https://v4.webpack.js.org/configuration/watch/#watchoptions).
* */
webpack: { webpack: {
aggregateTimeout: 1000 aggregateTimeout: 1000
}, },
/**
* Options to pass directly to `chokidar`.
*
* @see [chokidar](https://github.com/paulmillr/chokidar#api)
*/
chokidar: { chokidar: {
ignoreInitial: true ignoreInitial: true
} }
}, },
/**
* Your preferred code editor to launch when debugging.
*
* @see [documentation](https://github.com/yyx990803/launch-editor#supported-editors)
*/
editor: undefined, editor: undefined,
/**
* Hooks are listeners to Nuxt events that are typically used in modules, but are also available in `nuxt.config`.
*
* Internally, hooks follow a naming pattern using colons (e.g., build:done).
*
* For ease of configuration, you can also structure them as an hierarchical object in `nuxt.config` (as below).
*
* @example
* ```js
* import fs from 'fs'
* import path from 'path'
* export default {
* hooks: {
* build: {
* done(builder) {
* const extraFilePath = path.join(
* builder.nuxt.options.buildDir,
* 'extra-file'
* )
* fs.writeFileSync(extraFilePath, 'Something extra')
* }
* }
* }
* }
* ```
*/
hooks: null, hooks: null,
/**
* Runtime config allows passing dynamic config and environment variables to the Nuxt app context.
*
* It is added to the Nuxt payload so there is no need to rebuild to update your configuration in
* development or if your application is served by the Nuxt server. (For static sites you will still
* need to regenerate your site to see changes.)
*
* The value of this object is accessible from server only using `$config`.
*
* It will override `publicRuntimeConfig` on the server-side.
*
* It should hold _private_ environment variables (that should not be exposed on the frontend).
* This could include a reference to your API secret tokens.
*
* @example
* ```js
* export default {
* privateRuntimeConfig: {
* apiSecret: process.env.API_SECRET
* }
* }
* ```
*/
privateRuntimeConfig: {}, privateRuntimeConfig: {},
/**
* Runtime config allows passing dynamic config and environment variables to the Nuxt app context.
*
* It is added to the Nuxt payload so there is no need to rebuild to update your configuration in
* development or if your application is served by the Nuxt server. (For static sites you will still
* need to regenerate your site to see changes.)
*
* The value of this object is accessible from both client and server using `$config`. It should hold env
* variables that are _public_ as they will be accessible on the frontend. This could include a
* reference to your public URL.
*
* @example
* ```js
* export default {
* publicRuntimeConfig: {
* baseURL: process.env.BASE_URL || 'https://nuxtjs.org'
* }
* }
* ```
*/
publicRuntimeConfig: { publicRuntimeConfig: {
app: { app: {
$resolve: (val, get) => ({ ...get('app'), ...(val || {}) }) $resolve: (val, get) => ({ ...get('app'), ...(val || {}) })
} }
} },
/**
* Enable vite mode.
*/
vite: false
} }

View File

@ -1,13 +1,22 @@
export default { export default {
/** @private */
_majorVersion: 2, _majorVersion: 2,
/** @private */
_legacyGenerate: false, _legacyGenerate: false,
/** @private */
_start: false, _start: false,
/** @private */
_build: false, _build: false,
/** @private */
_generate: false, _generate: false,
/** @private */
_cli: false, _cli: false,
/** @private */
_requiredModules: {}, _requiredModules: {},
/** @private */
_nuxtConfigFile: undefined, _nuxtConfigFile: undefined,
/** @private */
_nuxtConfigFiles: [], _nuxtConfigFiles: [],
appDir: '', /** @private */
vite: false appDir: ''
} }

View File

@ -2,26 +2,171 @@ import env from 'std-env'
import { hasProtocol } from 'ufo' import { hasProtocol } from 'ufo'
export default { export default {
/**
* Suppresses most of the build output log.
*
* It is enabled by default when a CI or test environment is detected.
*
* @see [std-env](https://github.com/unjs/std-env)
*/
quiet: Boolean(env.ci || env.test), quiet: Boolean(env.ci || env.test),
/**
* Nuxt uses `webpack-bundle-analyzer` to visualize your bundles and how to optimize them.
*
* This option is normally enabled by the CLI argument `--analyze`.
*
* Set to `true` to enable bundle analysis, or pass [an object with options](https://github.com/webpack-contrib/webpack-bundle-analyzer#options-for-plugin).
*
* @example
* ```js
* analyze: {
* analyzerMode: 'static'
* }
* ```
*/
analyze: false, analyze: false,
/**
* Enable the profiler in webpackbar.
*
* It is normally enabled by CLI argument `--profile`.
*
* @see [webpackbar](https://github.com/unjs/webpackbar#profile)
*/
profile: process.argv.includes('--profile'), profile: process.argv.includes('--profile'),
/**
* Enables Common CSS Extraction using
* [Vue Server Renderer guidelines](https://ssr.vuejs.org/guide/css.html).
*
* Using [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/) under the hood, your CSS will be extracted
* into separate files, usually one per component. This allows caching your CSS and
* JavaScript separately and is worth trying if you have a lot of global or shared CSS.
*
* @example
* ```js
* extractCSS: true,
* // or
* extractCSS: {
* ignoreOrder: true
* }
* ```
*
* If you want to extract all your CSS to a single file, there is a workaround for this.
* However, note that it is not recommended to extract everything into a single file.
* Extracting into multiple CSS files is better for caching and preload isolation. It
* can also improve page performance by downloading and resolving only those resources
* that are needed.
*
* @example
* ```js
* extractCSS: true,
* optimization: {
* splitChunks: {
* cacheGroups: {
* styles: {
* name: 'styles',
* test: /\.(css|vue)$/,
* chunks: 'all',
* enforce: true
* }
* }
* }
* }
* ```
*/
extractCSS: false, extractCSS: false,
/**
* Enables CSS source map support (defaults to true in development)
*/
cssSourceMap: { cssSourceMap: {
$resolve: (val, get) => val ?? get('dev') $resolve: (val, get) => val ?? get('dev')
}, },
/**
* Creates special webpack bundle for SSR renderer. It is normally not necessary to change this value.
*/
ssr: undefined, ssr: undefined,
/**
* Enable [thread-loader](https://github.com/webpack-contrib/thread-loader#thread-loader) when building app with webpack.
*
* @warning This is an unstable feature.
*/
parallel: { parallel: {
$resolve: (val, get) => get('build.extractCSS') ? false : Boolean(val) $resolve: (val, get) => get('build.extractCSS') ? false : Boolean(val)
}, },
/**
* Enable caching for [`terser-webpack-plugin`](https://github.com/webpack-contrib/terser-webpack-plugin#options)
* and [`cache-loader`](https://github.com/webpack-contrib/cache-loader#cache-loader)
*
* @warning This is an unstable feature.
*/
cache: false, cache: false,
/**
* Inline server bundle dependencies
*
* This mode bundles `node_modules` that are normally preserved as externals in the server build.
*
* @warning Runtime dependencies (modules, `nuxt.config`, server middleware and the static directory) are not bundled.
* This feature only disables use of [webpack-externals](https://webpack.js.org/configuration/externals/) for server-bundle.
*
* @note You can enable standalone bundling by passing `--standalone` via the command line.
*
* @see [context](https://github.com/nuxt/nuxt.js/pull/4661)
*/
standalone: false, standalone: false,
/**
* If you are uploading your dist files to a CDN, you can set the publicPath to your CDN.
*
* @note This is only applied in production.
*
* The value of this property at runtime will override the configuration of an app that
* has already been built.
*
* @example
* ```js
* build: {
* publicPath: process.env.PUBLIC_PATH || 'https://cdn.nuxtjs.org'
* }
* ```
* */
publicPath: { publicPath: {
$resolve: (val, get) => { $resolve: (val, get) => {
if (hasProtocol(val, true) && get('dev')) { val = null } if (hasProtocol(val, true) && get('dev')) { val = null }
return (val || '/_nuxt/').replace(/([^/])$/, '$1/') return (val || '/_nuxt/').replace(/([^/])$/, '$1/')
} }
}, },
/**
* The polyfill library to load to provide URL and URLSearchParams.
*
* Defaults to `'url'` ([see package](https://www.npmjs.com/package/url)).
*/
serverURLPolyfill: 'url', serverURLPolyfill: 'url',
/**
* Customize bundle filenames.
*
* To understand a bit more about the use of manifests, take a look at [this webpack documentation](https://webpack.js.org/guides/code-splitting/).
*
* @note Be careful when using non-hashed based filenames in production
* as most browsers will cache the asset and not detect the changes on first load.
*
* This example changes fancy chunk names to numerical ids:
*
* @example
* ```js
* filenames: {
* chunk: ({ isDev }) => (isDev ? '[name].js' : '[id].[contenthash].js')
* }
* ```
*/
filenames: { filenames: {
app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
@ -30,6 +175,10 @@ export default {
font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]' video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
}, },
/**
* Customize the options of Nuxt's integrated webpack loaders.
*/
loaders: { loaders: {
$resolve: (val, get) => { $resolve: (val, get) => {
const styleLoaders = [ const styleLoaders = [
@ -78,17 +227,72 @@ export default {
stylus: {}, stylus: {},
vueStyle: {} vueStyle: {}
}, },
/**
* @deprecated Use [style-resources-module](https://github.com/nuxt-community/style-resources-module/)
*/
styleResources: {}, styleResources: {},
/**
* Add webpack plugins.
*
* @example
* ```js
* import webpack from 'webpack'
* import { version } from './package.json'
* // ...
* plugins: [
* new webpack.DefinePlugin({
* 'process.VERSION': version
* })
* ]
* ```
*/
plugins: [], plugins: [],
/**
* Terser plugin options.
*
* Set to false to disable this plugin, or pass an object of options.
*
* @see [terser-webpack-plugin documentation](https://github.com/webpack-contrib/terser-webpack-plugin)
*
* @note Enabling sourceMap will leave `//# sourceMappingURL` linking comment at
* the end of each output file if webpack `config.devtool` is set to `source-map`.
*/
terser: {}, terser: {},
/**
* Enables the [HardSourceWebpackPlugin](https://github.com/mzgoddard/hard-source-webpack-plugin) for improved caching.
*
* @warning unstable
*/
hardSource: false, hardSource: false,
/**
* Hard-replaces `typeof process`, `typeof window` and `typeof document` to tree-shake bundle.
*/
aggressiveCodeRemoval: false, aggressiveCodeRemoval: false,
/**
* OptimizeCSSAssets plugin options.
*
* Defaults to true when `extractCSS` is enabled.
*
* @see [optimize-css-assets-webpack-plugin documentation](https://github.com/NMFR/optimize-css-assets-webpack-plugin).
*/
optimizeCSS: { optimizeCSS: {
$resolve: (val, get) => val ?? (get('build.extractCSS') ? {} : false) $resolve: (val, get) => val ?? (get('build.extractCSS') ? {} : false)
}, },
/**
* Configure [webpack optimization](https://webpack.js.org/configuration/optimization/).
*/
optimization: { optimization: {
runtimeChunk: 'single', runtimeChunk: 'single',
/** Set minimize to false to disable all minimizers. (It is disabled in development by default) */
minimize: { $resolve: (val, get) => val ?? get('dev') }, minimize: { $resolve: (val, get) => val ?? get('dev') },
/** You can set minimizer to a customized array of plugins. */
minimizer: undefined, minimizer: undefined,
splitChunks: { splitChunks: {
chunks: 'all', chunks: 'all',
@ -96,30 +300,126 @@ export default {
cacheGroups: {} cacheGroups: {}
} }
}, },
/**
* Whether to split code for `layout`, `pages` and `commons` chunks.
*
* Commons libs include `vue`, `vue-loader`, `vue-router`, `vuex`, etc.
*/
splitChunks: { splitChunks: {
layouts: false, layouts: false,
pages: true, pages: true,
commons: true commons: true
}, },
/**
* Nuxt will automatically detect the current version of `core-js` in your project (`'auto'`),
* or you can specify which version you want to use (`2` or `3`).
*/
corejs: 'auto', corejs: 'auto',
/**
* Customize your Babel configuration.
*
* See [babel-loader options](https://github.com/babel/babel-loader#options) and
* [babel options](https://babeljs.io/docs/en/options).
*
* @note `.babelrc` is ignored by default.
*/
babel: { babel: {
configFile: false, configFile: false,
babelrc: false, babelrc: false,
/**
* The Babel presets to be applied.
*
* **Note**: The presets configured here will be applied to both the client and the server
* build. The target will be set by Nuxt accordingly (client/server). If you want to configure
* the preset differently for the client or the server build, please use presets as a function.
*
* **Warning**: It is highly recommended to use the default preset instead customizing.
*
* @example
* ```js
* presets({ isServer }, [ preset, options ]) {
* // change options directly
* options.targets = isServer ? ... : ...
* options.corejs = ...
* // return nothing
* }
* ```
*
* @example
* ```js
* presets({ isServer }, [preset, options]) {
* return [
* [
* preset,
* {
* targets: isServer ? ... : ...,
* ...options
* }
* ],
* [
* // Other presets
* ]
* ]
* }
* ```
*/
presets: {}, presets: {},
cacheDirectory: { cacheDirectory: {
$resolve: (val, get) => val ?? get('dev') $resolve: (val, get) => val ?? get('dev')
} }
}, },
/**
* If you want to transpile specific dependencies with Babel, you can add them here.
* Each item in transpile can be a package name, a function, a string or regex object matching the
* dependency's file name.
*
* Tou can also use a function to conditionally transpile, the function will receive a object ({ isDev, isServer, isClient, isModern, isLegacy }).
*
* @example
* ```js
transpile: [({ isLegacy }) => isLegacy && 'ky']
* ```
*/
transpile: { transpile: {
$resolve: val => [].concat(val).filter(Boolean) $resolve: val => [].concat(val).filter(Boolean)
}, },
/**
* Customize PostCSS Loader plugins.
*/
postcss: { postcss: {
preset: { preset: {
// https://cssdb.org/#staging-process // https://cssdb.org/#staging-process
stage: 2 stage: 2
} }
}, },
html: { html: {
/**
* Configuration for the html-minifier plugin used to minify HTML files created
* during the build process (will be applied for all modes).
*
* **Attention**: If you make changes, they won't be merged with the defaults!
*
* @example
* ```js
* minify: {
* collapseBooleanAttributes: true,
* decodeEntities: true,
* minifyCSS: true,
* minifyJS: true,
* processConditionalComments: true,
* removeEmptyAttributes: true,
* removeRedundantAttributes: true,
* trimCustomFragments: true,
* useShortDoctype: true
* }
* ```
*/
minify: { minify: {
collapseBooleanAttributes: true, collapseBooleanAttributes: true,
decodeEntities: true, decodeEntities: true,
@ -133,13 +433,46 @@ export default {
} }
}, },
/** Allows setting a different app template (other than `@nuxt/vue-app`) */
template: undefined, template: undefined,
/**
* You can provide your own templates which will be rendered based
* on Nuxt configuration. This feature is specially useful for using with modules.
*
* Templates are rendered using [`lodash.template`](https://lodash.com/docs/4.17.15#template).
*
* @example
* ```js
* templates: [
* {
* src: '~/modules/support/plugin.js', // `src` can be absolute or relative
* dst: 'support.js', // `dst` is relative to project `.nuxt` dir
* options: {
* // Options are provided to template as `options` key
* live_chat: false
* }
* }
* ]
* ```
*/
templates: [], templates: [],
/**
* You can provide your custom files to watch and regenerate after changes.
*
* This feature is specially useful for using with modules.
*
* @example
* ```js
watch: ['~/.nuxt/support.js']
* ```
*/
watch: [], watch: [],
/** See [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) for available options. */
devMiddleware: { devMiddleware: {
stats: 'none' stats: 'none'
}, },
/** See [webpack-hot-middleware](https://github.com/webpack-contrib/webpack-hot-middleware) for available options. */
hotMiddleware: {}, hotMiddleware: {},
vendor: { vendor: {
@ -148,17 +481,22 @@ export default {
} }
}, },
/** Set to `'none'` or `false` to disable stats printing out after a build. */
stats: { stats: {
$resolve: (val, get) => (val === 'none' || get('build.quite')) ? false : val, $resolve: (val, get) => (val === 'none' || get('build.quiet')) ? false : val,
excludeAssets: [ excludeAssets: [
/.map$/, /.map$/,
/index\..+\.html$/, /index\..+\.html$/,
/vue-ssr-(client|modern)-manifest.json/ /vue-ssr-(client|modern)-manifest.json/
] ]
}, },
/** Set to `false` to disable the overlay provided by [FriendlyErrorsWebpackPlugin](https://github.com/nuxt/friendly-errors-webpack-plugin) */
friendlyErrors: true, friendlyErrors: true,
/** Additional extensions (beyond `['vue', 'js']` to support in `pages/`, `layouts/`, `middleware/`, etc.) */
additionalExtensions: [], additionalExtensions: [],
/** Filters to hide build warnings. */
warningIgnoreFilters: [], warningIgnoreFilters: [],
/** Set to true to scan files within symlinks in the build (such as within `pages/`). */
followSymlinks: false followSymlinks: false
} }

View File

@ -1,4 +1,11 @@
export default { export default {
/**
* Add a message to the CLI banner by adding a string to this array.
*/
badgeMessages: [], badgeMessages: [],
/**
* Change the color of the 'Nuxt.js' title in the CLI banner.
*/
bannerColor: 'green' bannerColor: 'green'
} }

View File

@ -2,28 +2,153 @@ import { resolve } from 'path'
import { joinURL } from 'ufo' import { joinURL } from 'ufo'
export default { export default {
/**
* Directory name that holds all the assets and generated pages for a `static` build.
*/
dir: { dir: {
$resolve: (val = 'dist', get) => resolve(get('rootDir'), val) $resolve: (val = 'dist', get) => resolve(get('rootDir'), val)
}, },
/**
* The routes to generate.
*
* If you are using the crawler, this will be only the starting point for route generation.
* This is often necessary when using dynamic routes.
*
* It can be an array or a function.
*
* @example
* ```js
* routes: ['/users/1', '/users/2', '/users/3']
* ```
*
* You can pass a function that returns a promise or a function that takes a callback. It should
* return an array of strings or objects with `route` and (optional) `payload` keys.
*
* @example
* ```js
* async routes() {
* const res = await axios.get('https://my-api/users')
* return res.data.map(user => ({ route: '/users/' + user.id, payload: user }))
* }
* // or
* routes(callback) {
* axios
* .get('https://my-api/users')
* .then(res => {
* const routes = res.data.map(user => '/users/' + user.id)
* callback(null, routes)
* })
* .catch(callback)
* }
* ```
*
* If `routes()` returns a payload, it can be accessed from the Nuxt context.
* @example
* ```js
* async asyncData ({ params, error, payload }) {
* if (payload) return { user: payload }
* else return { user: await backend.fetchUser(params.id) }
* }
* ```
*/
routes: [], routes: [],
/**
* An array of string or regular expressions that will prevent generation
* of routes matching them. The routes will still be accessible when `fallback` is set.
*/
exclude: [], exclude: [],
/** The number of routes that are generated concurrently in the same thread. */
concurrency: 500, concurrency: 500,
/**
* Interval in milliseconds between two render cycles to avoid flooding a potential
* API with calls.
*/
interval: 0, interval: 0,
/**
* Set to `false` to disable creating a directory + `index.html` for each route.
*
* @example
* ```bash
* # subFolders: true
* -| dist/
* ---| index.html
* ---| about/
* -----| index.html
* ---| products/
* -----| item/
* -------| index.html
*
* # subFolders: false
* -| dist/
* ---| index.html
* ---| about.html
* ---| products/
* -----| item.html
* ```
*/
subFolders: true, subFolders: true,
/**
* The path to the fallback HTML file.
*
* Set this as the error page in your static server configuration, so that unknown
* routes can be rendered (on the client-side) by Nuxt.
*
* * If unset or set to a falsy value, the name of the fallback HTML file will be `200.html`.
* * If set to true, the filename will be `404.html`.
* * If you provide a string as a value, it will be used instead.
*
* **Note**: Multiple services (e.g. Netlify) detect a `404.html` automatically. If
* you configure your web server on your own, please consult its documentation
* to find out how to set up an error page (and set it to the 404.html file)
*/
fallback: { $resolve: val => val === true ? '400.html' : (val || '200.html') }, fallback: { $resolve: val => val === true ? '400.html' : (val || '200.html') },
/**
* Set to `false` to disable generating pages discovered through crawling relative
* links in generated pages.
*/
crawler: true, crawler: true,
/** Set to `false` to disable generating a `manifest.js` with a list of all generated pages. */
manifest: true, manifest: true,
/** Set to `false` to disable generating a `.nojekyll` file (which aids compatibility with GitHub Pages). */
nojekyll: true, nojekyll: true,
/**
* Configure the cache (used with `static` target to avoid rebuilding when no files have changed).
*
* Set to `false` to disable completely.
*/
cache: { cache: {
/** An array of files or directories to ignore. (It can also be a function that returns an array.) */
ignore: [], ignore: [],
/**
* Options to pass to [`globby`](https://github.com/sindresorhus/globby), which
* is used to generate a 'snapshot' of the source files.
*/
globbyOptions: { globbyOptions: {
gitignore: true gitignore: true
} }
}, },
staticAssets: { staticAssets: {
/** The directory underneath `/_nuxt/`, where static assets (payload, state and manifest files) will live. */
dir: 'static', dir: 'static',
/**
* The full path to the directory underneath `/_nuxt/` where static assets
* (payload, state and manifest files) will live.
*/
base: { $resolve: (val, get) => val || joinURL(get('app.assetsPath'), get('generate.dir')) }, base: { $resolve: (val, get) => val || joinURL(get('app.assetsPath'), get('generate.dir')) },
/** The full path to the versioned directory where static assets for the current buidl are located. */
versionBase: { $resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version')) }, versionBase: { $resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version')) },
/** A unique string to uniquely identify payload versions (defaults to the current timestamp). */
version: { $resolve: val => val || (String(Math.round(Date.now() / 1000))) } version: { $resolve: val => val || (String(Math.round(Date.now() / 1000))) }
} }
} }

View File

@ -1,10 +1,18 @@
export default { export default {
/** The text that displays on the Nuxt loading indicator when `ssr: false`. */
loading: 'Loading...', loading: 'Loading...',
/** The 404 text on the default Nuxt error page. */
error_404: 'This page could not be found', error_404: 'This page could not be found',
/** The text to display on the default Nuxt error page when there has been a server error. */
server_error: 'Server error', server_error: 'Server error',
/** The text (linked to nuxtjs.org) that appears on the built-in Nuxt error page. */
nuxtjs: 'Nuxt', nuxtjs: 'Nuxt',
/** The text (linked to the home page) that appears on the built-in Nuxt error page. */
back_to_home: 'Back to the home page', back_to_home: 'Back to the home page',
/** The message that will display on a white screen if the built-in Nuxt error page can't be rendered. */
server_error_details: 'An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.', server_error_details: 'An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.',
/** The default error title (if there isn't a specific error message) on the built-in Nuxt error page. */
client_error: 'Error', client_error: 'Error',
/** The error message (in debug mode) on the built-in Nuxt error page. */
client_error_details: 'An error occurred while rendering the page. Check developer tools console for details.' client_error_details: 'An error occurred while rendering the page. Check developer tools console for details.'
} }

View File

@ -1,52 +1,269 @@
export default { export default {
/**
* Use this option to customize the Vue SSR bundle renderer.
* This option is skipped if `ssr: false`.
*
* Read [docs for Vue 2](https://ssr.vuejs.org/api/#renderer-options) here.
*/
bundleRenderer: { bundleRenderer: {
shouldPrefetch: () => false, shouldPrefetch: () => false,
shouldPreload: (_fileWithoutQuery, asType) => ['script', 'style'].includes(asType), shouldPreload: (_fileWithoutQuery, asType) => ['script', 'style'].includes(asType),
/** /** enabled by default for development */
* enabled by default for development
*/
runInNewContext: { $resolve: (val, get) => val ?? get('dev') } runInNewContext: { $resolve: (val, get) => val ?? get('dev') }
}, },
/**
* Configure the crossorigin attribute on `<link rel="stylesheet">` and `<script>`
* tags in generated HTML. [More information](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin).
*/
crossorigin: undefined, crossorigin: undefined,
/**
* Adds prefetch and preload links for faster initial page load time.
* You probably don't want to disable this option unless you have many pages and routes.
*/
resourceHints: true, resourceHints: true,
/**
* Whether to enable rendering of HTML - either dynamically (in server mode) or at generate time.
*
* This option is automatically set based on global ssr value if not provided.
* This can be useful to dynamically enable/disable SSR on runtime after image builds
* (with docker for example).
*/
ssr: undefined, ssr: undefined,
/**
* Forward server-side logs to the browser for better debugging (only available in development)
*
* Set to `collapsed` to collapse the logs, or false to disable.
*/
ssrLog: { $resolve: (val, get) => get('dev') ? Boolean(val) : false }, ssrLog: { $resolve: (val, get) => get('dev') ? Boolean(val) : false },
/**
* Configuration for HTTP2 push headers
*/
http2: { http2: {
/** Set to true to enable HTTP2 push headers */
push: false, push: false,
/** @deprecated */
shouldPush: null, shouldPush: null,
/**
* You can control what links to push using this function. It receives `req`,
* `res`, `publicPath` and a `preloadFiles` array.
*
* You can add your own assets to the array as well. Using `req` and `res`
* you can decide what links to push based on the request headers, for example
* using the cookie with application version.
*
* Assets will be joined together with `,` and passed as a single `Link` header.
*
* @example
* ```js
* pushAssets: (req, res, publicPath, preloadFiles) =>
* preloadFiles
* .filter(f => f.asType === 'script' && f.file === 'runtime.js')
* .map(f => `<${publicPath}${f.file}>; rel=preload; as=${f.asType}`)
* ```
*/
pushAssets: null pushAssets: null
}, },
/**
* Configure the behavior of the `static/` directory.
*
* See [serve-static docs](https://github.com/expressjs/serve-static) for possible options.
*/
static: { static: {
/**
* Whether to add the router base to your static assets.
*
* **Note**: some URL rewrites might not respect the prefix.
*
* @example
* Assets: favicon.ico
* Router base: /t
* With `prefix: true` (default): /t/favicon.ico
* With `prefix: false`: /favicon.ico
*/
prefix: true prefix: true
}, },
/**
* Configure server compression.
*
* Set to `false` to disable compression. You can also pass an object of options
* for [compression middleware](https://www.npmjs.com/package/compression), or
* use your own middleware by passing it in directly - for example,
* `otherComp({ myOptions: 'example' })`.
*/
compressor: { compressor: {
threshold: 0 threshold: 0
}, },
/**
* To disable etag for pages set `etag: false`. See
* [etag docs](https://github.com/jshttp/etag) for possible options.
* You can use your own hash function by specifying etag.hash:
*
* @example
* ```js
* import { murmurHash128 } from 'murmurhash-native'
*
* export default {
* render: {
* etag: {
* hash: html => murmurHash128(html)
* }
* }
* }
* ```
* In this example we are using `murmurhash-native`, which is faster
* for larger HTML body sizes. Note that the weak option is ignored
* when specifying your own hash function.
*/
etag: { etag: {
hash: false, hash: false,
weak: false weak: false
}, },
/**
* Use this to configure Content-Security-Policy to load external resources. [Read more](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
*
* Set to `true` to enable, or you can pass options to fine-tune your CSP options.
*
* **Prerequisites**:
* These CSP settings are only effective when using Nuxt with `mode: 'server'`
* to serve your SSR application.
*
* **Updating settings**:
* These settings are read by the Nuxt server directly from `nuxt.config.js`.
* This means changes to these settings take effect when the server is restarted.
* There is no need to rebuild the application to update CSP settings.
*
* @example
* ```js
* csp: {
* hashAlgorithm: 'sha256',
* policies: {
* 'script-src': [
* 'https://www.google-analytics.com',
* 'https://name.example.com'
* ],
* 'report-uri': ['https://report.example.com/report-csp-violations']
* },
* addMeta: true
* }
* ```
*
* The following example allows Google Analytics, LogRocket.io, and Sentry.io
* for logging and analytic tracking.
*
* Review [this blog on Sentry.io](https://blog.sentry.io/2018/09/04/how-sentry-captures-csp-violations)
* To learn what tracking link you should use.
* @example
* ```js
* // PRIMARY_HOSTS = `loc.example-website.com`
* csp: {
* reportOnly: true,
* hashAlgorithm: 'sha256',
* policies: {
* 'default-src': ["'self'"],
* 'img-src': ['https:', '*.google-analytics.com'],
* 'worker-src': ["'self'", `blob:`, PRIMARY_HOSTS, '*.logrocket.io'],
* 'style-src': ["'self'", "'unsafe-inline'", PRIMARY_HOSTS],
* 'script-src': [
* "'self'",
* "'unsafe-inline'",
* PRIMARY_HOSTS,
* 'sentry.io',
* '*.sentry-cdn.com',
* '*.google-analytics.com',
* '*.logrocket.io'
* ],
* 'connect-src': [PRIMARY_HOSTS, 'sentry.io', '*.google-analytics.com'],
* 'form-action': ["'self'"],
* 'frame-ancestors': ["'none'"],
* 'object-src': ["'none'"],
* 'base-uri': [PRIMARY_HOSTS],
* 'report-uri': [
* `https://sentry.io/api/<project>/security/?sentry_key=<key>`
* ]
* }
* }
* ```
*/
csp: { csp: {
$resolve: (val, get) => { $resolve: (val, get) => {
if (!val) { return false } if (!val) { return false }
return { return {
hashAlgorithm: 'sha256', hashAlgorithm: 'sha256',
allowedSources: undefined, allowedSources: undefined,
/** Policies to be added to the response `Content-Security-Policy` HTTP header. */
policies: undefined, policies: undefined,
/**
* Whether to add `<meta http-equiv="Content-Security-Policy"/>` to the `<head>`.
* This is independent of the `csp.policies` configuration and the complete set
* of the defined policies will still be added to the HTTP response header.
*
* **Note** CSP hashes will not be added as `<meta>` if `script-src` policy
* contains 'unsafe-inline'. This is due to browsers ignoring 'unsafe-inline'
* if hashes are present. (Set option `unsafeInlineCompatibility` to true to
* disable this behavior.)
*/
addMeta: Boolean(get('target') === 'static'), addMeta: Boolean(get('target') === 'static'),
/**
* Set option `unsafeInlineCompatibility` to true if you want both hashes and
* 'unsafe-inline' for CSPv1 compatibility. In that case the `<meta>` tag will
* still only contain the hashes of the inline `<script>` tags, and the policies
* defined under `csp.policies` will be used in the `Content-Security-Policy`
* HTTP response header.
*/
unsafeInlineCompatibility: false, unsafeInlineCompatibility: false,
reportOnly: get('debug'), reportOnly: get('debug'),
...val ...val
} }
} }
}, },
/**
* Options used for serving distribution files. Only applicable in production.
*
* See [serve-static docs](https://www.npmjs.com/package/serve-static) for possible options.
*/
dist: { dist: {
index: false, index: false,
maxAge: '1y' maxAge: '1y'
}, },
// https://github.com/nuxt/serve-placeholder
/**
* Configure fallback behavior for [`serve-placeholder` middleware](https://github.com/nuxt/serve-placeholder).
*
* Example of allowing `.js` extension for routing (for example, `/repos/nuxt.js`):
*
* @example
* ```js
* fallback: {
* static: {
* // Avoid sending 404 for these extensions
* handlers: {
* '.js': false
* }
* }
* }
* ```
*/
fallback: { fallback: {
/**
* For routes matching the publicPath (`/_nuxt/*`)
* Disable by setting to false.
*/
dist: {}, dist: {},
/**
* For all other routes (`/*`)
* Disable by setting to false.
*/
static: { static: {
skipUnknown: true, skipUnknown: true,
handlers: { handlers: {

View File

@ -1,31 +1,135 @@
import { normalizeURL, withTrailingSlash } from 'ufo' import { normalizeURL, withTrailingSlash } from 'ufo'
export default { export default {
/**
* Configure the router mode.
*
* For server-side rendering it is not recommended to change it.
*/
mode: 'history', mode: 'history',
/**
* The base URL of the app. For example, if the entire single page application is
* served under /app/, then base should use the value '/app/'.
*
* This can be useful if you need to serve Nuxt as a different context root, from
* within a bigger web site.
*/
base: { base: {
$resolve: (val = '/') => withTrailingSlash(normalizeURL(val)) $resolve: (val = '/') => withTrailingSlash(normalizeURL(val))
}, },
/** @private */
_routerBaseSpecified: { _routerBaseSpecified: {
$resolve: (_val, get) => typeof get('router.base') === 'string' $resolve: (_val, get) => typeof get('router.base') === 'string'
}, },
routes: [], routes: [],
/**
* This allows changing the separator between route names that Nuxt uses.
*
* Imagine we have the page file `pages/posts/_id.vue`. Nuxt will generate the
* route name programmatically, in this case `posts-id`. If you change the routeNameSplitter
* config to `/` the name will change to `posts/id`.
*/
routeNameSplitter: '-', routeNameSplitter: '-',
/**
* Set the default(s) middleware for every page of the application.
*/
middleware: { middleware: {
$resolve: val => Array.isArray(val) ? val : [val].filter(Boolean) $resolve: val => Array.isArray(val) ? val : [val].filter(Boolean)
}, },
/**
* Globally configure `<nuxt-link>` default active class.
*/
linkActiveClass: 'nuxt-link-active', linkActiveClass: 'nuxt-link-active',
/**
* Globally configure `<nuxt-link>` default exact active class.
*/
linkExactActiveClass: 'nuxt-link-exact-active', linkExactActiveClass: 'nuxt-link-exact-active',
/**
* Globally configure `<nuxt-link>` default prefetch class (feature disabled by default)
*/
linkPrefetchedClass: false, linkPrefetchedClass: false,
/**
* You can pass a function to extend the routes created by Nuxt.
*
* @example
* ```js
* extendRoutes(routes, resolve) {
* routes.push({
* name: 'custom',
* path: '*',
* component: resolve(__dirname, 'pages/404.vue')
* })
* ```
*/
extendRoutes: null, extendRoutes: null,
/**
* The `scrollBehavior` option lets you define a custom behavior for the scroll
* position between the routes. This method is called every time a page is
* rendered. To learn more about it.
*
* @see [vue-router `scrollBehavior` documentation](https://router.vuejs.org/guide/advanced/scroll-behavior.html)
*/
scrollBehavior: { scrollBehavior: {
$schema: { $schema: {
deprecated: 'router.scrollBehavior` property is deprecated in favor of using `~/app/router.scrollBehavior.js` file, learn more: https://nuxtjs.org/api/configuration-router#scrollbehavior' deprecated: 'router.scrollBehavior` property is deprecated in favor of using `~/app/router.scrollBehavior.js` file, learn more: https://nuxtjs.org/api/configuration-router#scrollbehavior'
} }
}, },
/**
* Provide custom query string parse function. Overrides the default.
*/
parseQuery: false, parseQuery: false,
/**
* Provide custom query string stringify function. Overrides the default.
*/
stringifyQuery: false, stringifyQuery: false,
/**
* Controls whether the router should fall back to hash mode when the browser
* does not support history.pushState but mode is set to history.
*
* Setting this to false essentially makes every router-link navigation a full
* page refresh in IE9. This is useful when the app is server-rendered and needs
* to work in IE9, because a hash mode URL does not work with SSR.
*/
fallback: false, fallback: false,
/**
* Configure `<nuxt-link>` to prefetch the code-splitted page when detected within
* the viewport. Requires [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to be supported (see [Caniuse](https://caniuse.com/intersectionobserver)).
*/
prefetchLinks: true, prefetchLinks: true,
/**
* When using nuxt generate with target: 'static', Nuxt will generate a
* payload.js for each page.
*
* With this option enabled, Nuxt will automatically prefetch the payload of the
* linked page when the <nuxt-link> is visible in the viewport, making instant navigation.
*/
prefetchPayloads: true, prefetchPayloads: true,
/**
* If this option is set to true, trailing slashes will be appended to every
* route. If set to false, they'll be removed.
*
* **Attention**: This option should not be set without preparation and has to
* be tested thoroughly. When setting `trailingSlash` to something else than
* undefined, the opposite route will stop working. Thus 301 redirects should
* be in place and your internal linking has to be adapted correctly. If you set
* `trailingSlash` to true, then only example.com/abc/ will work but not
* example.com/abc. On false, it's vice-versa
*/
trailingSlash: undefined trailingSlash: undefined
} }

View File

@ -1,7 +1,27 @@
export default { export default {
/**
* Whether to enable HTTPS.
*
* @example
* ```js
* https: {
* key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
* cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
* }
* ```
*/
https: false, https: false,
port: process.env.NUXT_PORT || process.env.PORT || process.env.npm_package_config_nuxt_port || 3000, port: process.env.NUXT_PORT || process.env.PORT || process.env.npm_package_config_nuxt_port || 3000,
host: process.env.NUXT_HOST || process.env.HOST || process.env.npm_package_config_nuxt_host || 'localhost', host: process.env.NUXT_HOST || process.env.HOST || process.env.npm_package_config_nuxt_host || 'localhost',
socket: process.env.UNIX_SOCKET || process.env.npm_package_config_unix_socket, socket: process.env.UNIX_SOCKET || process.env.npm_package_config_unix_socket,
/**
* Enabling timing adds a middleware to measure the time elapsed during
* server-side rendering and adds it to the headers as 'Server-Timing'.
*
* Apart from true/false, this can be an object for providing options.
* Currently, only `total` is supported (which directly tracks the whole
* time spent on server-side rendering.
*/
timing: (val: any) => val ? ({ total: true, ...val }) : false timing: (val: any) => val ? ({ total: true, ...val }) : false
} }

View File

@ -13,6 +13,7 @@ import {
extendRoutes extendRoutes
} from './utils' } from './utils'
/** Legacy ModuleContainer for backwards compatibility with existing Nuxt 2 modules. */
export class ModuleContainer { export class ModuleContainer {
nuxt: Nuxt nuxt: Nuxt
options: NuxtOptions options: NuxtOptions
@ -27,47 +28,88 @@ export class ModuleContainer {
return nuxtCtx.call(this.nuxt, () => fn(...args)) return nuxtCtx.call(this.nuxt, () => fn(...args))
} }
/**
* Returns a resolved promise immediately.
*
* @deprecated
*/
ready () { ready () {
return Promise.resolve() return Promise.resolve()
} }
/** @deprecated */
addVendor () { addVendor () {
console.warn('addVendor has been deprecated') console.warn('addVendor has been deprecated and has no effect.')
} }
/**
* Renders given template using lodash template during build into the project buildDir (`.nuxt`).
*
* If a fileName is not provided or the template is string, target file name defaults to
* [dirName].[fileName].[pathHash].[ext].
*/
addTemplate (tmpl: TemplateOpts | string) { addTemplate (tmpl: TemplateOpts | string) {
return this._call(addTemplate, tmpl) return this._call(addTemplate, tmpl)
} }
/**
* Registers a plugin using `addTemplate` and prepends it to the plugins[] array.
*
* Note: You can use mode or .client and .server modifiers with fileName option
* to use plugin only in client or server side.
*
* If you choose to specify a fileName, you can configure a custom path for the
* fileName too, so you can choose the folder structure inside .nuxt folder in
* order to prevent name collisioning:
*
* @example
* ```js
* this.addPlugin({
* src: path.resolve(__dirname, 'templates/foo.js'),
* fileName: 'foo.server.js' // [optional] only include in server bundle
* })
* ```
*/
addPlugin (tmpl: PluginTemplateOpts) { addPlugin (tmpl: PluginTemplateOpts) {
return this._call(addPlugin, tmpl) return this._call(addPlugin, tmpl)
} }
/** Register a custom layout. If its name is 'error' it will override the default error layout. */
addLayout (tmpl: TemplateOpts, name: string) { addLayout (tmpl: TemplateOpts, name: string) {
return this._call(addLayout, tmpl, name) return this._call(addLayout, tmpl, name)
} }
/**
* Set the layout that will render Nuxt errors. It should already have been added via addLayout or addTemplate.
*
* @param dst - Path to layout file within the buildDir (`.nuxt/<dst>.vue`)
*/
addErrorLayout (dst: string) { addErrorLayout (dst: string) {
return this._call(addErrorLayout, dst) return this._call(addErrorLayout, dst)
} }
/** Adds a new server middleware to the end of the server middleware array. */
addServerMiddleware (middleware) { addServerMiddleware (middleware) {
return this._call(addServerMiddleware, middleware) return this._call(addServerMiddleware, middleware)
} }
/** Allows extending webpack build config by chaining `options.build.extend` function. */
extendBuild (fn) { extendBuild (fn) {
return this._call(extendBuild, fn) return this._call(extendBuild, fn)
} }
/** Allows extending routes by chaining `options.build.extendRoutes` function. */
extendRoutes (fn) { extendRoutes (fn) {
return this._call(extendRoutes, fn) return this._call(extendRoutes, fn)
} }
requireModule (moduleOpts) { /** `requireModule` is a shortcut for `addModule` */
requireModule (moduleOpts: string | [src: string, options: any]) {
return installModule(this.nuxt, moduleOpts) return installModule(this.nuxt, moduleOpts)
} }
addModule (moduleOpts) { /** Registers a module. moduleOpts can be a string or an array ([src, options]). */
addModule (moduleOpts: string | [src: string, options: any]) {
return installModule(this.nuxt, moduleOpts) return installModule(this.nuxt, moduleOpts)
} }
} }

View File

@ -4,6 +4,10 @@ import { useNuxt, nuxtCtx } from '../nuxt'
import type { Nuxt } from '../types/nuxt' import type { Nuxt } from '../types/nuxt'
import type { NuxtModule, LegacyNuxtModule, ModuleOptions } from '../types/module' import type { NuxtModule, LegacyNuxtModule, ModuleOptions } from '../types/module'
/**
* Define a Nuxt module, automatically merging defaults with user provided options, installing
* any hooks that are provided, and calling an optional setup function for full control.
*/
export function defineNuxtModule<OptionsT extends ModuleOptions> (input: NuxtModule<OptionsT> | ((nuxt: Nuxt) => NuxtModule<OptionsT>)): LegacyNuxtModule { export function defineNuxtModule<OptionsT extends ModuleOptions> (input: NuxtModule<OptionsT> | ((nuxt: Nuxt) => NuxtModule<OptionsT>)): LegacyNuxtModule {
let mod: NuxtModule<OptionsT> let mod: NuxtModule<OptionsT>

View File

@ -5,6 +5,7 @@ import { nuxtCtx } from '../nuxt'
import { defineNuxtModule } from './define' import { defineNuxtModule } from './define'
import { ModuleContainer } from './container' import { ModuleContainer } from './container'
/** Installs a module on a Nuxt instance. */
export async function installModule (nuxt: Nuxt, installOpts: ModuleInstallOptions) { export async function installModule (nuxt: Nuxt, installOpts: ModuleInstallOptions) {
let src: ModuleSrc let src: ModuleSrc
let options: ModuleOptions = {} let options: ModuleOptions = {}

View File

@ -6,6 +6,12 @@ import { useNuxt } from '../nuxt'
import { chainFn } from '../utils/task' import { chainFn } from '../utils/task'
import type { TemplateOpts, PluginTemplateOpts } from '../types/module' import type { TemplateOpts, PluginTemplateOpts } from '../types/module'
/**
* Renders given template using lodash template during build into the project buildDir (`.nuxt`).
*
* If a fileName is not provided or the template is string, target file name defaults to
* [dirName].[fileName].[pathHash].[ext].
*/
export function addTemplate (tmpl: TemplateOpts | string) { export function addTemplate (tmpl: TemplateOpts | string) {
const nuxt = useNuxt() const nuxt = useNuxt()
@ -21,7 +27,7 @@ export function addTemplate (tmpl: TemplateOpts | string) {
throw new Error('tmpl src not found: ' + src) throw new Error('tmpl src not found: ' + src)
} }
// Mostly for DX, some people prefers `filename` vs `fileName` // Mostly for DX, some people prefer `filename` vs `fileName`
const fileName = typeof tmpl === 'string' ? '' : tmpl.fileName || tmpl.filename const fileName = typeof tmpl === 'string' ? '' : tmpl.fileName || tmpl.filename
// Generate unique and human readable dst filename if not provided // Generate unique and human readable dst filename if not provided
const dst = fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(src)}${srcPath.ext}` const dst = fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(src)}${srcPath.ext}`
@ -37,6 +43,24 @@ export function addTemplate (tmpl: TemplateOpts | string) {
return tmplObj return tmplObj
} }
/**
* Registers a plugin using `addTemplate` and prepends it to the plugins[] array.
*
* Note: You can use mode or .client and .server modifiers with fileName option
* to use plugin only in client or server side.
*
* If you choose to specify a fileName, you can configure a custom path for the
* fileName too, so you can choose the folder structure inside .nuxt folder in
* order to prevent name collisioning:
*
* @example
* ```js
* addPlugin({
* src: path.resolve(__dirname, 'templates/foo.js'),
* fileName: 'foo.server.js' // [optional] only include in server bundle
* })
* ```
*/
export function addPlugin (tmpl: PluginTemplateOpts) { export function addPlugin (tmpl: PluginTemplateOpts) {
const nuxt = useNuxt() const nuxt = useNuxt()
@ -53,6 +77,7 @@ export function addPlugin (tmpl: PluginTemplateOpts) {
}) })
} }
/** Register a custom layout. If its name is 'error' it will override the default error layout. */
export function addLayout (tmpl: TemplateOpts, name: string) { export function addLayout (tmpl: TemplateOpts, name: string) {
const nuxt = useNuxt() const nuxt = useNuxt()
@ -73,6 +98,11 @@ export function addLayout (tmpl: TemplateOpts, name: string) {
} }
} }
/**
* Set the layout that will render Nuxt errors. It should already have been added via addLayout or addTemplate.
*
* @param dst - Path to layout file within the buildDir (`.nuxt/<dst>.vue`)
*/
export function addErrorLayout (dst: string) { export function addErrorLayout (dst: string) {
const nuxt = useNuxt() const nuxt = useNuxt()
@ -80,12 +110,14 @@ export function addErrorLayout (dst: string) {
nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}` nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
} }
/** Adds a new server middleware to the end of the server middleware array. */
export function addServerMiddleware (middleware) { export function addServerMiddleware (middleware) {
const nuxt = useNuxt() const nuxt = useNuxt()
nuxt.options.serverMiddleware.push(middleware) nuxt.options.serverMiddleware.push(middleware)
} }
/** Allows extending webpack build config by chaining `options.build.extend` function. */
export function extendBuild (fn) { export function extendBuild (fn) {
const nuxt = useNuxt() const nuxt = useNuxt()
@ -93,6 +125,7 @@ export function extendBuild (fn) {
nuxt.options.build.extend = chainFn(nuxt.options.build.extend, fn) nuxt.options.build.extend = chainFn(nuxt.options.build.extend, fn)
} }
/** Allows extending routes by chaining `options.build.extendRoutes` function. */
export function extendRoutes (fn) { export function extendRoutes (fn) {
const nuxt = useNuxt() const nuxt = useNuxt()

View File

@ -2,9 +2,28 @@ import { getContext } from 'unctx'
import type { Nuxt } from './types/nuxt' import type { Nuxt } from './types/nuxt'
import type { NuxtConfig } from './types/config' import type { NuxtConfig } from './types/config'
/** Direct access to the Nuxt context - see https://github.com/unjs/unctx. */
export const nuxtCtx = getContext<Nuxt>('nuxt') export const nuxtCtx = getContext<Nuxt>('nuxt')
/**
* Get access to Nuxt (if run within the Nuxt context) - see https://github.com/unjs/unctx.
*
* @example
* ```js
* const nuxt = useNuxt()
* ```
*/
export const useNuxt = nuxtCtx.use export const useNuxt = nuxtCtx.use
/**
* This helper serves to add the correct typings for your `nuxt.config.js`.
*
* @example
* ```ts
* import { defineNuxtConfig } from '@nuxt/kit'
* export default defineNuxtConfig({
* // your Nuxt config
* })
*/
export function defineNuxtConfig (config: NuxtConfig) { export function defineNuxtConfig (config: NuxtConfig) {
return config return config
} }

View File

@ -3,18 +3,26 @@ import { Nuxt } from './nuxt'
import { NuxtHooks } from './hooks' import { NuxtHooks } from './hooks'
export interface ModuleMeta { export interface ModuleMeta {
/** The module name. */
name?: string name?: string
/**
* The configuration key used within `nuxt.config` for this module's options.
* For example, `@nuxtjs/axios` uses `axios`.
*/
configKey?: string configKey?: string
[key: string]: any [key: string]: any
} }
/** The options received */
export type ModuleOptions = Record<string, any> export type ModuleOptions = Record<string, any>
/** A pre-kit Nuxt module */
export interface LegacyNuxtModule { export interface LegacyNuxtModule {
(this: ModuleContainer, inlineOptions?: ModuleOptions): void | Promise<void> (this: ModuleContainer, inlineOptions?: ModuleOptions): void | Promise<void>
meta?: ModuleMeta meta?: ModuleMeta
} }
/** A Nuxt module definition */
export interface NuxtModule<T extends ModuleOptions = any> extends ModuleMeta { export interface NuxtModule<T extends ModuleOptions = any> extends ModuleMeta {
defaults?: T defaults?: T
setup?: (this: null, resolvedOptions: T, nuxt: Nuxt) => void | Promise<void> setup?: (this: null, resolvedOptions: T, nuxt: Nuxt) => void | Promise<void>
@ -38,14 +46,19 @@ export type ModuleInstallOptions =
// -- Templates -- // -- Templates --
export interface TemplateOpts { export interface TemplateOpts {
/** The target filename once the template is copied into the Nuxt buildDir */
filename?: string filename?: string
/** The target filename once the template is copied into the Nuxt buildDir */
fileName?: string fileName?: string
/** An options object that will be accessible within the template via `<% options %>` */
options?: Record<string, any> options?: Record<string, any>
/** The resolved path to the source file to be templated */
src: string src: string
} }
export interface PluginTemplateOpts extends TemplateOpts { export interface PluginTemplateOpts extends TemplateOpts {
/** @deprecated use mode */ /** @deprecated use mode */
ssr?: boolean ssr?: boolean
/** Whether the plugin will be loaded on only server-side, only client-side or on both. */
mode?: 'all' | 'server' | 'client' mode?: 'all' | 'server' | 'client'
} }

View File

@ -2,15 +2,20 @@ import { NuxtHookName, NuxtHooks } from './hooks'
import { NuxtOptions } from './config' import { NuxtOptions } from './config'
export interface Nuxt { export interface Nuxt {
/** The resolved Nuxt configuration. */
options: NuxtOptions options: NuxtOptions
hooks: { hooks: {
/** Register a function to be run when the named Nuxt hook is called. */
hook<Hook extends NuxtHookName>(hookName: Hook, callback: NuxtHooks[Hook]): void | Promise<void> hook<Hook extends NuxtHookName>(hookName: Hook, callback: NuxtHooks[Hook]): void | Promise<void>
/** Run all Nuxt hooks that have been registered against the hook name. */
callHook<Hook extends NuxtHookName>(hookName: Hook, ...args: Parameters<NuxtHooks[Hook]>): ReturnType<NuxtHooks[Hook]> callHook<Hook extends NuxtHookName>(hookName: Hook, ...args: Parameters<NuxtHooks[Hook]>): ReturnType<NuxtHooks[Hook]>
/** Add all hooks in the object passed in. */
addHooks(hooks: Partial<NuxtHooks>): void addHooks(hooks: Partial<NuxtHooks>): void
} }
hook: Nuxt['hooks']['hook'] hook: Nuxt['hooks']['hook']
callHook: Nuxt['hooks']['callHook'] callHook: Nuxt['hooks']['callHook']
/** The production or development server */
server?: any server?: any
} }

View File

@ -9,8 +9,11 @@ export interface ResolveModuleOptions {
} }
export interface RequireModuleOptions extends ResolveModuleOptions { export interface RequireModuleOptions extends ResolveModuleOptions {
native?: boolean // TODO: use create-require for jest environment
// native?: boolean
/** Clear the require cache (force fresh require) but only if not within `node_modules` */
clearCache?: boolean clearCache?: boolean
/** Automatically de-default the result of requiring the module. */
interopDefault?: boolean interopDefault?: boolean
} }
@ -63,6 +66,7 @@ export function scanRequireTree (id: string, files = new Set<string>()) {
return files return files
} }
/** Access the require cache by module id. */
export function getRequireCacheItem (id: string) { export function getRequireCacheItem (id: string) {
try { try {
return _require.cache[id] return _require.cache[id]
@ -70,16 +74,19 @@ export function getRequireCacheItem (id: string) {
} }
} }
/** Resolve the `package.json` file for a given module. */
export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) { export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) {
return requireModule(join(id, 'package.json'), opts) return requireModule(join(id, 'package.json'), opts)
} }
/** Resolve the path of a module. */
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) { export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
return _require.resolve(id, { return _require.resolve(id, {
paths: opts.paths paths: opts.paths
}) })
} }
/** Try to resolve the path of a module, but don't emit an error if it can't be found. */
export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}) { export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}) {
try { try {
return resolveModule(path, opts) return resolveModule(path, opts)
@ -90,6 +97,7 @@ export function tryResolveModule (path: string, opts: ResolveModuleOptions = {})
} }
} }
/** Require a module and return it. */
export function requireModule (id: string, opts: RequireModuleOptions = {}) { export function requireModule (id: string, opts: RequireModuleOptions = {}) {
// Resolve id // Resolve id
const resolvedPath = resolveModule(id, opts) const resolvedPath = resolveModule(id, opts)
@ -110,6 +118,7 @@ export function requireModule (id: string, opts: RequireModuleOptions = {}) {
return requiredModule return requiredModule
} }
/** Try to require a module, but don't emit an error if the module can't be required. */
export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) { export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) {
try { try {
return requireModule(id, opts) return requireModule(id, opts)

View File

@ -2,13 +2,23 @@ import { existsSync, lstatSync } from 'fs'
import { resolve, join } from 'upath' import { resolve, join } from 'upath'
export interface ResolveOptions { export interface ResolveOptions {
/**
* The base path against which to resolve the path
*
* @default .
*/
base?: string base?: string
/**
* An object of aliases (alias, path) to take into account, for example
* `{ 'example/alias': '/full/path/to/alias' }`
*/
alias?: Record<string, string> alias?: Record<string, string>
/** The file extensions to try (for example, ['js', 'ts']) */
extensions?: string[] extensions?: string[]
} }
function resolvePath (path: string, opts: ResolveOptions = {}) { function resolvePath (path: string, opts: ResolveOptions = {}) {
// Fast return in case of path exists // Fast return if the path exists
if (existsSync(path)) { if (existsSync(path)) {
return path return path
} }
@ -55,6 +65,15 @@ function resolvePath (path: string, opts: ResolveOptions = {}) {
throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`) throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`)
} }
/**
* Return a path with any relevant aliases resolved.
*
* @example
* ```js
* const aliases = { 'test': '/here/there' }
* resolveAlias('test/everywhere', aliases)
* // '/here/there/everywhere'
*/
export function resolveAlias (path: string, alias: ResolveOptions['alias']) { export function resolveAlias (path: string, alias: ResolveOptions['alias']) {
for (const key in alias) { for (const key in alias) {
if (path.startsWith(key)) { if (path.startsWith(key)) {
@ -64,6 +83,10 @@ export function resolveAlias (path: string, alias: ResolveOptions['alias']) {
return path return path
} }
/**
* Resolve the path of a file but don't emit an error,
* even if the module can't be resolved.
*/
export function tryResolvePath (path: string, opts: ResolveOptions = {}) { export function tryResolvePath (path: string, opts: ResolveOptions = {}) {
try { try {
return resolvePath(path, opts) return resolvePath(path, opts)

View File

@ -4401,6 +4401,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"comment-parser@npm:1.1.2":
version: 1.1.2
resolution: "comment-parser@npm:1.1.2"
checksum: b61e90aa9e725d352c09697933536256e76e23498a5f8720324b354f4910edd1dbdbb1b1a83b8ed6d98ff37781c973bb0a355e57afe4b092e0e63273f10fc61d
languageName: node
linkType: hard
"commondir@npm:^1.0.1": "commondir@npm:^1.0.1":
version: 1.0.1 version: 1.0.1
resolution: "commondir@npm:1.0.1" resolution: "commondir@npm:1.0.1"
@ -4977,7 +4984,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1": "debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1":
version: 4.3.2 version: 4.3.2
resolution: "debug@npm:4.3.2" resolution: "debug@npm:4.3.2"
dependencies: dependencies:
@ -5682,6 +5689,23 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-jsdoc@npm:^32.3.0":
version: 32.3.0
resolution: "eslint-plugin-jsdoc@npm:32.3.0"
dependencies:
comment-parser: 1.1.2
debug: ^4.3.1
jsdoctypeparser: ^9.0.0
lodash: ^4.17.20
regextras: ^0.7.1
semver: ^7.3.4
spdx-expression-parse: ^3.0.1
peerDependencies:
eslint: ^6.0.0 || ^7.0.0
checksum: f4665eb3c4b32d139342028a9f0d96b095214778a3e32b8a1461d397674954c4d36a0c019f11eefcfa64202c2ad71ecf558e5a553d8a3827b3ccfef2391a741c
languageName: node
linkType: hard
"eslint-plugin-node@npm:^11.1.0": "eslint-plugin-node@npm:^11.1.0":
version: 11.1.0 version: 11.1.0
resolution: "eslint-plugin-node@npm:11.1.0" resolution: "eslint-plugin-node@npm:11.1.0"
@ -8385,6 +8409,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"jsdoctypeparser@npm:^9.0.0":
version: 9.0.0
resolution: "jsdoctypeparser@npm:9.0.0"
bin:
jsdoctypeparser: bin/jsdoctypeparser
checksum: d0c855be23ddb77260d54c8d833bf089e2e5a08f7b7dd7fdd60c35d3a222669e2edadc455fd69c435e593413e09b6792410d1d877c8f423662053f5e5012513b
languageName: node
linkType: hard
"jsdom@npm:^16.4.0": "jsdom@npm:^16.4.0":
version: 16.5.3 version: 16.5.3
resolution: "jsdom@npm:16.5.3" resolution: "jsdom@npm:16.5.3"
@ -9985,6 +10018,7 @@ __metadata:
"@types/jest": ^26.0.22 "@types/jest": ^26.0.22
"@types/node": ^14.14.37 "@types/node": ^14.14.37
eslint: ^7.24.0 eslint: ^7.24.0
eslint-plugin-jsdoc: ^32.3.0
jest: ^26.6.3 jest: ^26.6.3
jiti: ^1.9.1 jiti: ^1.9.1
lerna: ^4.0.0 lerna: ^4.0.0
@ -11676,6 +11710,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"regextras@npm:^0.7.1":
version: 0.7.1
resolution: "regextras@npm:0.7.1"
checksum: 60e965d826751da5c7c744c9ecdca3bd90026f8376ec6a362b04b9eeb8140e8be5f6028de155f9b4d3a713344aff625668522c3fb3fc391aec67815bdc3ab509
languageName: node
linkType: hard
"remove-trailing-separator@npm:^1.0.1": "remove-trailing-separator@npm:^1.0.1":
version: 1.1.0 version: 1.1.0
resolution: "remove-trailing-separator@npm:1.1.0" resolution: "remove-trailing-separator@npm:1.1.0"
@ -12553,7 +12594,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"spdx-expression-parse@npm:^3.0.0": "spdx-expression-parse@npm:^3.0.0, spdx-expression-parse@npm:^3.0.1":
version: 3.0.1 version: 3.0.1
resolution: "spdx-expression-parse@npm:3.0.1" resolution: "spdx-expression-parse@npm:3.0.1"
dependencies: dependencies: