From ce72ce6b07eb175e2ea9a1fc0d67ab74eb3808bc Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 15 Apr 2021 19:49:29 +0100 Subject: [PATCH] docs(kit): initial documentation (#86) --- .eslintrc | 16 +- package.json | 1 + packages/app/src/composables/data.ts | 3 + packages/app/src/composables/hydrate.ts | 1 + packages/app/src/nuxt.ts | 1 + packages/kit/src/config/env.ts | 41 +- packages/kit/src/config/load.ts | 5 +- packages/kit/src/config/schema/_app.ts | 175 +++++++- packages/kit/src/config/schema/_common.ts | 463 +++++++++++++++++++- packages/kit/src/config/schema/_internal.ts | 13 +- packages/kit/src/config/schema/build.ts | 340 +++++++++++++- packages/kit/src/config/schema/cli.ts | 7 + packages/kit/src/config/schema/generate.ts | 125 ++++++ packages/kit/src/config/schema/messages.ts | 8 + packages/kit/src/config/schema/render.ts | 225 +++++++++- packages/kit/src/config/schema/router.ts | 104 +++++ packages/kit/src/config/schema/server.ts | 20 + packages/kit/src/module/container.ts | 48 +- packages/kit/src/module/define.ts | 4 + packages/kit/src/module/install.ts | 1 + packages/kit/src/module/utils.ts | 35 +- packages/kit/src/nuxt.ts | 19 + packages/kit/src/types/module.ts | 13 + packages/kit/src/types/nuxt.ts | 5 + packages/kit/src/utils/cjs.ts | 11 +- packages/kit/src/utils/resolve.ts | 25 +- yarn.lock | 45 +- 27 files changed, 1717 insertions(+), 37 deletions(-) diff --git a/.eslintrc b/.eslintrc index 2c23dddc42..442bafddf4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,11 +2,25 @@ "globals": { "NodeJS": true }, + "plugins": ["jsdoc"], "extends": [ + "plugin:jsdoc/recommended", "@nuxtjs/eslint-config-typescript" ], "rules": { "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" + } + } } } diff --git a/package.json b/package.json index 51c356c6d8..d3dfef767a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@types/jest": "^26.0.22", "@types/node": "^14.14.37", "eslint": "^7.24.0", + "eslint-plugin-jsdoc": "^32.3.0", "jest": "^26.6.3", "jiti": "^1.9.1", "lerna": "^4.0.0", diff --git a/packages/app/src/composables/data.ts b/packages/app/src/composables/data.ts index 0aee2c87f7..1dd6df9181 100644 --- a/packages/app/src/composables/data.ts +++ b/packages/app/src/composables/data.ts @@ -13,6 +13,7 @@ export function ensureReactive< /** * Returns a unique string suitable for syncing data between server and client. + * * @param nuxt (optional) A Nuxt 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. + * * @param nuxt (optional) A Nuxt instance * @param vm (optional) A Vue component - by default it will use the current instance */ @@ -53,6 +55,7 @@ export function useData> ( /** * Allows accessing reactive global data that can be synced between server and client. + * * @param nuxt - (optional) A Nuxt instance */ export function useGlobalData (nuxt = useNuxt()): Record { diff --git a/packages/app/src/composables/hydrate.ts b/packages/app/src/composables/hydrate.ts index cd05de4639..74b464f4b7 100644 --- a/packages/app/src/composables/hydrate.ts +++ b/packages/app/src/composables/hydrate.ts @@ -2,6 +2,7 @@ import { useNuxt } from '@nuxt/app' /** * 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 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 diff --git a/packages/app/src/nuxt.ts b/packages/app/src/nuxt.ts index 89cf5298a2..b71ff09a56 100644 --- a/packages/app/src/nuxt.ts +++ b/packages/app/src/nuxt.ts @@ -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`. + * * @param nuxt A Nuxt instance * @param setup The function to call */ diff --git a/packages/kit/src/config/env.ts b/packages/kit/src/config/env.ts index 5d278a1c90..155bee926e 100644 --- a/packages/kit/src/config/env.ts +++ b/packages/kit/src/config/env.ts @@ -3,15 +3,37 @@ import { existsSync, promises as fsp } from 'fs' import dotenv from 'dotenv' export interface LoadDotEnvOptions { + /** The project root directory (either absolute or relative to the current working directory). */ rootDir: string + /** + * What file to look in for environment variables (either absolute or relative + * to the current working directory). For example, `.env`. + */ dotenvFile: string + /** + * Whether to interpolate variables within .env. + * + * @example + * ```env + * BASE_DIR="/test" + * # resolves to "/test/further" + * ANOTHER_DIR="${BASE_DIR}/further" + * ``` + */ 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 - const env = await loalDotenv({ + const env = await loadDotenv({ rootDir, dotenvFile: '.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 dotenvFile = resolve(opts.rootDir, opts.dotenvFile) - if (await existsSync(dotenvFile)) { + if (existsSync(dotenvFile)) { const parsed = dotenv.parse(await fsp.readFile(dotenvFile, 'utf-8')) Object.assign(env, parsed) } @@ -51,13 +74,13 @@ export async function loalDotenv (opts: LoadDotEnvOptions) { } // Based on https://github.com/motdotla/dotenv-expand -function expand (target, source = {}, parse = v => v) { - function getValue (key) { +function expand (target: Record, source: Record = {}, parse = (v: any) => v) { + function getValue (key: string) { // Source value 'wins' over target value return source[key] !== undefined ? source[key] : target[key] } - function interpolate (value, parents = []) { + function interpolate (value: unknown, parents: string[] = []) { if (typeof value !== 'string') { return value } @@ -66,7 +89,7 @@ function expand (target, source = {}, parse = v => v) { const parts = /(.?)\${?([a-zA-Z0-9_:]+)?}?/g.exec(match) const prefix = parts[1] - let value, replacePart + let value, replacePart: string if (prefix === '\\') { replacePart = parts[0] diff --git a/packages/kit/src/config/load.ts b/packages/kit/src/config/load.ts index 3aec30d2a4..22ba9cdd48 100644 --- a/packages/kit/src/config/load.ts +++ b/packages/kit/src/config/load.ts @@ -7,9 +7,12 @@ import { NuxtOptions } from '../types/config' import nuxtConfigSchema from './schema' export interface LoadNuxtConfigOptions { + /** Your project root directory (either absolute or relative to the current working directory). */ rootDir?: string + /** The path to your `nuxt.config` file (either absolute or relative to your project `rootDir`). */ configFile?: string - config?: any + /** Any overrides to your Nuxt configuration. */ + config?: Record } export function loadNuxtConfig (opts: LoadNuxtConfigOptions): NuxtOptions { diff --git a/packages/kit/src/config/schema/_app.ts b/packages/kit/src/config/schema/_app.ts index 3a2394302b..cfaec62297 100644 --- a/packages/kit/src/config/schema/_app.ts +++ b/packages/kit/src/config/schema/_app.ts @@ -4,16 +4,23 @@ import defu from 'defu' import { isRelative, joinURL, hasProtocol } from 'ufo' export default { - /** - * Vue.js configuration - */ + /** Vue.js config */ 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: { silent: { $resolve: (val, get) => val ?? get('dev') }, performance: { $resolve: (val, get) => val ?? get('dev') } } }, + /** + * Nuxt App configuration. + */ app: { $resolve: (val, get) => { 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 `/app.html` if it exists or the Nuxt default template if not. + * + * @example + * ```html + * + * + * + * {{ HEAD }} + * + * + * {{ APP }} + * + * + * ``` */ appTemplatePath: { $resolve: (val, get) => { @@ -41,6 +62,10 @@ export default { } }, + /** + * Enable or disable vuex store. + * By default is enbled if there is store / directory + */ store: { $resolve: (val, get) => val !== false && 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, + /** + * Set default configuration for `` on every page. + * + * @see [documentation](https://vue-meta.nuxtjs.org/api/#metainfo-properties) for specifics. + */ head: { + /** Each item in the array maps to a newly-created element, where object properties map to attributes. */ meta: [], + /** Each item in the array maps to a newly-created element, where object properties map to attributes. */ link: [], + /** Each item in the array maps to a newly-created + * ``` + */ alias: { $resolve: (val, get) => ({ '~~': 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, + + /** + * Any file in `pages/`, `layouts/`, `middleware/` or `store/` will be ignored during + * building if its filename starts with the prefix specified by `ignorePrefix`. + */ ignorePrefix: '-', + + /** + * More customizable than `ignorePrefix`: all files matching glob patterns specified + * inside the `ignore` array will be ignored in building. + */ ignore: { $resolve: (val, get) => [ '**/*.test.*', @@ -134,28 +486,135 @@ export default { ].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: { $resolve: (val, get) => [].concat(val, get('_nuxtConfigFiles')).filter(Boolean) }, + /** + * The watchers property lets you overwrite watchers configuration in your `nuxt.config`. + */ watchers: { + /** An array of event types, which, when received, will cause the watcher to restart. */ rewatchOnRawEvents: undefined, + /** + * `watchOptions` to pass directly to webpack. + * + * @see [webpack@4 watch options](https://v4.webpack.js.org/configuration/watch/#watchoptions). + * */ webpack: { aggregateTimeout: 1000 }, + /** + * Options to pass directly to `chokidar`. + * + * @see [chokidar](https://github.com/paulmillr/chokidar#api) + */ chokidar: { ignoreInitial: true } }, + /** + * Your preferred code editor to launch when debugging. + * + * @see [documentation](https://github.com/yyx990803/launch-editor#supported-editors) + */ 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, + /** + * 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: {}, + + /** + * 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: { app: { $resolve: (val, get) => ({ ...get('app'), ...(val || {}) }) } - } + }, + + /** + * Enable vite mode. + */ + vite: false } diff --git a/packages/kit/src/config/schema/_internal.ts b/packages/kit/src/config/schema/_internal.ts index ffe161a3a9..2f8a4913f5 100644 --- a/packages/kit/src/config/schema/_internal.ts +++ b/packages/kit/src/config/schema/_internal.ts @@ -1,13 +1,22 @@ export default { + /** @private */ _majorVersion: 2, + /** @private */ _legacyGenerate: false, + /** @private */ _start: false, + /** @private */ _build: false, + /** @private */ _generate: false, + /** @private */ _cli: false, + /** @private */ _requiredModules: {}, + /** @private */ _nuxtConfigFile: undefined, + /** @private */ _nuxtConfigFiles: [], - appDir: '', - vite: false + /** @private */ + appDir: '' } diff --git a/packages/kit/src/config/schema/build.ts b/packages/kit/src/config/schema/build.ts index b31302a5b8..015850012a 100644 --- a/packages/kit/src/config/schema/build.ts +++ b/packages/kit/src/config/schema/build.ts @@ -2,26 +2,171 @@ import env from 'std-env' import { hasProtocol } from 'ufo' 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), + + /** + * 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, + + /** + * 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'), + + /** + * 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, + + /** + * Enables CSS source map support (defaults to true in development) + */ cssSourceMap: { $resolve: (val, get) => val ?? get('dev') }, + + /** + * Creates special webpack bundle for SSR renderer. It is normally not necessary to change this value. + */ 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: { $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, + + /** + * 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, + + /** + * 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: { $resolve: (val, get) => { if (hasProtocol(val, true) && get('dev')) { val = null } 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', + + /** + * 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: { 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`, @@ -30,6 +175,10 @@ export default { font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[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: { $resolve: (val, get) => { const styleLoaders = [ @@ -78,17 +227,72 @@ export default { stylus: {}, vueStyle: {} }, + + /** + * @deprecated Use [style-resources-module](https://github.com/nuxt-community/style-resources-module/) + */ styleResources: {}, + + /** + * Add webpack plugins. + * + * @example + * ```js + * import webpack from 'webpack' + * import { version } from './package.json' + * // ... + * plugins: [ + * new webpack.DefinePlugin({ + * 'process.VERSION': version + * }) + * ] + * ``` + */ 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: {}, + + /** + * Enables the [HardSourceWebpackPlugin](https://github.com/mzgoddard/hard-source-webpack-plugin) for improved caching. + * + * @warning unstable + */ hardSource: false, + + /** + * Hard-replaces `typeof process`, `typeof window` and `typeof document` to tree-shake bundle. + */ 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: { $resolve: (val, get) => val ?? (get('build.extractCSS') ? {} : false) }, + + /** + * Configure [webpack optimization](https://webpack.js.org/configuration/optimization/). + */ optimization: { runtimeChunk: 'single', + /** Set minimize to false to disable all minimizers. (It is disabled in development by default) */ minimize: { $resolve: (val, get) => val ?? get('dev') }, + /** You can set minimizer to a customized array of plugins. */ minimizer: undefined, splitChunks: { chunks: 'all', @@ -96,30 +300,126 @@ export default { cacheGroups: {} } }, + + /** + * Whether to split code for `layout`, `pages` and `commons` chunks. + * + * Commons libs include `vue`, `vue-loader`, `vue-router`, `vuex`, etc. + */ splitChunks: { layouts: false, pages: 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', + + /** + * 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: { configFile: 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: {}, cacheDirectory: { $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: { $resolve: val => [].concat(val).filter(Boolean) }, + + /** + * Customize PostCSS Loader plugins. + */ postcss: { preset: { // https://cssdb.org/#staging-process stage: 2 } }, + 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: { collapseBooleanAttributes: true, decodeEntities: true, @@ -133,13 +433,46 @@ export default { } }, + /** Allows setting a different app template (other than `@nuxt/vue-app`) */ 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: [], + /** + * 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: [], + /** See [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) for available options. */ devMiddleware: { stats: 'none' }, + /** See [webpack-hot-middleware](https://github.com/webpack-contrib/webpack-hot-middleware) for available options. */ hotMiddleware: {}, vendor: { @@ -148,17 +481,22 @@ export default { } }, + /** Set to `'none'` or `false` to disable stats printing out after a build. */ stats: { - $resolve: (val, get) => (val === 'none' || get('build.quite')) ? false : val, + $resolve: (val, get) => (val === 'none' || get('build.quiet')) ? false : val, excludeAssets: [ /.map$/, /index\..+\.html$/, /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, + /** Additional extensions (beyond `['vue', 'js']` to support in `pages/`, `layouts/`, `middleware/`, etc.) */ additionalExtensions: [], + /** Filters to hide build warnings. */ warningIgnoreFilters: [], + /** Set to true to scan files within symlinks in the build (such as within `pages/`). */ followSymlinks: false } diff --git a/packages/kit/src/config/schema/cli.ts b/packages/kit/src/config/schema/cli.ts index 0e79115bd1..d3bef5179b 100644 --- a/packages/kit/src/config/schema/cli.ts +++ b/packages/kit/src/config/schema/cli.ts @@ -1,4 +1,11 @@ export default { + /** + * Add a message to the CLI banner by adding a string to this array. + */ badgeMessages: [], + + /** + * Change the color of the 'Nuxt.js' title in the CLI banner. + */ bannerColor: 'green' } diff --git a/packages/kit/src/config/schema/generate.ts b/packages/kit/src/config/schema/generate.ts index a9caa545ba..f7962361ce 100644 --- a/packages/kit/src/config/schema/generate.ts +++ b/packages/kit/src/config/schema/generate.ts @@ -2,28 +2,153 @@ import { resolve } from 'path' import { joinURL } from 'ufo' export default { + /** + * Directory name that holds all the assets and generated pages for a `static` build. + */ dir: { $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: [], + + /** + * 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: [], + + /** The number of routes that are generated concurrently in the same thread. */ concurrency: 500, + + /** + * Interval in milliseconds between two render cycles to avoid flooding a potential + * API with calls. + */ 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, + + /** + * 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') }, + + /** + * Set to `false` to disable generating pages discovered through crawling relative + * links in generated pages. + */ crawler: true, + + /** Set to `false` to disable generating a `manifest.js` with a list of all generated pages. */ manifest: true, + + /** Set to `false` to disable generating a `.nojekyll` file (which aids compatibility with GitHub Pages). */ nojekyll: true, + + /** + * Configure the cache (used with `static` target to avoid rebuilding when no files have changed). + * + * Set to `false` to disable completely. + */ cache: { + /** An array of files or directories to ignore. (It can also be a function that returns an array.) */ ignore: [], + /** + * Options to pass to [`globby`](https://github.com/sindresorhus/globby), which + * is used to generate a 'snapshot' of the source files. + */ globbyOptions: { gitignore: true } }, + staticAssets: { + /** The directory underneath `/_nuxt/`, where static assets (payload, state and manifest files) will live. */ 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')) }, + /** 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')) }, + /** A unique string to uniquely identify payload versions (defaults to the current timestamp). */ version: { $resolve: val => val || (String(Math.round(Date.now() / 1000))) } } } diff --git a/packages/kit/src/config/schema/messages.ts b/packages/kit/src/config/schema/messages.ts index ad1ff51de1..530740137d 100644 --- a/packages/kit/src/config/schema/messages.ts +++ b/packages/kit/src/config/schema/messages.ts @@ -1,10 +1,18 @@ export default { + /** The text that displays on the Nuxt loading indicator when `ssr: false`. */ loading: 'Loading...', + /** The 404 text on the default Nuxt error page. */ 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', + /** The text (linked to nuxtjs.org) that appears on the built-in Nuxt error page. */ 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', + /** 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.', + /** The default error title (if there isn't a specific error message) on the built-in Nuxt error page. */ 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.' } diff --git a/packages/kit/src/config/schema/render.ts b/packages/kit/src/config/schema/render.ts index 2c09cfc65b..4bdfada308 100644 --- a/packages/kit/src/config/schema/render.ts +++ b/packages/kit/src/config/schema/render.ts @@ -1,52 +1,269 @@ 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: { shouldPrefetch: () => false, shouldPreload: (_fileWithoutQuery, asType) => ['script', 'style'].includes(asType), - /** - * enabled by default for development - */ + /** enabled by default for development */ runInNewContext: { $resolve: (val, get) => val ?? get('dev') } }, + + /** + * Configure the crossorigin attribute on `` and `