import { join, resolve } from 'pathe' import { isDevelopment } from 'std-env' import createRequire from 'create-require' import { pascalCase } from 'scule' import jiti from 'jiti' import defu from 'defu' import { findWorkspaceDir } from 'pkg-types' import { RuntimeConfig } from '../types/config' import { defineUntypedSchema } from 'untyped' export default defineUntypedSchema({ /** * Extend project from multiple local or remote sources. * * Value should be either a string or array of strings pointing to source directories or config path relative to current config. * * You can use `github:`, `gitlab:`, `bitbucket:` or `https://` to extend from a remote git repository. * * @type {string|string[]} * * @version 3 */ extends: null, /** * Extend project from a local or remote source. * * Value should be a string pointing to source directory or config path relative to current config. * * You can use `github:`, `gitlab:`, `bitbucket:` or `https://` to extend from a remote git repository. * * @type {string} * * @version 3 */ theme: null, /** * Define the root 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. * @version 2 * @version 3 */ rootDir: { $resolve: val => typeof val === 'string' ? resolve(val) : process.cwd() }, /** * Define the workspace directory of your application. * * Often this is used when in a monorepo setup. Nuxt will attempt to detect * your workspace directory automatically, but you can override it here. * * It is normally not needed to configure this option. * @version 3 */ workspaceDir: { $resolve: async (val, get) => val ? resolve(await get('rootDir'), val) : await findWorkspaceDir(await get('rootDir')).catch(() => get('rootDir')) }, /** * 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/ * ``` * @version 2 * @version 3 */ srcDir: { $resolve: async (val, get) => resolve(await 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' * } * ``` * @version 2 * @version 3 */ buildDir: { $resolve: async (val, get) => resolve(await get('rootDir'), val || '.nuxt') }, /** * Whether Nuxt is running in development mode. * * Normally, you should not need to set this. * @version 2 * @version 3 */ dev: Boolean(isDevelopment), /** * Whether your app is being unit tested. * @version 2 */ test: Boolean(isDevelopment), /** * Set to `true` to enable debug mode. * * By default, it's only enabled in development mode. * @version 2 */ debug: { $resolve: async (val, get) => val ?? await 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. * * @version 2 */ env: { $default: {}, $resolve: (val) => { val = { ...val } for (const key in process.env) { if (key.startsWith('NUXT_ENV_')) { val[key] = process.env[key] } } return val } }, /** * 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) * @type {'jiti' | 'native' | ((p: string | { filename: string }) => NodeRequire)} * @version 2 */ createRequire: { $resolve: (val: any) => { val = process.env.NUXT_CREATE_REQUIRE || val || // @ts-expect-error global type (typeof globalThis.jest !== 'undefined' ? 'native' : 'jiti') if (val === 'jiti') { return (p: string | { filename: string }) => jiti(typeof p === 'string' ? p : p.filename, { esmResolve: true }) } if (val === 'native') { return (p: string | { filename: string }) => createRequire(typeof p === 'string' ? p : p.filename) } return val } }, /** * 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`. * @type {'server' | 'static'} * @version 2 */ target: { $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. * @version 2 * @version 3 */ ssr: { $resolve: (val) => val ?? true, }, /** * @deprecated use `ssr` option */ mode: { $resolve: async (val, get) => val || ((await get('ssr')) ? 'spa' : 'universal'), $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 ` * * * ``` * * @type {Record} * @version 2 * @version 3 */ alias: { $resolve: async (val, get) => ({ '~~': await get('rootDir'), '@@': await get('rootDir'), '~': await get('srcDir'), '@': await get('srcDir'), [await get('dir.assets')]: join(await get('srcDir'), await get('dir.assets')), [await get('dir.public')]: join(await get('srcDir'), await get('dir.public')), ...val }) }, /** * 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 * } * ``` * @version 2 * @version 3 */ 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`. * @version 2 * @version 3 */ ignorePrefix: '-', /** * More customizable than `ignorePrefix`: all files matching glob patterns specified * inside the `ignore` array will be ignored in building. * @version 2 * @version 3 */ ignore: { $resolve: async (val, get) => [ '**/*.stories.{js,ts,jsx,tsx}', // ignore storybook files '**/*.{spec,test}.{js,ts,jsx,tsx}', // ignore tests '.output', await get('ignorePrefix') && `**/${await get('ignorePrefix')}*.*` ].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'] * ``` * @type {string[]} * @version 2 */ watch: { $resolve: async (val, get) => { const rootDir = await get('rootDir') return Array.from(new Set([].concat(val, await get('_nuxtConfigFiles')) .filter(Boolean).map(p => resolve(rootDir, p)) )) } }, /** * The watchers property lets you overwrite watchers configuration in your `nuxt.config`. * @version 2 * @version 3 */ 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) * @type {string} * @version 2 */ 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'node:fs' * import fs from 'node:fs' * import path from 'node:path' * export default { * hooks: { * build: { * done(builder) { * const extraFilePath = path.join( * builder.nuxt.options.buildDir, * 'extra-file' * ) * fs.writeFileSync(extraFilePath, 'Something extra') * } * } * } * } * ``` * @version 2 * @version 3 * @type {typeof import('../src/types/hooks').NuxtHooks} */ hooks: null, /** * Runtime config allows passing dynamic config and environment variables to the Nuxt app context. * * The value of this object is accessible from server only using `useRuntimeConfig`. * * It mainly should hold _private_ configuration which is not exposed on the frontend. * This could include a reference to your API secret tokens. * * Anything under `public` and `app` will be exposed to the frontend as well. * * Values are automatically replaced by matching env variables at runtime, e.g. setting an environment * variable `NUXT_API_KEY=my-api-key NUXT_PUBLIC_BASE_URL=/foo/` would overwrite the two values in the example below. * * @example * ```js * export default { * runtimeConfig: { * apiKey: '' // Default to an empty string, automatically set at runtime using process.env.NUXT_API_KEY * public: { * baseURL: '' // Exposed to the frontend as well. * } * } * } * ``` * @type {typeof import('../src/types/config').RuntimeConfig} * @version 3 */ runtimeConfig: { $resolve: async (val: RuntimeConfig, get) => defu(val, { ...await get('publicRuntimeConfig'), ...await get('privateRuntimeConfig'), public: await get('publicRuntimeConfig'), app: { baseURL: (await get('app')).baseURL, buildAssetsDir: (await get('app')).buildAssetsDir, cdnURL: (await get('app')).cdnURL, } }) }, /** * @type {typeof import('../src/types/config').PrivateRuntimeConfig} * @version 2 * @version 3 * @deprecated Use `runtimeConfig` option. */ privateRuntimeConfig: {}, /** * @type {typeof import('../src/types/config').PublicRuntimeConfig} * @version 2 * @version 3 * @deprecated Use `runtimeConfig` option with `public` key (`runtimeConfig.public.*`). */ publicRuntimeConfig: {}, /** * Additional app configuration * * For programmatic usage and type support, you can directly provide app config with this option. * It will be merged with `app.config` file as default value. * * @type {typeof import('../src/types/config').AppConfig} * @version 3 */ appConfig: {}, })