chore: cleanup eslint rules with latest `@nuxt/eslint-config` (#26653)

This commit is contained in:
Anthony Fu 2024-04-05 20:08:32 +02:00 committed by GitHub
parent ee608cea2c
commit f209158352
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
357 changed files with 2713 additions and 2952 deletions

2
.gitignore vendored
View File

@ -73,3 +73,5 @@ Temporary Items
fixtures-temp
.pnpm-store
eslint-typegen.d.ts
.eslintcache

View File

@ -1,280 +1,215 @@
// Configs
// import standard from "eslint-config-standard"
// import nuxt from '@nuxt/eslint-config'
// Plugins
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import jsdoc from 'eslint-plugin-jsdoc'
import esImport from 'eslint-plugin-import'
import unicorn from 'eslint-plugin-unicorn'
// @ts-check
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
// @ts-expect-error missing types
import noOnlyTests from 'eslint-plugin-no-only-tests'
import typegen from 'eslint-typegen'
// @ts-expect-error missing types
import perfectionist from 'eslint-plugin-perfectionist'
/**
* eslintrc compatibility
* @see https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config
* @see https://github.com/eslint/eslintrc#usage-esm
*/
import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended
export default createConfigForNuxt({
features: {
stylistic: {
commaDangle: 'always-multiline',
},
tooling: true,
},
})
// TODO: Type definition?
export default [
.prepend(
{
// Ignores have to be a separate object to be treated as global ignores
// Don't add other attributes to this object
ignores: [
'**/dist/**',
'**/.nuxt/**',
'**/.nuxt-*/**',
'**/.output/**',
'**/.output-*/**',
'**/public/**',
'**/node_modules/**',
'packages/schema/schema',
// TODO: remove when fully migrated to flat config
'**/*.d.mts'
]
},
// standard,
...compat.extends('eslint-config-standard'),
jsdoc.configs['flat/recommended'],
// nuxt,
...compat.extends('@nuxt/eslint-config'),
esImport.configs.typescript,
{
rules: {
'import/export': 'off'
}
'packages/schema/schema/**',
],
},
{
files: ['**/*.vue', '**/*.ts', '**/*.mts', '**/*.js', '**/*.cjs', '**/*.mjs'],
languageOptions: {
globals: {
$fetch: 'readonly',
NodeJS: 'readonly',
$fetch: 'readonly'
}
},
plugins: {
jsdoc,
import: esImport,
unicorn,
'no-only-tests': noOnlyTests
},
name: 'local/settings',
settings: {
jsdoc: {
ignoreInternal: true,
tagNamePreference: {
note: 'note',
warning: 'warning',
},
},
},
},
)
.override('nuxt/javascript', {
rules: {
// Imports should come first
'import/first': 'error',
// Other import rules
'import/no-mutable-exports': 'error',
// Allow unresolved imports
'import/no-unresolved': 'off',
// Allow paren-less arrow functions only when there's no braces
'arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }],
// Allow async-await
'generator-star-spacing': 'off',
// Prefer const over let
'prefer-const': ['error', { destructuring: 'any', ignoreReadBeforeAssign: false }],
// No single if in an "else" block
'no-lonely-if': 'error',
// Force curly braces for control flow,
// including if blocks with a single statement
curly: ['error', 'all'],
// No async function without await
'require-await': 'error',
// Force dot notation when possible
'curly': ['error', 'all'], // Including if blocks with a single statement
'dot-notation': 'error',
'no-var': 'error',
// Force object shorthand where possible
'object-shorthand': 'error',
// No useless destructuring/importing/exporting renames
'no-useless-rename': 'error',
/**********************/
/* Unicorn Rules */
/**********************/
// Pass error message when throwing errors
'unicorn/error-message': 'error',
// Uppercase regex escapes
'unicorn/escape-case': 'error',
// Array.isArray instead of instanceof
'unicorn/no-array-instanceof': 'error',
// Prevent deprecated `new Buffer()`
'unicorn/no-new-buffer': 'error',
// Keep regex literals safe!
'unicorn/no-unsafe-regex': 'off',
// Lowercase number formatting for octal, hex, binary (0x12 instead of 0X12)
'unicorn/number-literal-case': 'error',
// ** instead of Math.pow()
'unicorn/prefer-exponentiation-operator': 'error',
// includes over indexOf when checking for existence
'unicorn/prefer-includes': 'error',
// String methods startsWith/endsWith instead of more complicated stuff
'unicorn/prefer-starts-ends-with': 'error',
// textContent instead of innerText
'unicorn/prefer-text-content': 'error',
// Enforce throwing type error when throwing error while checking typeof
'unicorn/prefer-type-error': 'error',
// Use new when throwing error
'unicorn/throw-new-error': 'error',
'sort-imports': [
'error',
{
ignoreDeclarationSort: true
}
],
'no-only-tests/no-only-tests': 'error',
'unicorn/prefer-node-protocol': 'error',
'no-console': ['warn', { allow: ['warn', 'error', 'debug'] }],
'vue/one-component-per-file': 'off',
'vue/require-default-prop': 'off',
'no-lonely-if': 'error', // No single if in an "else" block
'no-useless-rename': 'error',
'object-shorthand': 'error',
'prefer-const': ['error', { destructuring: 'any', ignoreReadBeforeAssign: false }],
'require-await': 'error',
'sort-imports': ['error', { ignoreDeclarationSort: true }],
},
})
// Vue stylistic rules from `@antfu/eslint-config`
'vue/array-bracket-spacing': ['error', 'never'],
'vue/arrow-spacing': ['error', { after: true, before: true }],
'vue/block-spacing': ['error', 'always'],
'vue/block-tag-newline': [
.override('nuxt/typescript/rules', {
rules: {
'@typescript-eslint/ban-ts-comment': [
'error',
{
multiline: 'always',
singleline: 'always'
}
'ts-expect-error': 'allow-with-description',
'ts-ignore': true,
},
],
'vue/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'vue/comma-dangle': ['error', 'always-multiline'],
'vue/comma-spacing': ['error', { after: true, before: false }],
'vue/comma-style': ['error', 'last'],
'vue/html-comment-content-spacing': [
'@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
'always',
{
exceptions: ['-']
}
argsIgnorePattern: '^_',
ignoreRestSiblings: true,
varsIgnorePattern: '^_',
},
],
'vue/key-spacing': ['error', { afterColon: true, beforeColon: false }],
'vue/keyword-spacing': ['error', { after: true, before: true }],
'vue/object-curly-newline': 'off',
'vue/object-curly-spacing': ['error', 'always'],
'vue/object-property-newline': [
'error',
{ allowMultiplePropertiesPerLine: true }
],
'vue/operator-linebreak': ['error', 'before'],
'vue/padding-line-between-blocks': ['error', 'always'],
'vue/quote-props': ['error', 'consistent-as-needed'],
'vue/space-in-parens': ['error', 'never'],
'vue/template-curly-spacing': 'error',
'@typescript-eslint/triple-slash-reference': 'off',
'@typescript-eslint/unified-signatures': 'off',
...{
// TODO: Discuss if we want to enable this
'@typescript-eslint/ban-types': 'off',
// TODO: Discuss if we want to enable this
'@typescript-eslint/no-explicit-any': 'off',
// TODO: Discuss if we want to enable this
'@typescript-eslint/no-invalid-void-type': 'off',
},
},
})
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-param-type': 'off',
'import/order': [
'error',
.override('nuxt/tooling/unicorn', {
rules: {
'unicorn/no-new-array': 'off',
'unicorn/prefer-dom-node-text-content': 'off',
},
})
.override('nuxt/vue/rules', {
rules: {
},
})
// Stylistic rules
.override('nuxt/stylistic', {
rules: {
'@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: true }],
'@stylistic/indent-binary-ops': 'off',
'@stylistic/max-statements-per-line': 'off',
'@stylistic/operator-linebreak': 'off',
'@stylistic/quote-props': ['error', 'consistent'],
'@stylistic/space-before-function-paren': ['error', 'always'],
},
})
// Append local rules
.append(
{
pathGroups: [
{
pattern: '#vue-router',
group: 'external'
}
]
}
],
files: ['**/*.vue', '**/*.ts', '**/*.mts', '**/*.js', '**/*.cjs', '**/*.mjs'],
name: 'local/rules',
rules: {
'import/no-restricted-paths': [
'error',
{
zones: [
{
from: 'packages/nuxt/src/!(core)/**/*',
message: 'core should not directly import from modules.',
target: 'packages/nuxt/src/core',
message: 'core should not directly import from modules.'
},
{
from: 'packages/nuxt/src/!(app)/**/*',
message: 'app should not directly import from modules.',
target: 'packages/nuxt/src/app',
message: 'app should not directly import from modules.'
},
{
from: 'packages/nuxt/src/app/**/index.ts',
message: 'should not import from barrel/index files',
target: 'packages/nuxt/src',
message: 'should not import from barrel/index files'
},
{
from: 'packages/nitro',
message: 'nitro should not directly import other packages.',
target: 'packages/!(nitro)/**/*',
message: 'nitro should not directly import other packages.'
}
]
}
},
],
'@typescript-eslint/consistent-type-imports': [
},
],
'import/order': [
'error',
{
disallowTypeAnnotations: false
}
],
'@typescript-eslint/ban-ts-comment': [
'error',
pathGroups: [
{
'ts-expect-error': 'allow-with-description',
'ts-ignore': true
}
group: 'external',
pattern: '#vue-router',
},
],
'@typescript-eslint/prefer-ts-expect-error': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true
}
},
],
'jsdoc/check-tag-names': [
'error',
{
definedTags: ['__NO_SIDE_EFFECTS__']
}
]
definedTags: [
'experimental',
'__NO_SIDE_EFFECTS__',
],
},
settings: {
jsdoc: {
ignoreInternal: true,
tagNamePreference: {
warning: 'warning',
note: 'note'
}
}
}
],
},
{
files: ['packages/schema/**'],
rules: {
'jsdoc/valid-types': 'off',
'jsdoc/check-tag-names': [
'error',
{
definedTags: ['experimental']
}
]
}
},
{
files: ['packages/nuxt/src/app/**', 'test/**', '**/runtime/**', '**/*.test.ts'],
name: 'local/disables/client-console',
rules: {
'no-console': 'off'
}
'no-console': 'off',
},
},
{
files: ['test/fixtures/**'],
files: ['**/fixtures/**', '**/fixture/**'],
name: 'local/disables/fixtures',
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'vue/valid-v-for': 'off'
}
}
]
'@typescript-eslint/triple-slash-reference': 'off',
'vue/multi-word-component-names': 'off',
'vue/valid-v-for': 'off',
},
},
{
files: ['test/**', '**/*.test.ts'],
name: 'local/disables/tests',
plugins: {
'no-only-tests': noOnlyTests,
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'no-console': 'off',
'no-only-tests/no-only-tests': 'error',
},
},
// Sort rule keys in eslint config
{
files: ['**/eslint.config.mjs'],
name: 'local/sort-eslint-config',
plugins: {
perfectionist,
},
rules: {
'perfectionist/sort-objects': 'error',
},
},
)
// Generate type definitions for the eslint config
.onResolved((configs) => {
return typegen(configs)
})

View File

@ -9,8 +9,8 @@ export default defineNuxtConfig({
function () {
addPluginTemplate({
filename: 'plugins/my-plugin.mjs',
getContents: () => 'export default defineNuxtPlugin({ name: \'my-plugin\' })'
getContents: () => 'export default defineNuxtPlugin({ name: \'my-plugin\' })',
})
}
]
},
],
})

View File

@ -13,8 +13,8 @@
"cleanup": "rimraf 'packages/**/node_modules' 'playground/node_modules' 'node_modules'",
"dev": "pnpm play",
"dev:prepare": "pnpm --filter './packages/**' prepack --stub",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint": "eslint . --cache",
"lint:fix": "eslint . --cache --fix",
"lint:docs": "markdownlint ./docs && case-police 'docs/**/*.md' *.md",
"lint:docs:fix": "markdownlint ./docs --fix && case-police 'docs/**/*.md' *.md --fix",
"lint:knip": "pnpx knip",
@ -44,13 +44,13 @@
"magic-string": "^0.30.9"
},
"devDependencies": {
"@eslint/eslintrc": "3.0.2",
"@eslint/js": "8.57.0",
"@nuxt/eslint-config": "0.2.0",
"@nuxt/eslint-config": "0.3.0",
"@nuxt/kit": "workspace:*",
"@nuxt/test-utils": "3.12.0",
"@nuxt/webpack-builder": "workspace:*",
"@testing-library/vue": "8.0.3",
"@types/eslint__js": "^8.42.3",
"@types/fs-extra": "11.0.4",
"@types/node": "20.12.4",
"@types/semver": "7.5.8",
@ -61,11 +61,9 @@
"consola": "3.2.3",
"devalue": "4.3.2",
"eslint": "8.57.0",
"eslint-config-standard": "17.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsdoc": "48.2.2",
"eslint-plugin-no-only-tests": "3.1.0",
"eslint-plugin-unicorn": "52.0.0",
"eslint-plugin-perfectionist": "^2.8.0",
"eslint-typegen": "^0.2.0",
"execa": "8.0.1",
"fs-extra": "11.2.0",
"globby": "14.0.1",

View File

@ -3,14 +3,14 @@ import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
declaration: true,
entries: [
'src/index'
'src/index',
],
externals: [
'@nuxt/schema',
'nitropack',
'webpack',
'vite',
'h3'
'h3',
],
failOnWarn: false
failOnWarn: false,
})

View File

@ -42,7 +42,7 @@ export interface ExtendViteConfigOptions extends ExtendConfigOptions {}
*/
export function extendWebpackConfig (
fn: ((config: WebpackConfig) => void),
options: ExtendWebpackConfigOptions = {}
options: ExtendWebpackConfigOptions = {},
) {
const nuxt = useNuxt()
@ -74,7 +74,7 @@ export function extendWebpackConfig (
*/
export function extendViteConfig (
fn: ((config: ViteConfig) => void),
options: ExtendViteConfigOptions = {}
options: ExtendViteConfigOptions = {},
) {
const nuxt = useNuxt()

View File

@ -18,7 +18,7 @@ export async function checkNuxtCompatibility (constraints: NuxtCompatibility, nu
if (!satisfies(normalizeSemanticVersion(nuxtVersion), constraints.nuxt, { includePrerelease: true })) {
issues.push({
name: 'nuxt',
message: `Nuxt version \`${constraints.nuxt}\` is required but currently using \`${nuxtVersion}\``
message: `Nuxt version \`${constraints.nuxt}\` is required but currently using \`${nuxtVersion}\``,
})
}
}
@ -30,12 +30,12 @@ export async function checkNuxtCompatibility (constraints: NuxtCompatibility, nu
if (bridgeRequirement === true && !hasBridge) {
issues.push({
name: 'bridge',
message: 'Nuxt bridge is required'
message: 'Nuxt bridge is required',
})
} else if (bridgeRequirement === false && hasBridge) {
issues.push({
name: 'bridge',
message: 'Nuxt bridge is not supported'
message: 'Nuxt bridge is not supported',
})
}
}

View File

@ -49,7 +49,7 @@ export async function addComponent (opts: AddComponentOptions) {
shortPath: opts.filePath,
priority: 0,
meta: {},
...opts
...opts,
}
nuxt.hook('components:extend', (components: Component[]) => {

View File

@ -5,7 +5,7 @@ describe('resolveGroupSyntax', () => {
it('should resolve single group syntax', () => {
expect(resolveGroupSyntax('**/*.{spec}.{js,ts}')).toStrictEqual([
'**/*.spec.js',
'**/*.spec.ts'
'**/*.spec.ts',
])
})
@ -14,13 +14,13 @@ describe('resolveGroupSyntax', () => {
'**/*.spec.js',
'**/*.spec.ts',
'**/*.test.js',
'**/*.test.ts'
'**/*.test.ts',
])
})
it('should do nothing with normal globs', () => {
expect(resolveGroupSyntax('**/*.spec.js')).toStrictEqual([
'**/*.spec.js'
'**/*.spec.js',
])
})
})

View File

@ -30,7 +30,7 @@ export {
requireModule,
importModule,
tryImportModule,
tryRequireModule
tryRequireModule,
} from './internal/cjs'
export type { ResolveModuleOptions, RequireModuleOptions } from './internal/cjs'
export { tryResolveModule } from './internal/esm'

View File

@ -66,14 +66,14 @@ export function getModulePaths (paths?: string[] | string) {
global.__NUXT_PREPATHS__,
paths || [],
process.cwd(),
global.__NUXT_PATHS__
global.__NUXT_PATHS__,
).filter(Boolean) as string[]
}
/** @deprecated Do not use CJS utils */
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
return normalize(_require.resolve(id, {
paths: getModulePaths(opts.paths)
paths: getModulePaths(opts.paths),
}))
}

View File

@ -9,7 +9,7 @@ import { toArray } from '../utils'
/** @deprecated */
// TODO: Remove support for compiling ejs templates in v4
export async function compileTemplate <T> (template: NuxtTemplate<T>, ctx: any) {
export async function compileTemplate<T> (template: NuxtTemplate<T>, ctx: any) {
const data = { ...ctx, options: template.options }
if (template.src) {
try {

View File

@ -16,7 +16,7 @@ export function addLayout (this: any, template: NuxtTemplate | string, name?: st
const layout = (nuxt.options as any).layouts[layoutName]
if (layout) {
return logger.warn(
`Not overriding \`${layoutName}\` (provided by \`${layout}\`) with \`${src || filename}\`.`
`Not overriding \`${layoutName}\` (provided by \`${layout}\`) with \`${src || filename}\`.`,
)
}
(nuxt.options as any).layouts[layoutName] = `./${filename}`
@ -31,12 +31,12 @@ export function addLayout (this: any, template: NuxtTemplate | string, name?: st
if (layoutName in app.layouts) {
const relativePath = relative(nuxt.options.srcDir, app.layouts[layoutName].file)
return logger.warn(
`Not overriding \`${layoutName}\` (provided by \`~/${relativePath}\`) with \`${src || filename}\`.`
`Not overriding \`${layoutName}\` (provided by \`~/${relativePath}\`) with \`${src || filename}\`.`,
)
}
app.layouts[layoutName] = {
file: join('#build', filename),
name: layoutName
name: layoutName,
}
})
}

View File

@ -17,7 +17,7 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
extend: { extendKey: ['theme', 'extends'] },
dotenv: true,
globalRc: true,
...opts
...opts,
})
delete (globalThis as any).defineNuxtConfig
const { configFile, layers = [], cwd } = result
@ -45,8 +45,8 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
cwd,
config: {
rootDir: cwd,
srcDir: cwd
}
srcDir: cwd,
},
})
}

View File

@ -33,7 +33,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
throw new Error(`Cannot find any nuxt version from ${opts.cwd}`)
}
const pkg = await readPackageJSON(nearestNuxtPkg)
const majorVersion = pkg.version ? parseInt(pkg.version.split('.')[0]) : ''
const majorVersion = pkg.version ? Number.parseInt(pkg.version.split('.')[0]) : ''
const rootDir = pathToFileURL(opts.cwd || process.cwd()).href
@ -51,7 +51,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
for: opts.dev ? 'dev' : 'build',
configOverrides: opts.overrides,
ready: opts.ready,
envConfig: opts.dotenv // TODO: Backward format conversion
envConfig: opts.dotenv, // TODO: Backward format conversion
})
// Mock new hookable methods

View File

@ -10,21 +10,21 @@ describe('nuxt module compatibility', () => {
modules: [
defineNuxtModule({
meta: {
name: 'nuxt-module-foo'
}
name: 'nuxt-module-foo',
},
}),
[
defineNuxtModule({
meta: {
name: 'module-instance-with-options'
}
name: 'module-instance-with-options',
},
}),
{
foo: 'bar'
}
]
]
}
foo: 'bar',
},
],
],
},
})
expect(hasNuxtModule('nuxt-module-foo', nuxt)).toStrictEqual(true)
expect(hasNuxtModule('module-instance-with-options', nuxt)).toStrictEqual(true)
@ -35,8 +35,8 @@ describe('nuxt module compatibility', () => {
const module = defineNuxtModule({
meta: {
name: 'nuxt-module-foo',
version: '1.0.0'
}
version: '1.0.0',
},
})
expect(await getNuxtModuleVersion(module, nuxt)).toEqual('1.0.0')
await nuxt.close()
@ -46,8 +46,8 @@ describe('nuxt module compatibility', () => {
const module = defineNuxtModule({
meta: {
name: 'nuxt-module-foo',
version: '1.0.0'
}
version: '1.0.0',
},
})
expect(await hasNuxtModuleCompatibility(module, '^1.0.0', nuxt)).toStrictEqual(true)
expect(await hasNuxtModuleCompatibility(module, '^2.0.0', nuxt)).toStrictEqual(false)

View File

@ -20,7 +20,7 @@ function resolveNuxtModuleEntryName (m: NuxtOptions['modules'][number]): string
* This will check both the installed modules and the modules to be installed. Note
* that it cannot detect if a module is _going to be_ installed programmatically by another module.
*/
export function hasNuxtModule (moduleName: string, nuxt: Nuxt = useNuxt()) : boolean {
export function hasNuxtModule (moduleName: string, nuxt: Nuxt = useNuxt()): boolean {
// check installed modules
return nuxt.options._installedModules.some(({ meta }) => meta.name === moduleName) ||
// check modules to be installed
@ -36,7 +36,7 @@ export async function hasNuxtModuleCompatibility (module: string | NuxtModule, s
return false
}
return satisfies(normalizeSemanticVersion(version), semverVersion, {
includePrerelease: true
includePrerelease: true,
})
}

View File

@ -89,8 +89,8 @@ export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: Mo
// Return module install result
return defu(res, <ModuleSetupReturn> {
timings: {
setup: setupTime
}
setup: setupTime,
},
})
}
@ -138,10 +138,10 @@ function nuxt2Shims (nuxt: Nuxt) {
plugins: nuxt.options.plugins,
templates: [
...templates.templatesFiles,
...virtualTemplates
...virtualTemplates,
],
templateVars: templates.templateVars
}
templateVars: templates.templateVars,
},
}
for await (const template of virtualTemplates) {
const contents = await compileTemplate({ ...template, src: '' }, context)

View File

@ -46,7 +46,7 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
nuxt.options._installedModules.push({
meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
timings: res.timings,
entryPath: typeof moduleToInstall === 'string' ? resolveAlias(moduleToInstall) : undefined
entryPath: typeof moduleToInstall === 'string' ? resolveAlias(moduleToInstall) : undefined,
})
}

View File

@ -14,7 +14,7 @@ function normalizeHandlerMethod (handler: NitroEventHandler) {
return {
method,
...handler,
handler: normalize(handler.handler)
handler: normalize(handler.handler),
}
}

View File

@ -127,7 +127,7 @@ export function createResolver (base: string | URL): Resolver {
return {
resolve: (...path) => resolve(base as string, ...path),
resolvePath: (path, opts) => resolvePath(path, { cwd: base as string, ...opts })
resolvePath: (path, opts) => resolvePath(path, { cwd: base as string, ...opts }),
}
}

View File

@ -119,7 +119,7 @@ export async function _generateTypes (nuxt: Nuxt) {
const modulePaths = await resolveNuxtModule(rootDirWithSlash,
nuxt.options._installedModules
.filter(m => m.entryPath)
.map(m => getDirectory(m.entryPath))
.map(m => getDirectory(m.entryPath)),
)
const tsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, {
@ -142,7 +142,7 @@ export async function _generateTypes (nuxt: Nuxt) {
noEmit: true,
resolveJsonModule: true,
allowSyntheticDefaultImports: true,
paths: {}
paths: {},
},
include: [
'./nuxt.d.ts',
@ -153,19 +153,19 @@ export async function _generateTypes (nuxt: Nuxt) {
.filter(srcOrCwd => !srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes('node_modules'))
.map(srcOrCwd => join(relative(nuxt.options.buildDir, srcOrCwd), '**/*')),
...nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : [],
...modulePaths.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime'))
...modulePaths.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime')),
],
exclude: [
...nuxt.options.modulesDir.map(m => relativeWithDot(nuxt.options.buildDir, m)),
...modulePaths.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime/server')),
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist'))
]
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist')),
],
} satisfies TSConfig)
const aliases: Record<string, string> = {
...nuxt.options.alias,
'#build': nuxt.options.buildDir
'#build': nuxt.options.buildDir,
}
// Exclude bridge alias types to support Volar
@ -215,7 +215,7 @@ export async function _generateTypes (nuxt: Nuxt) {
const references: TSReference[] = await Promise.all([
...nuxt.options.modules,
...nuxt.options._modules
...nuxt.options._modules,
]
.filter(f => typeof f === 'string')
.map(async id => ({ types: (await readPackageJSON(id, { url: nodeModulePaths }).catch(() => null))?.name || id })))
@ -246,12 +246,12 @@ export async function _generateTypes (nuxt: Nuxt) {
...declarations,
'',
'export {}',
''
'',
].join('\n')
return {
declaration,
tsConfig
tsConfig,
}
}

View File

@ -14,7 +14,7 @@ const mockNuxt = {
srcDir: '/my-app',
alias: {
'~': '/my-app',
'some-custom-alias': '/my-app/some-alias'
'some-custom-alias': '/my-app/some-alias',
},
typescript: { includeWorkspace: false },
buildDir: '/my-app/.nuxt',
@ -22,9 +22,9 @@ const mockNuxt = {
modules: [],
_layers: [{ config: { srcDir: '/my-app' } }],
_installedModules: [],
_modules: []
_modules: [],
},
callHook: () => {}
callHook: () => {},
} satisfies DeepPartial<Nuxt> as unknown as Nuxt
const mockNuxtWithOptions = (options: NuxtConfig) => defu({ options }, mockNuxt) as Nuxt
@ -49,7 +49,7 @@ describe('tsConfig generation', () => {
it('should add exclude for module paths', async () => {
const { tsConfig } = await _generateTypes(mockNuxtWithOptions({
modulesDir: ['/my-app/modules/test/node_modules', '/my-app/modules/node_modules', '/my-app/node_modules/@some/module/node_modules']
modulesDir: ['/my-app/modules/test/node_modules', '/my-app/modules/node_modules', '/my-app/node_modules/@some/module/node_modules'],
}))
expect(tsConfig.exclude).toMatchInlineSnapshot(`
[

View File

@ -9,7 +9,7 @@ const fixtures = {
'basic test fixture': 'test/fixtures/basic',
'basic test fixture (types)': 'test/fixtures/basic-types',
'minimal test fixture': 'test/fixtures/minimal',
'minimal test fixture (types)': 'test/fixtures/minimal-types'
'minimal test fixture (types)': 'test/fixtures/minimal-types',
}
describe('loadNuxtConfig', () => {

View File

@ -13,23 +13,23 @@ export default defineBuildConfig({
'core',
'head',
'components',
'pages'
].map(name => ({ input: `src/${name}/runtime/`, outDir: `dist/${name}/runtime`, format: 'esm', ext: 'js' } as BuildEntry))
'pages',
].map(name => ({ input: `src/${name}/runtime/`, outDir: `dist/${name}/runtime`, format: 'esm', ext: 'js' } as BuildEntry)),
],
hooks: {
'mkdist:entry:options' (_ctx, _entry, mkdistOptions) {
mkdistOptions.addRelativeDeclarationExtensions = true
}
},
},
dependencies: [
'nuxi',
'vue-router',
'ofetch'
'ofetch',
],
externals: [
'nuxt',
'nuxt/schema',
'@vue/shared',
'@unhead/vue'
]
'@unhead/vue',
],
})

View File

@ -1,8 +1,7 @@
/* eslint-disable jsdoc/require-jsdoc */
function defineNuxtConfig (config) {
return config
}
module.exports = {
defineNuxtConfig
defineNuxtConfig,
}

View File

@ -1,5 +1,6 @@
import type { NuxtConfig } from 'nuxt/schema'
import type { ConfigLayerMeta, DefineConfig } from 'c12'
export { NuxtConfig } from 'nuxt/schema'
export interface DefineNuxtConfig extends DefineConfig<NuxtConfig, ConfigLayerMeta> {}

View File

@ -1,4 +1,3 @@
// eslint-disable-next-line import/export
export * from 'vue'
export const install = () => {}

View File

@ -6,7 +6,7 @@ export const requestIdleCallback: Window['requestIdleCallback'] = import.meta.se
const start = Date.now()
const idleDeadline = {
didTimeout: false,
timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
timeRemaining: () => Math.max(0, 50 - (Date.now() - start)),
}
return setTimeout(() => { cb(idleDeadline) }, 1)
}))

View File

@ -8,7 +8,7 @@ export const setInterval = import.meta.client
if (import.meta.dev) {
throw createError({
statusCode: 500,
message: intervalError
message: intervalError,
})
}

View File

@ -6,26 +6,26 @@ export default defineComponent({
inheritAttrs: false,
props: {
uid: {
type: String
type: String,
},
fallbackTag: {
type: String,
default: () => 'div'
default: () => 'div',
},
fallback: {
type: String,
default: () => ''
default: () => '',
},
placeholder: {
type: String
type: String,
},
placeholderTag: {
type: String
type: String,
},
keepFallback: {
type: Boolean,
default: () => false
}
default: () => false,
},
},
emits: ['ssr-error'],
setup (props, ctx) {
@ -49,5 +49,5 @@ export default defineComponent({
}
return ctx.slots.default?.()
}
}
},
})

View File

@ -1,6 +1,6 @@
import { defineComponent, getCurrentInstance, onErrorCaptured, ref } from 'vue'
import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
// eslint-disable-next-line
import { isPromise } from '@vue/shared'
import { useState } from '../composables/state'
import { useNuxtApp } from '../nuxt'
@ -11,31 +11,31 @@ const NuxtClientFallbackServer = defineComponent({
inheritAttrs: false,
props: {
uid: {
type: String
type: String,
},
fallbackTag: {
type: String,
default: () => 'div'
default: () => 'div',
},
fallback: {
type: String,
default: () => ''
default: () => '',
},
placeholder: {
type: String
type: String,
},
placeholderTag: {
type: String
type: String,
},
keepFallback: {
type: Boolean,
default: () => false
}
default: () => false,
},
},
emits: {
'ssr-error' (_error: unknown) {
return true
}
},
},
async setup (props, ctx) {
const vm = getCurrentInstance()
@ -86,7 +86,7 @@ const NuxtClientFallbackServer = defineComponent({
push(ctx.ssrVNodes.getBuffer())
push('<!--]-->')
}
}
},
})
export default NuxtClientFallbackServer

View File

@ -8,7 +8,7 @@ export const clientOnlySymbol: InjectionKey<boolean> = Symbol.for('nuxt:client-o
export default defineComponent({
name: 'ClientOnly',
inheritAttrs: false,
// eslint-disable-next-line vue/require-prop-types
props: ['fallback', 'placeholder', 'placeholderTag', 'fallbackTag'],
setup (_, { slots, attrs }) {
const mounted = ref(false)
@ -28,7 +28,7 @@ export default defineComponent({
const fallbackTag = props.fallbackTag || props.placeholderTag || 'span'
return createElementBlock(fallbackTag, attrs, fallbackStr)
}
}
},
})
const cache = new WeakMap()

View File

@ -7,5 +7,5 @@ export default defineComponent({
return () => props.slots.default?.()
}
return () => props.slots.fallback?.()
}
},
})

View File

@ -10,8 +10,8 @@ export default defineComponent({
props: {
context: {
type: Object as () => { name: string, props?: Record<string, any> },
required: true
}
required: true,
},
},
setup (props) {
const component = islandComponents[props.context.name] as ReturnType<typeof defineAsyncComponent>
@ -19,7 +19,7 @@ export default defineComponent({
if (!component) {
throw createError({
statusCode: 404,
statusMessage: `Island component not found: ${props.context.name}`
statusMessage: `Island component not found: ${props.context.name}`,
})
}
@ -28,5 +28,5 @@ export default defineComponent({
})
return () => createVNode(component || 'span', { ...props.context.props, 'data-island-uid': '' })
}
},
})

View File

@ -5,7 +5,7 @@ export default defineComponent({
emits: {
error (_error: unknown) {
return true
}
},
},
setup (_props, { slots, emit }) {
const error = ref<Error | null>(null)
@ -25,5 +25,5 @@ export default defineComponent({
}
return () => error.value ? slots.error?.({ error, clearError }) : slots.default?.()
}
},
})

View File

@ -6,7 +6,7 @@
import { defineAsyncComponent } from 'vue'
const props = defineProps({
error: Object
error: Object,
})
// Deliberately prevent reactive update when error is cleared
@ -26,7 +26,7 @@ const stacktrace = _error.stack
text,
internal: (line.includes('node_modules') && !line.includes('.cache')) ||
line.includes('internal') ||
line.includes('new Promise')
line.includes('new Promise'),
}
}).map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')
: ''

View File

@ -48,25 +48,25 @@ export default defineComponent({
props: {
name: {
type: String,
required: true
required: true,
},
lazy: Boolean,
props: {
type: Object,
default: () => undefined
default: () => undefined,
},
context: {
type: Object,
default: () => ({})
default: () => ({}),
},
source: {
type: String,
default: () => undefined
default: () => undefined,
},
dangerouslyLoadClientComponents: {
type: Boolean,
default: false
}
default: false,
},
},
emits: ['error'],
async setup (props, { slots, expose, emit }) {
@ -99,9 +99,9 @@ export default defineComponent({
...(import.meta.server && import.meta.prerender)
? {}
: { params: { ...props.context, props: props.props ? JSON.stringify(props.props) : undefined } },
result: toRevive
result: toRevive,
},
...result
...result,
}
}
@ -168,7 +168,7 @@ export default defineComponent({
// $fetch handles the app.baseURL in dev
const r = await eventFetch(withQuery(((import.meta.dev && import.meta.client) || props.source) ? url : joinURL(config.app.baseURL ?? '', url), {
...props.context,
props: props.props ? JSON.stringify(props.props) : undefined
props: props.props ? JSON.stringify(props.props) : undefined,
}))
const result = import.meta.server || !import.meta.dev ? await r.json() : (r as FetchResponse<NuxtIslandResponse>)._data
// TODO: support passing on more headers
@ -219,7 +219,7 @@ export default defineComponent({
}
expose({
refresh: () => fetchComponent(true)
refresh: () => fetchComponent(true),
})
if (import.meta.hot) {
@ -261,7 +261,7 @@ export default defineComponent({
teleports.push(createVNode(Teleport,
// use different selectors for even and odd teleportKey to force trigger the teleport
{ to: import.meta.client ? `${isKeyOdd ? 'div' : ''}[data-island-uid="${uid.value}"][data-island-slot="${slot}"]` : `uid=${uid.value};slot=${slot}` },
{ default: () => (payloads.slots?.[slot].props?.length ? payloads.slots[slot].props : [{}]).map((data: any) => slots[slot]?.(data)) })
{ default: () => (payloads.slots?.[slot].props?.length ? payloads.slots[slot].props : [{}]).map((data: any) => slots[slot]?.(data)) }),
)
}
}
@ -275,7 +275,7 @@ export default defineComponent({
replaced = replaced.replaceAll(`data-island-slot="${slot}">`, full => full + slots[slot])
}
teleports.push(createVNode(Teleport, { to: `uid=${uid.value};client=${id}` }, {
default: () => [createStaticVNode(replaced, 1)]
default: () => [createStaticVNode(replaced, 1)],
}))
}
}
@ -286,9 +286,9 @@ export default defineComponent({
// use different selectors for even and odd teleportKey to force trigger the teleport
const vnode = createVNode(Teleport, { to: `${isKeyOdd ? 'div' : ''}[data-island-uid='${uid.value}'][data-island-component="${id}"]` }, {
default: () => {
return [h(component, props, Object.fromEntries(Object.entries(slots || {}).map(([k, v]) => ([k, () => createStaticVNode(`<div style="display: contents" data-island-uid data-island-slot="${k}">${v}</div>`, 1)
return [h(component, props, Object.fromEntries(Object.entries(slots || {}).map(([k, v]) => ([k, () => createStaticVNode(`<div style="display: contents" data-island-uid data-island-slot="${k}">${v}</div>`, 1),
]))))]
}
},
})
teleports.push(vnode)
}
@ -297,8 +297,8 @@ export default defineComponent({
}
return h(Fragment, teleports)
}, _cache, 1)
}, _cache, 1),
]
}
}
},
})

View File

@ -2,7 +2,6 @@ import type { DefineComponent, MaybeRef, VNode } from 'vue'
import { Suspense, Transition, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from 'vue'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
// eslint-disable-next-line import/no-restricted-paths
import type { PageMeta } from '../../pages/runtime/composables'
import { useRoute, useRouter } from '../composables/router'
@ -23,7 +22,7 @@ const LayoutLoader = defineComponent({
inheritAttrs: false,
props: {
name: String,
layoutProps: Object
layoutProps: Object,
},
async setup (props, context) {
// This is a deliberate hack - this component must always be called with an explicit key to ensure
@ -32,7 +31,7 @@ const LayoutLoader = defineComponent({
const LayoutComponent = await layouts[props.name]().then((r: any) => r.default || r)
return () => h(LayoutComponent, props.layoutProps, context.slots)
}
},
})
export default defineComponent({
@ -41,12 +40,12 @@ export default defineComponent({
props: {
name: {
type: [String, Boolean, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout'],
default: null
default: null,
},
fallback: {
type: [String, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef<string> : PageMeta['layout'],
default: null
}
default: null,
},
},
setup (props, context) {
const nuxtApp = useNuxtApp()
@ -94,12 +93,12 @@ export default defineComponent({
key: layout.value || undefined,
name: layout.value,
shouldProvide: !props.name,
hasTransition: !!transitionProps
}, context.slots)
})
hasTransition: !!transitionProps,
}, context.slots),
}),
}).default()
}
}
},
}) as unknown as DefineComponent<{
name?: (unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout']) | undefined
}>
@ -109,17 +108,17 @@ const LayoutProvider = defineComponent({
inheritAttrs: false,
props: {
name: {
type: [String, Boolean] as unknown as () => string | false
type: [String, Boolean] as unknown as () => string | false,
},
layoutProps: {
type: Object
type: Object,
},
hasTransition: {
type: Boolean
type: Boolean,
},
shouldProvide: {
type: Boolean
}
type: Boolean,
},
},
setup (props, context) {
// Prevent reactivity when the page will be rerendered in a different suspense fork
@ -127,7 +126,7 @@ const LayoutProvider = defineComponent({
const name = props.name
if (props.shouldProvide) {
provide(LayoutMetaSymbol, {
isCurrent: (route: RouteLocationNormalizedLoaded) => name === (route.meta.layout ?? 'default')
isCurrent: (route: RouteLocationNormalizedLoaded) => name === (route.meta.layout ?? 'default'),
})
}
@ -159,7 +158,7 @@ const LayoutProvider = defineComponent({
vnode = h(
LayoutLoader,
{ key: name, layoutProps: props.layoutProps, name },
context.slots
context.slots,
)
return vnode
@ -168,8 +167,8 @@ const LayoutProvider = defineComponent({
return h(
LayoutLoader,
{ key: name, layoutProps: props.layoutProps, name },
context.slots
context.slots,
)
}
}
},
})

View File

@ -4,7 +4,7 @@ import type {
ComputedRef,
DefineComponent,
InjectionKey, PropType,
VNodeProps
VNodeProps,
} from 'vue'
import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue'
import type { RouteLocation, RouteLocationRaw, Router, RouterLinkProps } from '#vue-router'
@ -114,7 +114,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
const resolvedPath = {
...to,
name: undefined, // named routes would otherwise always override trailing slash behavior
path: applyTrailingSlashBehavior(path, options.trailingSlash)
path: applyTrailingSlashBehavior(path, options.trailingSlash),
}
return resolvedPath
@ -127,85 +127,85 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
to: {
type: [String, Object] as PropType<RouteLocationRaw>,
default: undefined,
required: false
required: false,
},
href: {
type: [String, Object] as PropType<RouteLocationRaw>,
default: undefined,
required: false
required: false,
},
// Attributes
target: {
type: String as PropType<NuxtLinkProps['target']>,
default: undefined,
required: false
required: false,
},
rel: {
type: String as PropType<NuxtLinkProps['rel']>,
default: undefined,
required: false
required: false,
},
noRel: {
type: Boolean as PropType<NuxtLinkProps['noRel']>,
default: undefined,
required: false
required: false,
},
// Prefetching
prefetch: {
type: Boolean as PropType<NuxtLinkProps['prefetch']>,
default: undefined,
required: false
required: false,
},
noPrefetch: {
type: Boolean as PropType<NuxtLinkProps['noPrefetch']>,
default: undefined,
required: false
required: false,
},
// Styling
activeClass: {
type: String as PropType<NuxtLinkProps['activeClass']>,
default: undefined,
required: false
required: false,
},
exactActiveClass: {
type: String as PropType<NuxtLinkProps['exactActiveClass']>,
default: undefined,
required: false
required: false,
},
prefetchedClass: {
type: String as PropType<NuxtLinkProps['prefetchedClass']>,
default: undefined,
required: false
required: false,
},
// Vue Router's `<RouterLink>` additional props
replace: {
type: Boolean as PropType<NuxtLinkProps['replace']>,
default: undefined,
required: false
required: false,
},
ariaCurrentValue: {
type: String as PropType<NuxtLinkProps['ariaCurrentValue']>,
default: undefined,
required: false
required: false,
},
// Edge cases handling
external: {
type: Boolean as PropType<NuxtLinkProps['external']>,
default: undefined,
required: false
required: false,
},
// Slot API
custom: {
type: Boolean as PropType<NuxtLinkProps['custom']>,
default: undefined,
required: false
}
required: false,
},
},
setup (props, { slots }) {
const router = useRouter()
@ -269,7 +269,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
const path = typeof to.value === 'string' ? to.value : router.resolve(to.value).fullPath
await Promise.all([
nuxtApp.hooks.callHook('link:prefetch', path).catch(() => {}),
!isExternal.value && preloadRouteComponents(to.value as string, router).catch(() => {})
!isExternal.value && preloadRouteComponents(to.value as string, router).catch(() => {}),
])
prefetched.value = true
})
@ -303,7 +303,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
exactActiveClass: props.exactActiveClass || options.exactActiveClass,
replace: props.replace,
ariaCurrentValue: props.ariaCurrentValue,
custom: props.custom
custom: props.custom,
}
// `custom` API cannot support fallthrough attributes as the slot
@ -319,7 +319,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
return h(
resolveComponent('RouterLink'),
routerLinkProps,
slots.default
slots.default,
)
}
@ -344,7 +344,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
* A fallback rel of `noopener noreferrer` is applied for external links or links that open in a new tab.
* This solves a reverse tabnapping security flaw in browsers pre-2021 as well as improving privacy.
*/
(isAbsoluteUrl.value || hasTarget.value) ? 'noopener noreferrer' : ''
(isAbsoluteUrl.value || hasTarget.value) ? 'noopener noreferrer' : '',
) || null
// https://router.vuejs.org/api/#custom
@ -372,20 +372,20 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
matched: [],
redirectedFrom: undefined,
meta: {},
href
href,
} satisfies RouteLocation & { href: string }
},
rel,
target,
isExternal: isExternal.value,
isActive: false,
isExactActive: false
isExactActive: false,
})
}
return h('a', { ref: el, href, rel, target }, slots.default?.())
}
}
},
}) as unknown as DefineComponent<NuxtLinkProps>
}
@ -441,7 +441,7 @@ function useObserver (): { observe: ObserveFn } | undefined {
}
const _observer = nuxtApp._observer = {
observe
observe,
}
return _observer

View File

@ -6,34 +6,34 @@ export default defineComponent({
props: {
throttle: {
type: Number,
default: 200
default: 200,
},
duration: {
type: Number,
default: 2000
default: 2000,
},
height: {
type: Number,
default: 3
default: 3,
},
color: {
type: [String, Boolean],
default: 'repeating-linear-gradient(to right,#00dc82 0%,#34cdfe 50%,#0047e1 100%)'
default: 'repeating-linear-gradient(to right,#00dc82 0%,#34cdfe 50%,#0047e1 100%)',
},
estimatedProgress: {
type: Function as unknown as () => (duration: number, elapsed: number) => number,
required: false
}
required: false,
},
},
setup (props, { slots, expose }) {
const { progress, isLoading, start, finish, clear } = useLoadingIndicator({
duration: props.duration,
throttle: props.throttle,
estimatedProgress: props.estimatedProgress
estimatedProgress: props.estimatedProgress,
})
expose({
progress, isLoading, start, finish, clear
progress, isLoading, start, finish, clear,
})
return () => h('div', {
@ -52,8 +52,8 @@ export default defineComponent({
transform: `scaleX(${progress.value}%)`,
transformOrigin: 'left',
transition: 'transform 0.1s, height 0.4s, opacity 0.4s',
zIndex: 999999
}
zIndex: 999999,
},
}, slots)
}
},
})

View File

@ -4,14 +4,14 @@ function renderStubMessage (name: string) {
throw createError({
fatal: true,
statusCode: 500,
statusMessage: `${name} is provided by @nuxt/image. Check your console to install it or run 'npx nuxi@latest module add @nuxt/image'`
statusMessage: `${name} is provided by @nuxt/image. Check your console to install it or run 'npx nuxi@latest module add @nuxt/image'`,
})
}
export const NuxtImg = {
setup: () => renderStubMessage('<NuxtImg>')
setup: () => renderStubMessage('<NuxtImg>'),
}
export const NuxtPicture = {
setup: () => renderStubMessage('<NuxtPicture>')
setup: () => renderStubMessage('<NuxtPicture>'),
}

View File

@ -5,7 +5,7 @@ import { useNuxtApp } from '../nuxt'
import { paths } from '#build/components-chunk'
type ExtendedComponent = Component & {
__file: string,
__file: string
__name: string
}
@ -21,11 +21,11 @@ export default defineComponent({
props: {
to: {
type: String,
required: true
required: true,
},
nuxtClient: {
type: Boolean,
default: false
default: false,
},
/**
* ONLY used in dev mode since we use build:manifest result in production
@ -33,8 +33,8 @@ export default defineComponent({
*/
rootDir: {
type: String,
default: null
}
default: null,
},
},
setup (props, { slots }) {
const nuxtApp = useNuxtApp()
@ -47,19 +47,19 @@ export default defineComponent({
return () => {
const slot = slots.default!()[0]
const slotType = (slot.type as ExtendedComponent)
const slotType = slot.type as ExtendedComponent
const name = (slotType.__name || slotType.name) as string
islandContext.components[props.to] = {
chunk: import.meta.dev ? '_nuxt/' + paths[name] : paths[name],
props: slot.props || {}
props: slot.props || {},
}
return [h('div', {
style: 'display: contents;',
'style': 'display: contents;',
'data-island-uid': '',
'data-island-component': props.to
'data-island-component': props.to,
}, []), h(Teleport, { to: props.to }, slot)]
}
}
},
})

View File

@ -12,14 +12,14 @@ export default defineComponent({
props: {
name: {
type: String,
required: true
required: true,
},
/**
* must be an array to handle v-for
*/
props: {
type: Object as () => Array<any>
}
type: Object as () => Array<any>,
},
},
setup (props, { slots }) {
const nuxtApp = useNuxtApp()
@ -30,7 +30,7 @@ export default defineComponent({
const componentName = inject(NuxtTeleportIslandSymbol, false)
islandContext.slots[props.name] = {
props: (props.props || []) as unknown[]
props: (props.props || []) as unknown[],
}
return () => {
@ -38,18 +38,18 @@ export default defineComponent({
if (nuxtApp.ssrContext?.islandContext && slots.default) {
vnodes.push(h('div', {
style: 'display: contents;',
'style': 'display: contents;',
'data-island-uid': '',
'data-island-slot': props.name
'data-island-slot': props.name,
}, {
// Teleport in slot to not be hydrated client-side with the staticVNode
default: () => [createVNode(Teleport, { to: `island-slot=${componentName};${props.name}` }, slots.default?.())]
default: () => [createVNode(Teleport, { to: `island-slot=${componentName};${props.name}` }, slots.default?.())],
}))
} else {
vnodes.push(h('div', {
style: 'display: contents;',
'style': 'display: contents;',
'data-island-uid': '',
'data-island-slot': props.name
'data-island-slot': props.name,
}))
}
@ -59,5 +59,5 @@ export default defineComponent({
return vnodes
}
}
},
})

View File

@ -7,15 +7,15 @@ export const RouteProvider = defineComponent({
props: {
vnode: {
type: Object as () => VNode,
required: true
required: true,
},
route: {
type: Object as () => RouteLocationNormalizedLoaded,
required: true
required: true,
},
vnodeRef: Object as () => Ref<any>,
renderKey: String,
trackRootNodes: Boolean
trackRootNodes: Boolean,
},
setup (props) {
// Prevent reactivity when the page will be rerendered in a different suspense fork
@ -26,7 +26,7 @@ export const RouteProvider = defineComponent({
const route = {} as RouteLocation
for (const key in props.route) {
Object.defineProperty(route, key, {
get: () => previousKey === props.renderKey ? props.route[key as keyof RouteLocationNormalizedLoaded] : previousRoute[key as keyof RouteLocationNormalizedLoaded]
get: () => previousKey === props.renderKey ? props.route[key as keyof RouteLocationNormalizedLoaded] : previousRoute[key as keyof RouteLocationNormalizedLoaded],
})
}
@ -52,5 +52,5 @@ export const RouteProvider = defineComponent({
return h(props.vnode, { ref: props.vnodeRef })
}
}
},
})

View File

@ -4,5 +4,5 @@ export default defineComponent({
name: 'ServerPlaceholder',
render () {
return createElementBlock('div')
}
},
})

View File

@ -20,8 +20,8 @@ export default (url: string) => defineComponent({
return () => [
h('div', 'Component Test Wrapper for ' + query.path),
h('div', { id: 'nuxt-component-root' }, [
h(comp, { ...attrs, ...props, ...urlProps })
])
h(comp, { ...attrs, ...props, ...urlProps }),
]),
]
}
},
})

View File

@ -36,7 +36,7 @@ export function isChangingPage (to: RouteLocationNormalized, from: RouteLocation
if (generateRouteKey(to) !== generateRouteKey(from)) { return true }
const areComponentsSame = to.matched.every((comp, index) =>
comp.components && comp.components.default === from.matched[index]?.components?.default
comp.components && comp.components.default === from.matched[index]?.components?.default,
)
if (areComponentsSame) {
return false
@ -44,7 +44,6 @@ export function isChangingPage (to: RouteLocationNormalized, from: RouteLocation
return true
}
// eslint-disable-next-line no-use-before-define
export type SSRBuffer = SSRBufferItem[] & { hasAsync?: boolean }
export type SSRBufferItem = string | SSRBuffer | Promise<SSRBuffer>
@ -71,7 +70,7 @@ export function createBuffer () {
if (isPromise(item) || (isArray(item) && item.hasAsync)) {
buffer.hasAsync = true
}
}
},
}
}
@ -95,7 +94,7 @@ export function vforToArray (source: any): any[] {
} else if (isObject(source)) {
if (source[Symbol.iterator as any]) {
return Array.from(source as Iterable<any>, item =>
item
item,
)
} else {
const keys = Object.keys(source)

View File

@ -257,7 +257,7 @@ export function useAsyncData<
data: _ref(options.getCachedData!(key, nuxtApp) ?? options.default!()),
pending: ref(!hasCachedData()),
error: toRef(nuxtApp.payload._errors, key),
status: ref('idle')
status: ref('idle'),
}
}
@ -477,8 +477,8 @@ export function useNuxtData<DataT = any> (key: string): { data: Ref<DataT | null
} else {
nuxtApp.payload.data[key] = value
}
}
})
},
}),
}
}

View File

@ -38,7 +38,7 @@ export const defineNuxtComponent: typeof defineComponent =
if (!setup && !options.asyncData && !options.head) {
return {
[NuxtComponentIndicator]: true,
...options
...options,
}
}
@ -66,6 +66,6 @@ export const defineNuxtComponent: typeof defineComponent =
.finally(() => {
promises.length = 0
})
}
},
} as DefineComponent
}

View File

@ -29,7 +29,7 @@ const CookieDefaults = {
path: '/',
watch: true,
decode: val => destr(decodeURIComponent(val)),
encode: val => encodeURIComponent(typeof val === 'string' ? val : JSON.stringify(val))
encode: val => encodeURIComponent(typeof val === 'string' ? val : JSON.stringify(val)),
} satisfies CookieOptions<any>
const store = import.meta.client && cookieStore ? window.cookieStore : undefined
@ -220,7 +220,7 @@ function cookieRef<T> (value: T | undefined, delay: number, shouldWatch: boolean
internalRef.value = newValue
trigger()
}
},
}
})
}

View File

@ -14,9 +14,9 @@ export interface NuxtError<DataT = unknown> extends H3Error<DataT> {}
/** @since 3.0.0 */
export const showError = <DataT = unknown>(
error: string | Error | (Partial<NuxtError<DataT>> & {
status?: number;
statusText?: string;
})
status?: number
statusText?: string
}),
) => {
const nuxtError = createError<DataT>(error)
@ -52,22 +52,22 @@ export const clearError = async (options: { redirect?: string } = {}) => {
/** @since 3.0.0 */
export const isNuxtError = <DataT = unknown>(
error?: string | object
error?: string | object,
): error is NuxtError<DataT> => !!error && typeof error === 'object' && NUXT_ERROR_SIGNATURE in error
/** @since 3.0.0 */
export const createError = <DataT = unknown>(
error: string | Error | (Partial<NuxtError<DataT>> & {
status?: number;
statusText?: string;
})
status?: number
statusText?: string
}),
) => {
const nuxtError: NuxtError<DataT> = createH3Error<DataT>(error)
Object.defineProperty(nuxtError, NUXT_ERROR_SIGNATURE, {
value: true,
configurable: false,
writable: false
writable: false,
})
return nuxtError

View File

@ -21,7 +21,7 @@ type ComputedOptions<T extends Record<string, any>> = {
}
interface NitroFetchOptions<R extends NitroFetchRequest, M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>> extends FetchOptions {
method?: M;
method?: M
}
type ComputedFetchOptions<R extends NitroFetchRequest, M extends AvailableRouterMethod<R>> = ComputedOptions<NitroFetchOptions<R, M>>
@ -32,7 +32,7 @@ export interface UseFetchOptions<
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = null,
R extends NitroFetchRequest = string & {},
M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>
M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>,
> extends Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'watch'>, ComputedFetchOptions<R, M> {
key?: string
$fetch?: typeof globalThis.$fetch
@ -90,7 +90,7 @@ export function useFetch<
> (
request: Ref<ReqT> | ReqT | (() => ReqT),
arg1?: string | UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>,
arg2?: string
arg2?: string,
) {
const [opts = {}, autoKey] = typeof arg1 === 'string' ? [{}, arg1] : [arg1, arg2]
@ -127,7 +127,7 @@ export function useFetch<
const _fetchOptions = reactive({
...fetchDefaults,
...fetchOptions,
cache: typeof opts.cache === 'boolean' ? undefined : opts.cache
cache: typeof opts.cache === 'boolean' ? undefined : opts.cache,
})
const _asyncDataOptions: AsyncDataOptions<_ResT, DataT, PickKeys, DefaultT> = {
@ -140,7 +140,7 @@ export function useFetch<
getCachedData,
deep,
dedupe,
watch: watch === false ? [] : [_fetchOptions, _request, ...(watch || [])]
watch: watch === false ? [] : [_fetchOptions, _request, ...(watch || [])],
}
if (import.meta.dev && import.meta.client) {
@ -220,7 +220,7 @@ export function useLazyFetch<
> (
request: Ref<ReqT> | ReqT | (() => ReqT),
arg1?: string | Omit<UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>, 'lazy'>,
arg2?: string
arg2?: string,
) {
const [opts = {}, autoKey] = typeof arg1 === 'string' ? [{}, arg1] : [arg1, arg2]
@ -231,16 +231,16 @@ export function useLazyFetch<
return useFetch<ResT, ErrorT, ReqT, Method, _ResT, DataT, PickKeys, DefaultT>(request, {
...opts,
lazy: true
lazy: true,
},
// @ts-expect-error we pass an extra argument with the resolved auto-key to prevent another from being injected
autoKey)
}
function generateOptionSegments <_ResT, DataT, DefaultT> (opts: UseFetchOptions<_ResT, DataT, any, DefaultT, any, any>) {
function generateOptionSegments<_ResT, DataT, DefaultT> (opts: UseFetchOptions<_ResT, DataT, any, DefaultT, any, any>) {
const segments: Array<string | undefined | Record<string, string>> = [
toValue(opts.method as MaybeRef<string | undefined> | undefined)?.toUpperCase() || 'GET',
toValue(opts.baseURL)
toValue(opts.baseURL),
]
for (const _obj of [opts.params || opts.query]) {
const obj = toValue(_obj)

View File

@ -9,7 +9,7 @@ export {
/** @deprecated Import `useSeoMeta` from `#imports` instead. This may be removed in a future minor version. */
useSeoMeta,
/** @deprecated Import `useServerSeoMeta` from `#imports` instead. This may be removed in a future minor version. */
useServerSeoMeta
useServerSeoMeta,
} from '@unhead/vue'
export { defineNuxtComponent } from './component'

View File

@ -148,7 +148,7 @@ function createLoadingIndicator (opts: Partial<LoadingIndicatorOpts> = {}) {
start,
set,
finish,
clear
clear,
}
}

View File

@ -46,7 +46,7 @@ export function getAppManifest (): Promise<NuxtAppManifest> {
export async function getRouteRules (url: string) {
if (import.meta.server) {
const _routeRulesMatcher = toRouteMatcher(
createRadixRouter({ routes: useRuntimeConfig().nitro!.routeRules })
createRadixRouter({ routes: useRuntimeConfig().nitro!.routeRules }),
)
return defu({} as Record<string, any>, ..._routeRulesMatcher.matchAll(url).reverse())
}

View File

@ -44,8 +44,8 @@ export function preloadPayload (url: string, opts: LoadPayloadOptions = {}) {
const payloadURL = _getPayloadURL(url, opts)
useHead({
link: [
{ rel: 'modulepreload', href: payloadURL }
]
{ rel: 'modulepreload', href: payloadURL },
],
})
}
@ -109,7 +109,7 @@ export async function getNuxtClientPayload () {
payloadCache = {
...inlineData,
...externalData,
...window.__NUXT__
...window.__NUXT__,
}
return payloadCache
@ -125,7 +125,7 @@ export async function parsePayload (payload: string) {
*/
export function definePayloadReducer (
name: string,
reduce: (data: any) => any
reduce: (data: any) => any,
) {
if (import.meta.server) {
useNuxtApp().ssrContext!._payloadReducers[name] = reduce
@ -140,7 +140,7 @@ export function definePayloadReducer (
*/
export function definePayloadReviver (
name: string,
revive: (data: any) => any | undefined
revive: (data: any) => any | undefined,
) {
if (import.meta.dev && getCurrentInstance()) {
console.warn('[nuxt] [definePayloadReviver] This function must be called in a Nuxt plugin that is `unshift`ed to the beginning of the Nuxt plugins array.')

View File

@ -36,7 +36,7 @@ function _loadAsyncComponent (component: Component) {
}
/** @since 3.0.0 */
export async function preloadRouteComponents (to: RouteLocationRaw, router: Router & { _routePreloaded?: Set<string>; _preloadPromises?: Array<Promise<any>> } = useRouter()): Promise<void> {
export async function preloadRouteComponents (to: RouteLocationRaw, router: Router & { _routePreloaded?: Set<string>, _preloadPromises?: Array<Promise<any>> } = useRouter()): Promise<void> {
if (import.meta.server) { return }
const { path, matched } = router.resolve(to)

View File

@ -11,8 +11,8 @@ interface Preview {
}
interface PreviewModeOptions<S> {
shouldEnable?: (state: Preview['state']) => boolean,
getState?: (state: Preview['state']) => S,
shouldEnable?: (state: Preview['state']) => boolean
getState?: (state: Preview['state']) => S
}
type EnteredState = Record<any, unknown> | null | undefined | void
@ -23,13 +23,13 @@ let unregisterRefreshHook: (() => any) | undefined
export function usePreviewMode<S extends EnteredState> (options: PreviewModeOptions<S> = {}) {
const preview = useState<Preview>('_preview-state', () => ({
enabled: false,
state: {}
state: {},
}))
if (preview.value._initialized) {
return {
enabled: toRef(preview.value, 'enabled'),
state: preview.value.state as S extends void ? Preview['state'] : (NonNullable<S> & Preview['state'])
state: preview.value.state as S extends void ? Preview['state'] : (NonNullable<S> & Preview['state']),
}
}
@ -67,7 +67,7 @@ export function usePreviewMode<S extends EnteredState> (options: PreviewModeOpti
return {
enabled: toRef(preview.value, 'enabled'),
state: preview.value.state as S extends void ? Preview['state'] : (NonNullable<S> & Preview['state'])
state: preview.value.state as S extends void ? Preview['state'] : (NonNullable<S> & Preview['state']),
}
}

View File

@ -4,7 +4,6 @@ import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, Route
import { sanitizeStatusCode } from 'h3'
import { hasProtocol, isScriptProtocol, joinURL, parseURL, withQuery } from 'ufo'
// eslint-disable-next-line import/no-restricted-paths
import type { PageMeta } from '../../pages/runtime/composables'
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
@ -98,10 +97,10 @@ export type OpenWindowFeatures = {
popup?: boolean
noopener?: boolean
noreferrer?: boolean
} & XOR<{width?: number}, {innerWidth?: number}>
& XOR<{height?: number}, {innerHeight?: number}>
& XOR<{left?: number}, {screenX?: number}>
& XOR<{top?: number}, {screenY?: number}>
} & XOR<{ width?: number }, { innerWidth?: number }>
& XOR<{ height?: number }, { innerHeight?: number }>
& XOR<{ left?: number }, { screenX?: number }>
& XOR<{ top?: number }, { screenY?: number }>
export type OpenOptions = {
target: '_blank' | '_parent' | '_self' | '_top' | (string & {})
@ -170,7 +169,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
nuxtApp.ssrContext!._renderResponse = {
statusCode: sanitizeStatusCode(options?.redirectCode || 302, 302),
body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
headers: { location }
headers: { location },
}
return response
}

View File

@ -10,9 +10,9 @@ const useStateKeyPrefix = '$s'
* @param key a unique key ensuring that data fetching can be properly de-duplicated across requests
* @param init a function that provides initial value for the state when it's not initiated
*/
export function useState <T> (key?: string, init?: (() => T | Ref<T>)): Ref<T>
export function useState <T> (init?: (() => T | Ref<T>)): Ref<T>
export function useState <T> (...args: any): Ref<T> {
export function useState<T> (key?: string, init?: (() => T | Ref<T>)): Ref<T>
export function useState<T> (init?: (() => T | Ref<T>)): Ref<T>
export function useState<T> (...args: any): Ref<T> {
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
const [_key, init] = args as [string, (() => T | Ref<T>)]
@ -40,7 +40,7 @@ export function useState <T> (...args: any): Ref<T> {
/** @since 3.6.0 */
export function clearNuxtState (
keys?: string | string[] | ((key: string) => boolean)
keys?: string | string[] | ((key: string) => boolean),
): void {
const nuxtApp = useNuxtApp()
const _allKeys = Object.keys(nuxtApp.payload.state)

View File

@ -52,7 +52,7 @@ if (import.meta.client) {
if (vueAppPromise) { return vueAppPromise }
const isSSR = Boolean(
window.__NUXT__?.serverRendered ||
document.getElementById('__NUXT_DATA__')?.dataset.ssr === 'true'
document.getElementById('__NUXT_DATA__')?.dataset.ssr === 'true',
)
const vueApp = isSSR ? createSSRApp(RootComponent) : createApp(RootComponent)

View File

@ -1,9 +1,9 @@
/// <reference path="types/augments.d.ts" />
export * from './nuxt'
// eslint-disable-next-line import/no-restricted-paths
export * from './composables/index'
// eslint-disable-next-line import/no-restricted-paths
export * from './components/index'
export * from './config'
export * from './compat/idle-callback'

View File

@ -1,4 +1,3 @@
/* eslint-disable no-use-before-define */
import { effectScope, getCurrentInstance, hasInjectionContext, reactive } from 'vue'
import type { App, EffectScope, Ref, VNode, onErrorCaptured } from 'vue'
import type { RouteLocationNormalizedLoaded } from '#vue-router'
@ -23,7 +22,7 @@ import type { ViewTransition } from './plugins/view-transitions.client'
import type { NuxtAppLiterals } from '#app'
const nuxtAppCtx = /* @__PURE__ */ getContext<NuxtApp>('nuxt-app', {
asyncContext: !!__NUXT_ASYNC_CONTEXT__ && import.meta.server
asyncContext: !!__NUXT_ASYNC_CONTEXT__ && import.meta.server,
})
type HookResult = Promise<void> | void
@ -236,17 +235,17 @@ export function createNuxtApp (options: CreateOptions) {
globalName: 'nuxt',
versions: {
get nuxt () { return __NUXT_VERSION__ },
get vue () { return nuxtApp.vueApp.version }
get vue () { return nuxtApp.vueApp.version },
},
payload: reactive({
data: {},
state: {},
once: new Set<string>(),
_errors: {},
...(import.meta.client ? window.__NUXT__ ?? {} : { serverRendered: true })
...(import.meta.client ? window.__NUXT__ ?? {} : { serverRendered: true }),
}),
static: {
data: {}
data: {},
},
runWithContext: (fn: any) => nuxtApp._scope.run(() => callWithNuxt(nuxtApp, fn)),
isHydrating: import.meta.client,
@ -271,7 +270,7 @@ export function createNuxtApp (options: CreateOptions) {
_asyncDataPromises: {},
_asyncData: {},
_payloadRevivers: {},
...options
...options,
} as any as NuxtApp
nuxtApp.hooks = createHooks<RuntimeNuxtHooks>()
@ -319,7 +318,7 @@ export function createNuxtApp (options: CreateOptions) {
// Expose client runtime-config to the payload
nuxtApp.ssrContext!.config = {
public: options.ssrContext!.runtimeConfig.public,
app: options.ssrContext!.runtimeConfig.app
app: options.ssrContext!.runtimeConfig.app,
}
}

View File

@ -23,6 +23,6 @@ export default defineNuxtPlugin({
}
},
env: {
islands: false
}
islands: false,
},
})

View File

@ -30,5 +30,5 @@ export default defineNuxtPlugin({
reloadAppAtPath(to)
}
})
}
},
})

View File

@ -16,23 +16,23 @@ export default defineNuxtPlugin({
{
source: 'list',
urls: [...externalURLs.value],
requires: ['anonymous-client-ip-when-cross-origin']
}
]
})
requires: ['anonymous-client-ip-when-cross-origin'],
},
],
}),
}
}
const head = useHead({
script: [generateRules()]
script: [generateRules()],
})
nuxtApp.hook('link:prefetch', (url) => {
const { protocol } = parseURL(url)
if (protocol && ['http:', 'https:'].includes(protocol)) {
externalURLs.value.add(url)
head?.patch({
script: [generateRules()]
script: [generateRules()],
})
}
})
}
},
})

View File

@ -6,5 +6,5 @@ export default defineNuxtPlugin({
enforce: 'pre',
setup (nuxtApp) {
createDebugger(nuxtApp.hooks, { tag: 'nuxt-app' })
}
},
})

View File

@ -20,8 +20,8 @@ export default defineNuxtPlugin((nuxtApp) => {
const logger = createConsola({
formatOptions: {
colors: true,
date: true
}
date: true,
},
})
const hydrationLogs = new Set<string>()
consola.wrapConsole()
@ -32,7 +32,7 @@ export default defineNuxtPlugin((nuxtApp) => {
} catch {
// silently ignore - the worst case is a user gets log twice
}
}
},
})
nuxtApp.hook('dev:ssr-logs', (logs) => {
for (const log of logs) {

View File

@ -32,5 +32,5 @@ export default defineNuxtPlugin({
setTimeout(getAppManifest, 1000)
}
})
}
},
})

View File

@ -8,7 +8,7 @@ export default defineNuxtPlugin({
const { _registeredComponents } = this.$nuxt.ssrContext
const { __moduleIdentifier } = this.$options
_registeredComponents.add(__moduleIdentifier)
}
},
})
}
},
})

View File

@ -15,6 +15,6 @@ export default defineNuxtPlugin({
} catch {
// don't throw an error if we have issues reading sessionStorage
}
}
}
},
},
})

View File

@ -14,7 +14,7 @@ const revivers: Record<string, (data: any) => any> = {
ShallowRef: data => shallowRef(data),
ShallowReactive: data => shallowReactive(data),
Ref: data => ref(data),
Reactive: data => reactive(data)
Reactive: data => reactive(data),
}
if (componentIslands) {
@ -23,7 +23,7 @@ if (componentIslands) {
if (!nuxtApp.isHydrating) {
nuxtApp.payload.data[key] = nuxtApp.payload.data[key] || $fetch(`/__nuxt_island/${key}.json`, {
responseType: 'json',
...params ? { params } : {}
...params ? { params } : {},
}).then((r) => {
nuxtApp.payload.data[key] = r
return r
@ -34,9 +34,9 @@ if (componentIslands) {
state: {},
head: {
link: [],
style: []
style: [],
},
...result
...result,
}
}
}
@ -51,5 +51,5 @@ export default defineNuxtPlugin({
Object.assign(nuxtApp.payload, await nuxtApp.runWithContext(getNuxtClientPayload))
// For backwards compatibility - TODO: remove later
window.__NUXT__ = nuxtApp.payload
}
},
})

View File

@ -13,7 +13,7 @@ const reducers: Record<string, (data: any) => any> = {
ShallowRef: data => isRef(data) && isShallow(data) && data.value,
ShallowReactive: data => isReactive(data) && isShallow(data) && toRaw(data),
Ref: data => isRef(data) && data.value,
Reactive: data => isReactive(data) && toRaw(data)
Reactive: data => isReactive(data) && toRaw(data),
}
if (componentIslands) {
@ -26,5 +26,5 @@ export default defineNuxtPlugin({
for (const reducer in reducers) {
definePayloadReducer(reducer, reducers[reducer as keyof typeof reducers])
}
}
},
})

View File

@ -41,7 +41,7 @@ function getRouteFromPath (fullPath: string | Partial<Route>) {
fullPath = stringifyParsedURL({
pathname: fullPath.path || '',
search: stringifyQuery(fullPath.query || {}),
hash: fullPath.hash || ''
hash: fullPath.hash || '',
})
}
@ -57,7 +57,7 @@ function getRouteFromPath (fullPath: string | Partial<Route>) {
matched: [],
redirectedFrom: undefined,
meta: {},
href: fullPath
href: fullPath,
}
}
@ -112,7 +112,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
'navigate:before': [],
'resolve:before': [],
'navigate:after': [],
error: []
'error': [],
}
const registerHook = <T extends keyof RouterHooks> (hook: T, guard: RouterHooks[T]) => {
@ -191,7 +191,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
if (index !== -1) {
routes.splice(index, 1)
}
}
},
}
nuxtApp.vueApp.component('RouterLink', defineComponent({
@ -199,14 +199,14 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
props: {
to: {
type: String,
required: true
required: true,
},
custom: Boolean,
replace: Boolean,
// Not implemented
activeClass: String,
exactActiveClass: String,
ariaCurrentValue: String
ariaCurrentValue: String,
},
setup: (props, { slots }) => {
const navigate = () => handleNavigation(props.to!, props.replace)
@ -216,7 +216,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
? slots.default?.({ href: props.to, navigate, route })
: h('a', { href: props.to, onClick: (e: MouseEvent) => { e.preventDefault(); return navigate() } }, slots)
}
}
},
}))
if (import.meta.client) {
@ -231,7 +231,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
// Handle middleware
nuxtApp._middleware = nuxtApp._middleware || {
global: [],
named: {}
named: {},
}
const initialLayout = nuxtApp.payload.state._layout
@ -271,8 +271,8 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
statusCode: 404,
statusMessage: `Page Not Found: ${initialURL}`,
data: {
path: initialURL
}
path: initialURL,
},
})
delete nuxtApp._processingMiddleware
return nuxtApp.runWithContext(() => showError(error))
@ -295,8 +295,8 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({
return {
provide: {
route,
router
}
}
router,
},
}
},
})

View File

@ -1,9 +1,7 @@
// eslint-disable-next-line import/no-restricted-paths
export type { PageMeta } from '../pages/runtime/index'
export interface NuxtAppLiterals {
[key: string]: string
}
// eslint-disable-next-line import/no-restricted-paths
export type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from '../core/runtime/nitro/renderer'

View File

@ -4,9 +4,10 @@ import MagicString from 'magic-string'
import { isAbsolute, relative } from 'pathe'
import { hash } from 'ohash'
import { isVue } from '../core/utils'
interface LoaderOptions {
sourcemap?: boolean
transform?: ComponentsOptions['transform'],
transform?: ComponentsOptions['transform']
rootDir: string
}
const CLIENT_FALLBACK_RE = /<(NuxtClientFallback|nuxt-client-fallback)( [^>]*)?>/
@ -45,9 +46,9 @@ export const clientFallbackAutoIdPlugin = createUnplugin((options: LoaderOptions
code: s.toString(),
map: options.sourcemap
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})

View File

@ -53,7 +53,7 @@ export const islandsTransform = createUnplugin((options: ServerOnlyComponentTran
const components = options.getComponents()
const islands = components.filter(component =>
component.island || (component.mode === 'server' && !components.some(c => c.pascalName === component.pascalName && c.mode === 'client'))
component.island || (component.mode === 'server' && !components.some(c => c.pascalName === component.pascalName && c.mode === 'client')),
)
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href))
return islands.some(c => c.filePath === pathname)
@ -129,17 +129,16 @@ export const islandsTransform = createUnplugin((options: ServerOnlyComponentTran
})
if (!isVite && hasNuxtClient) {
// eslint-disable-next-line no-console
console.warn(`nuxt-client attribute and client components within islands is only supported with Vite. file: ${id}`)
}
if (s.hasChanged()) {
return {
code: s.toString(),
map: s.generateMap({ source: id, includeContent: true })
}
map: s.generateMap({ source: id, includeContent: true }),
}
}
},
}
})
@ -187,8 +186,8 @@ export const componentsChunkPlugin = createUnplugin((options: ComponentChunkOpti
config.build = defu(config.build, {
rollupOptions: {
input: {},
output: {}
}
output: {},
},
})
const rollupOptions = config.build.rollupOptions!
@ -228,7 +227,7 @@ export const componentsChunkPlugin = createUnplugin((options: ComponentChunkOpti
}
fs.writeFileSync(join(buildDir, 'components-chunk.mjs'), `export const paths = ${JSON.stringify(pathAssociation, null, 2)}`)
}
}
},
},
}
})

View File

@ -99,10 +99,10 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
code: s.toString(),
map: options.sourcemap
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})

View File

@ -25,15 +25,15 @@ export type getComponentsT = (mode?: 'client' | 'server' | 'all') => Component[]
export default defineNuxtModule<ComponentsOptions>({
meta: {
name: 'components',
configKey: 'components'
configKey: 'components',
},
defaults: {
dirs: []
dirs: [],
},
setup (componentOptions, nuxt) {
let componentDirs: ComponentsDir[] = []
const context = {
components: [] as Component[]
components: [] as Component[],
}
const getComponents: getComponentsT = (mode) => {
@ -50,12 +50,12 @@ export default defineNuxtModule<ComponentsOptions>({
return [
{ priority: options?.priority || 0, path: resolve(cwd, 'components/islands'), island: true },
{ priority: options?.priority || 0, path: resolve(cwd, 'components/global'), global: true },
{ priority: options?.priority || 0, path: resolve(cwd, 'components') }
{ priority: options?.priority || 0, path: resolve(cwd, 'components') },
]
}
if (typeof dir === 'string') {
return [
{ priority: options?.priority || 0, path: resolve(cwd, resolveAlias(dir)) }
{ priority: options?.priority || 0, path: resolve(cwd, resolveAlias(dir)) },
]
}
if (!dir) {
@ -65,7 +65,7 @@ export default defineNuxtModule<ComponentsOptions>({
return dirs.map(_dir => ({
priority: options?.priority || 0,
..._dir,
path: resolve(cwd, resolveAlias(_dir.path))
path: resolve(cwd, resolveAlias(_dir.path)),
}))
}
@ -100,15 +100,15 @@ export default defineNuxtModule<ComponentsOptions>({
ignore: [
'**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}', // ignore mixins
'**/*.d.{cts,mts,ts}', // .d.ts files
...(dirOptions.ignore || [])
...(dirOptions.ignore || []),
],
transpile: (transpile === 'auto' ? dirPath.includes('node_modules') : transpile)
transpile: (transpile === 'auto' ? dirPath.includes('node_modules') : transpile),
}
}).filter(d => d.enabled)
componentDirs = [
...componentDirs.filter(dir => !dir.path.includes('node_modules')),
...componentDirs.filter(dir => dir.path.includes('node_modules'))
...componentDirs.filter(dir => dir.path.includes('node_modules')),
]
nuxt.options.build!.transpile!.push(...componentDirs.filter(dir => dir.transpile).map(dir => dir.path))
@ -179,7 +179,7 @@ export default defineNuxtModule<ComponentsOptions>({
_raw: true,
mode: 'server',
filePath: serverPlaceholderPath,
chunkName: 'components/' + component.kebabName
chunkName: 'components/' + component.kebabName,
})
}
if (component.mode === 'server' && !nuxt.options.ssr && !newComponents.some(other => other.pascalName === component.pascalName && other.mode === 'client')) {
@ -206,8 +206,8 @@ export default defineNuxtModule<ComponentsOptions>({
'components.plugin.mjs',
'components.d.ts',
'components.server.mjs',
'components.client.mjs'
].includes(template.filename)
'components.client.mjs',
].includes(template.filename),
})
}
})
@ -219,19 +219,19 @@ export default defineNuxtModule<ComponentsOptions>({
if (nuxt.options.experimental.treeshakeClientOnly && isServer) {
config.plugins.push(TreeShakeTemplatePlugin.vite({
sourcemap: !!nuxt.options.sourcemap[mode],
getComponents
getComponents,
}))
}
config.plugins.push(clientFallbackAutoIdPlugin.vite({
sourcemap: !!nuxt.options.sourcemap[mode],
rootDir: nuxt.options.rootDir
rootDir: nuxt.options.rootDir,
}))
config.plugins.push(loaderPlugin.vite({
sourcemap: !!nuxt.options.sourcemap[mode],
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
}))
if (nuxt.options.experimental.componentIslands) {
@ -242,7 +242,7 @@ export default defineNuxtModule<ComponentsOptions>({
if (!nuxt.options.dev) {
config.plugins.push(componentsChunkPlugin.vite({
getComponents,
buildDir: nuxt.options.buildDir
buildDir: nuxt.options.buildDir,
}))
} else {
fs.writeFileSync(join(nuxt.options.buildDir, 'components-chunk.mjs'), `export const paths = ${JSON.stringify(
@ -250,7 +250,7 @@ export default defineNuxtModule<ComponentsOptions>({
if (c.filePath.endsWith('.vue') || c.filePath.endsWith('.js') || c.filePath.endsWith('.ts')) { return Object.assign(acc, { [c.pascalName]: `/@fs/${c.filePath}` }) }
const filePath = fs.existsSync(`${c.filePath}.vue`) ? `${c.filePath}.vue` : fs.existsSync(`${c.filePath}.js`) ? `${c.filePath}.js` : `${c.filePath}.ts`
return Object.assign(acc, { [c.pascalName]: `/@fs/${filePath}` })
}, {} as Record<string, string>)
}, {} as Record<string, string>),
)}`)
}
}
@ -260,7 +260,7 @@ export default defineNuxtModule<ComponentsOptions>({
getComponents,
rootDir: nuxt.options.rootDir,
isDev: nuxt.options.dev,
selectiveClient
selectiveClient,
}))
}
}
@ -274,10 +274,10 @@ export default defineNuxtModule<ComponentsOptions>({
if (comp?.mode === 'server') {
ctx.server.ws.send({
event: `nuxt-server-component:${comp.pascalName}`,
type: 'custom'
type: 'custom',
})
}
}
},
})
}
})
@ -288,25 +288,25 @@ export default defineNuxtModule<ComponentsOptions>({
if (nuxt.options.experimental.treeshakeClientOnly && mode === 'server') {
config.plugins.push(TreeShakeTemplatePlugin.webpack({
sourcemap: !!nuxt.options.sourcemap[mode],
getComponents
getComponents,
}))
}
config.plugins.push(clientFallbackAutoIdPlugin.webpack({
sourcemap: !!nuxt.options.sourcemap[mode],
rootDir: nuxt.options.rootDir
rootDir: nuxt.options.rootDir,
}))
config.plugins.push(loaderPlugin.webpack({
sourcemap: !!nuxt.options.sourcemap[mode],
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
}))
if (nuxt.options.experimental.componentIslands) {
if (mode === 'server') {
config.plugins.push(islandsTransform.webpack({
getComponents
getComponents,
}))
} else {
fs.writeFileSync(join(nuxt.options.buildDir, 'components-chunk.mjs'), 'export const paths = {}')
@ -314,5 +314,5 @@ export default defineNuxtModule<ComponentsOptions>({
}
})
})
}
},
})

View File

@ -11,9 +11,9 @@ export const createClientPage = (loader: AsyncComponentLoader) => {
setup (_, { attrs }) {
return () => h('div', [
h(ClientOnly, undefined, {
default: () => h(page, attrs)
})
default: () => h(page, attrs),
}),
])
}
},
})
}

View File

@ -14,7 +14,7 @@ export const createServerComponent = (name: string) => {
const islandRef = ref<null | typeof NuxtIsland>(null)
expose({
refresh: () => islandRef.value?.refresh()
refresh: () => islandRef.value?.refresh(),
})
return () => {
@ -25,10 +25,10 @@ export const createServerComponent = (name: string) => {
ref: islandRef,
onError: (err) => {
emit('error', err)
}
},
}, slots)
}
}
},
})
}
@ -42,7 +42,7 @@ export const createIslandPage = (name: string) => {
const islandRef = ref<null | typeof NuxtIsland>(null)
expose({
refresh: () => islandRef.value?.refresh()
refresh: () => islandRef.value?.refresh(),
})
const route = useRoute()
@ -54,10 +54,10 @@ export const createIslandPage = (name: string) => {
name: `page:${name}`,
lazy: props.lazy,
ref: islandRef,
context: { url: path }
}, slots)
context: { url: path },
}, slots),
])
}
}
},
})
}

View File

@ -69,7 +69,7 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
*/
const prefixParts = ([] as string[]).concat(
dir.prefix ? splitByCase(dir.prefix) : [],
(dir.pathPrefix !== false) ? splitByCase(relative(dir.path, dirname(filePath))) : []
(dir.pathPrefix !== false) ? splitByCase(relative(dir.path, dirname(filePath))) : [],
)
/**
@ -118,7 +118,7 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
shortPath,
export: 'default',
// by default, give priority to scanned components
priority: dir.priority ?? 1
priority: dir.priority ?? 1,
}
if (typeof dir.extendComponent === 'function') {
@ -160,6 +160,6 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
function warnAboutDuplicateComponent (componentName: string, filePath: string, duplicatePath: string) {
logger.warn(`Two component files resolving to the same name \`${componentName}\`:\n` +
`\n - ${filePath}` +
`\n - ${duplicatePath}`
`\n - ${duplicatePath}`,
)
}

View File

@ -13,7 +13,7 @@ const createImportMagicComments = (options: ImportMagicCommentsOptions) => {
return [
`webpackChunkName: "${chunkName}"`,
prefetch === true || typeof prefetch === 'number' ? `webpackPrefetch: ${prefetch}` : false,
preload === true || typeof preload === 'number' ? `webpackPreload: ${preload}` : false
preload === true || typeof preload === 'number' ? `webpackPreload: ${preload}` : false,
].filter(Boolean).join(', ')
}
@ -58,14 +58,14 @@ export default defineNuxtPlugin({
}
})
`
}
},
}
export const componentNamesTemplate: NuxtTemplate = {
filename: 'component-names.mjs',
getContents ({ app }) {
return `export const componentNames = ${JSON.stringify(app.components.filter(c => !c.island).map(c => c.pascalName))}`
}
},
}
export const componentsIslandsTemplate: NuxtTemplate = {
@ -76,7 +76,7 @@ export const componentsIslandsTemplate: NuxtTemplate = {
const islands = components.filter(component =>
component.island ||
// .server components without a corresponding .client component will need to be rendered as an island
(component.mode === 'server' && !components.some(c => c.pascalName === component.pascalName && c.mode === 'client'))
(component.mode === 'server' && !components.some(c => c.pascalName === component.pascalName && c.mode === 'client')),
)
const pageExports = pages?.filter(p => (p.mode === 'server' && p.file && p.name)).map((p) => {
@ -91,11 +91,11 @@ export const componentsIslandsTemplate: NuxtTemplate = {
const exp = c.export === 'default' ? 'c.default || c' : `c['${c.export}']`
const comment = createImportMagicComments(c)
return ` "${c.pascalName}": defineAsyncComponent(${genDynamicImport(c.filePath, { comment })}.then(c => ${exp}))`
}
},
).concat(pageExports).join(',\n'),
'}'
'}',
].join('\n')
}
},
}
export const componentsTypeTemplate = {
@ -106,7 +106,7 @@ export const componentsTypeTemplate = {
c.pascalName,
`typeof ${genDynamicImport(isAbsolute(c.filePath)
? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!vue)\w+$/g, '')
: c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']`
: c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']`,
])
return `
@ -132,11 +132,11 @@ ${componentTypes.map(([pascalName, type]) => `export const Lazy${pascalName}: ${
export const componentNames: string[]
`
}
},
} satisfies NuxtTemplate
export const componentsMetadataTemplate: NuxtTemplate = {
filename: 'components.json',
write: true,
getContents: ({ app }) => JSON.stringify(app.components, null, 2)
getContents: ({ app }) => JSON.stringify(app.components, null, 2),
}

View File

@ -18,10 +18,10 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
imports: [
{
name: 'componentNames',
from: '#build/component-names'
}
from: '#build/component-names',
},
],
virtualImports: ['#components']
virtualImports: ['#components'],
})
function getComponentsImports (): Import[] {
@ -37,13 +37,13 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
{
as: c.pascalName,
from: withMode(mode),
name: c.export || 'default'
name: c.export || 'default',
},
{
as: 'Lazy' + c.pascalName,
from: withMode([mode, 'async'].filter(Boolean).join(',')),
name: c.export || 'default'
}
name: c.export || 'default',
},
]
})
}
@ -67,36 +67,36 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
return {
code: [
'import { defineAsyncComponent } from "vue"',
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))`
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))`,
].join('\n'),
map: null
map: null,
}
} else if (mode === 'client') {
return {
code: [
genImport(bare, [{ name: componentExport, as: '__component' }]),
'import { createClientOnly } from "#app/components/client-only"',
`${exportWording} createClientOnly(__component)`
`${exportWording} createClientOnly(__component)`,
].join('\n'),
map: null
map: null,
}
} else if (mode === 'client,async') {
return {
code: [
'import { defineAsyncComponent } from "vue"',
'import { createClientOnly } from "#app/components/client-only"',
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))`
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))`,
].join('\n'),
map: null
map: null,
}
} else if (mode === 'server' || mode === 'server,async') {
const name = query.nuxt_component_name
return {
code: [
`import { createServerComponent } from ${JSON.stringify(serverComponentRuntime)}`,
`${exportWording} createServerComponent(${JSON.stringify(name)})`
`${exportWording} createServerComponent(${JSON.stringify(name)})`,
].join('\n'),
map: null
map: null,
}
} else {
throw new Error(`Unknown component mode: ${mode}, this might be an internal bug of Nuxt.`)
@ -118,8 +118,8 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
code: result.code,
map: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client
? result.s.generateMap({ hires: true })
: undefined
}
: undefined,
}
},
}))
}

View File

@ -81,13 +81,13 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
componentsToRemoveSet.add(nameToRemove)
}
}
}
},
})
}
}
}
}
}
},
})
const componentsToRemove = [...componentsToRemoveSet]
@ -107,10 +107,10 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
code: s.toString(),
map: options.sourcemap
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})
@ -142,7 +142,7 @@ function removeFromSetupReturn (codeAst: Program, name: string, magicString: Mag
}
}
}
}
},
})
}
@ -209,10 +209,10 @@ function isComponentNotCalledInSetup (codeAst: Node, name: string): string | voi
// dev only with $setup or _ctx
found = (node.property.type === 'Literal' && node.property.value === name) || (node.property.type === 'Identifier' && node.property.name === name)
}
}
},
})
}
}
},
})
if (!found) { return name }
}
@ -250,7 +250,7 @@ function removeVariableDeclarator (codeAst: Node, name: string, magicString: Mag
}
}
}
}
},
})
}

View File

@ -16,7 +16,7 @@ export function createApp (nuxt: Nuxt, options: Partial<NuxtApp> = {}): NuxtApp
extensions: nuxt.options.extensions,
plugins: [],
components: [],
templates: []
templates: [],
} as unknown as NuxtApp) as NuxtApp
}
@ -97,8 +97,8 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
app.mainComponent = await findPath(
nuxt.options._layers.flatMap(layer => [
join(layer.config.srcDir, 'App'),
join(layer.config.srcDir, 'app')
])
join(layer.config.srcDir, 'app'),
]),
)
}
if (!app.mainComponent) {
@ -113,7 +113,7 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
// Resolve error component
if (!app.errorComponent) {
app.errorComponent = (await findPath(
nuxt.options._layers.map(layer => join(layer.config.srcDir, 'error'))
nuxt.options._layers.map(layer => join(layer.config.srcDir, 'error')),
)) ?? resolve(nuxt.options.appDir, 'components/nuxt-error-page.vue')
}
@ -160,9 +160,9 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
...config.srcDir
? await resolveFiles(config.srcDir, [
`${pluginDir}/*{${nuxt.options.extensions.join(',')}}`,
`${pluginDir}/*/index{${nuxt.options.extensions.join(',')}}` // TODO: remove, only scan top-level plugins #18418
`${pluginDir}/*/index{${nuxt.options.extensions.join(',')}}`, // TODO: remove, only scan top-level plugins #18418
])
: []
: [],
].map(plugin => normalizePlugin(plugin as NuxtPlugin)))
}
@ -200,7 +200,7 @@ function resolvePaths<Item extends Record<string, any>> (items: Item[], key: { [
if (!item[key]) { return item }
return {
...item,
[key]: await resolvePath(resolveAlias(item[key]))
[key]: await resolvePath(resolveAlias(item[key])),
}
}))
}
@ -214,7 +214,7 @@ export async function annotatePlugins (nuxt: Nuxt, plugins: NuxtPlugin[]) {
const code = plugin.src in nuxt.vfs ? nuxt.vfs[plugin.src] : await fsp.readFile(plugin.src!, 'utf-8')
_plugins.push({
...await extractMetadata(code, IS_TSX.test(plugin.src) ? 'tsx' : 'ts'),
...plugin
...plugin,
})
} catch (e) {
const relativePluginSrc = relative(nuxt.options.rootDir, plugin.src)

View File

@ -56,7 +56,7 @@ export async function build (nuxt: Nuxt) {
const watchEvents: Record<EventType, 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'> = {
create: 'add',
delete: 'unlink',
update: 'change'
update: 'change',
}
async function watch (nuxt: Nuxt) {
@ -80,8 +80,8 @@ function createWatcher () {
ignoreInitial: true,
ignored: [
isIgnored,
'node_modules'
]
'node_modules',
],
})
// TODO: consider moving to emit absolute path in 3.8 or 4.0
@ -164,8 +164,8 @@ async function createParcelWatcher () {
}, {
ignore: [
...nuxt.options.ignore,
'node_modules'
]
'node_modules',
],
})
watcher.then((subscription) => {
if (nuxt.options.debug) {

View File

@ -30,7 +30,7 @@ async function checkViteConfig () {
return await checkAndWarnAboutConfigFileExistence({
fileName: 'vite.config',
extensions: ['.js', '.mjs', '.ts', '.cjs', '.mts', '.cts'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.vite\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#vite\`.`
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.vite\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#vite\`.`,
})
}
@ -39,7 +39,7 @@ async function checkWebpackConfig () {
return await checkAndWarnAboutConfigFileExistence({
fileName: 'webpack.config',
extensions: ['.js', '.mjs', '.ts', '.cjs', '.mts', '.cts', 'coffee'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.webpack\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#webpack-1\`.`
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.webpack\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#webpack-1\`.`,
})
}
@ -48,7 +48,7 @@ async function checkNitroConfig () {
return await checkAndWarnAboutConfigFileExistence({
fileName: 'nitro.config',
extensions: ['.ts', '.mts'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.nitro\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#nitro\`.`
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.nitro\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#nitro\`.`,
})
}
@ -56,13 +56,13 @@ async function checkPostCSSConfig () {
return await checkAndWarnAboutConfigFileExistence({
fileName: 'postcss.config',
extensions: ['.js', '.cjs'],
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.postcss\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#postcss\`.`
createWarningMessage: foundFile => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.postcss\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#postcss\`.`,
})
}
interface CheckAndWarnAboutConfigFileExistenceOptions {
fileName: string,
extensions: string[],
fileName: string
extensions: string[]
createWarningMessage: (foundFile: string) => string
}

View File

@ -26,7 +26,7 @@ async function promptToInstall (name: string, installCommand: () => Promise<void
const confirm = await logger.prompt(`Do you want to install ${name} package?`, {
type: 'confirm',
name: 'confirm',
initial: true
initial: true,
})
if (!confirm) {
@ -60,6 +60,6 @@ export function installNuxtModule (name: string, options?: EnsurePackageInstalle
export function ensurePackageInstalled (name: string, options: EnsurePackageInstalledOptions) {
return promptToInstall(name, () => addDependency(name, {
cwd: options.rootDir,
dev: true
dev: true,
}), options)
}

View File

@ -10,7 +10,7 @@ export const addModuleTranspiles = (opts: AddModuleTranspilesOptions = {}) => {
const modules = [
...opts.additionalModules || [],
...nuxt.options.modules,
...nuxt.options._modules
...nuxt.options._modules,
]
.map(m => typeof m === 'string' ? m : Array.isArray(m) ? m[0] : m.src)
.filter(m => typeof m === 'string')

View File

@ -23,7 +23,7 @@ import { ImportProtectionPlugin, nuxtImportProtections } from './plugins/import-
const logLevelMapReverse = {
silent: 0,
info: 3,
verbose: 3
verbose: 3,
} satisfies Record<NuxtOptions['logLevel'], NitroConfig['logLevel']>
export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
@ -33,7 +33,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
const excludePaths = nuxt.options._layers
.flatMap(l => [
l.cwd.match(/(?<=\/)node_modules\/(.+)$/)?.[1],
l.cwd.match(/\.pnpm\/.+\/node_modules\/(.+)$/)?.[1]
l.cwd.match(/\.pnpm\/.+\/node_modules\/(.+)$/)?.[1],
])
.filter((dir): dir is string => Boolean(dir))
.map(dir => escapeRE(dir))
@ -46,7 +46,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
const modules = await resolveNuxtModule(rootDirWithSlash,
nuxt.options._installedModules
.filter(m => m.entryPath)
.map(m => m.entryPath)
.map(m => m.entryPath),
)
const nitroConfig: NitroConfig = defu(_nitroConfig, {
@ -58,11 +58,11 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
buildDir: nuxt.options.buildDir,
experimental: {
asyncContext: nuxt.options.experimental.asyncContext,
typescriptBundlerResolution: nuxt.options.future.typescriptBundlerResolution || nuxt.options.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === 'bundler' || _nitroConfig.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === 'bundler'
typescriptBundlerResolution: nuxt.options.future.typescriptBundlerResolution || nuxt.options.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === 'bundler' || _nitroConfig.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === 'bundler',
},
framework: {
name: 'nuxt',
version: nuxtVersion
version: nuxtVersion,
},
imports: {
autoImport: nuxt.options.imports.autoImport as boolean,
@ -70,31 +70,31 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
{
as: '__buildAssetsURL',
name: 'buildAssetsURL',
from: resolve(distDir, 'core/runtime/nitro/paths')
from: resolve(distDir, 'core/runtime/nitro/paths'),
},
{
as: '__publicAssetsURL',
name: 'publicAssetsURL',
from: resolve(distDir, 'core/runtime/nitro/paths')
from: resolve(distDir, 'core/runtime/nitro/paths'),
},
{
// TODO: Remove after https://github.com/unjs/nitro/issues/1049
as: 'defineAppConfig',
name: 'defineAppConfig',
from: resolve(distDir, 'core/runtime/nitro/config'),
priority: -1
}
priority: -1,
},
],
exclude: [...excludePattern, /[\\/]\.git[\\/]/]
exclude: [...excludePattern, /[\\/]\.git[\\/]/],
},
esbuild: {
options: { exclude: excludePattern }
options: { exclude: excludePattern },
},
analyze: !nuxt.options.test && nuxt.options.build.analyze && (nuxt.options.build.analyze === true || nuxt.options.build.analyze.enabled)
? {
template: 'treemap',
projectRoot: nuxt.options.rootDir,
filename: join(nuxt.options.analyzeDir, '{name}.html')
filename: join(nuxt.options.analyzeDir, '{name}.html'),
}
: false,
scanDirs: nuxt.options._layers.map(layer => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, 'server'))).filter(Boolean),
@ -106,10 +106,10 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
baseURL: nuxt.options.app.baseURL,
virtual: {
'#internal/nuxt.config.mjs': () => nuxt.vfs['#build/nuxt.config'],
'#spa-template': async () => `export const template = ${JSON.stringify(await spaLoadingTemplate(nuxt))}`
'#spa-template': async () => `export const template = ${JSON.stringify(await spaLoadingTemplate(nuxt))}`,
},
routeRules: {
'/__nuxt_error': { cache: false }
'/__nuxt_error': { cache: false },
},
runtimeConfig: {
...nuxt.options.runtimeConfig,
@ -117,17 +117,17 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
...nuxt.options.runtimeConfig.app,
baseURL: nuxt.options.runtimeConfig.app.baseURL.startsWith('./')
? nuxt.options.runtimeConfig.app.baseURL.slice(1)
: nuxt.options.runtimeConfig.app.baseURL
: nuxt.options.runtimeConfig.app.baseURL,
},
nitro: {
envPrefix: 'NUXT_',
// TODO: address upstream issue with defu types...?
...nuxt.options.runtimeConfig.nitro satisfies RuntimeConfig['nitro'] as any
}
...nuxt.options.runtimeConfig.nitro satisfies RuntimeConfig['nitro'] as any,
},
},
appConfig: nuxt.options.appConfig,
appConfigFiles: nuxt.options._layers.map(
layer => resolve(layer.config.srcDir, 'app.config')
layer => resolve(layer.config.srcDir, 'app.config'),
),
typescript: {
strict: true,
@ -136,14 +136,14 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
tsConfig: {
include: [
join(nuxt.options.buildDir, 'types/nitro-nuxt.d.ts'),
...modules.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime/server'))
...modules.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime/server')),
],
exclude: [
...nuxt.options.modulesDir.map(m => relativeWithDot(nuxt.options.buildDir, m)),
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist'))
]
}
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist')),
],
},
},
publicAssets: [
nuxt.options.dev
@ -151,17 +151,17 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
: {
dir: join(nuxt.options.buildDir, 'dist/client', nuxt.options.app.buildAssetsDir),
maxAge: 31536000 /* 1 year */,
baseURL: nuxt.options.app.buildAssetsDir
baseURL: nuxt.options.app.buildAssetsDir,
},
...nuxt.options._layers
.map(layer => join(layer.config.srcDir, (layer.config.rootDir === nuxt.options.rootDir ? nuxt.options : layer.config).dir?.public || 'public'))
.filter(dir => existsSync(dir))
.map(dir => ({ dir }))
.map(dir => ({ dir })),
],
prerender: {
failOnError: true,
concurrency: cpus().length * 4 || 4,
routes: ([] as string[]).concat(nuxt.options.generate.routes)
routes: ([] as string[]).concat(nuxt.options.generate.routes),
},
sourceMap: nuxt.options.sourcemap.server,
externals: {
@ -171,13 +171,13 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
: [
...nuxt.options.experimental.externalVue ? [] : ['vue', '@vue/'],
'@nuxt/',
nuxt.options.buildDir
nuxt.options.buildDir,
]),
...nuxt.options.build.transpile.filter((i): i is string => typeof i === 'string'),
'nuxt/dist',
'nuxt3/dist',
'nuxt-nightly/dist',
distDir
distDir,
],
traceInclude: [
// force include files used in generated code from the runtime-compiler
@ -187,10 +187,10 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
const serverRendererPath = resolve(path, 'vue/server-renderer/index.js')
if (existsSync(serverRendererPath)) { targets.push(serverRendererPath) }
return targets
}, [])
]
: []
}, []),
]
: [],
],
},
alias: {
// Vue 3 mocks
@ -201,7 +201,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
'@babel/parser': 'unenv/runtime/mock/proxy',
'@vue/compiler-core': 'unenv/runtime/mock/proxy',
'@vue/compiler-dom': 'unenv/runtime/mock/proxy',
'@vue/compiler-ssr': 'unenv/runtime/mock/proxy'
'@vue/compiler-ssr': 'unenv/runtime/mock/proxy',
},
'@vue/devtools-api': 'vue-devtools-stub',
@ -209,7 +209,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
'#internal/nuxt/paths': resolve(distDir, 'core/runtime/nitro/paths'),
// Nuxt aliases
...nuxt.options.alias
...nuxt.options.alias,
},
replace: {
'process.env.NUXT_NO_SSR': nuxt.options.ssr === false,
@ -220,13 +220,13 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
'process.env.NUXT_ASYNC_CONTEXT': !!nuxt.options.experimental.asyncContext,
'process.env.NUXT_SHARED_DATA': !!nuxt.options.experimental.sharedPrerenderData,
'process.dev': nuxt.options.dev,
__VUE_PROD_DEVTOOLS__: false
'__VUE_PROD_DEVTOOLS__': false,
},
rollupConfig: {
output: {},
plugins: []
plugins: [],
},
logLevel: logLevelMapReverse[nuxt.options.logLevel]
logLevel: logLevelMapReverse[nuxt.options.logLevel],
} satisfies NitroConfig)
// Resolve user-provided paths
@ -252,14 +252,14 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
{
dir: join(tempDir, 'meta'),
maxAge: 31536000 /* 1 year */,
baseURL: joinURL(manifestPrefix, 'meta')
baseURL: joinURL(manifestPrefix, 'meta'),
},
// latest build
{
dir: tempDir,
maxAge: 1,
baseURL: manifestPrefix
}
baseURL: manifestPrefix,
},
)
nuxt.options.alias['#app-manifest'] = join(tempDir, `meta/${buildId}.json`)
@ -308,7 +308,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
// Add pages prerendered but not covered by route rules
const prerenderedRoutes = new Set<string>()
const routeRulesMatcher = toRouteMatcher(
createRadixRouter({ routes: routeRules })
createRadixRouter({ routes: routeRules }),
)
if (nitro._prerenderedRoutes?.length) {
const payloadSuffix = nuxt.options.experimental.renderJsonPayloads ? '/_payload.json' : '/_payload.js'
@ -327,13 +327,13 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
id: buildId,
timestamp: buildTimestamp,
matcher: exportMatcher(routeRulesMatcher),
prerendered: nuxt.options.dev ? [] : [...prerenderedRoutes]
prerendered: nuxt.options.dev ? [] : [...prerenderedRoutes],
}
await fsp.mkdir(join(tempDir, 'meta'), { recursive: true })
await fsp.writeFile(join(tempDir, 'latest.json'), JSON.stringify({
id: buildId,
timestamp: buildTimestamp
timestamp: buildTimestamp,
}))
await fsp.writeFile(join(tempDir, `meta/${buildId}.json`), JSON.stringify(manifest))
})
@ -362,7 +362,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
nitroConfig.handlers = nitroConfig.handlers || []
nitroConfig.handlers.push({
handler: resolve(distDir, 'core/runtime/nitro/no-ssr'),
middleware: true
middleware: true,
})
}
@ -373,8 +373,8 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
ImportProtectionPlugin.rollup({
rootDir: nuxt.options.rootDir,
patterns: nuxtImportProtections(nuxt, { isNitro: true }),
exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/]
})
exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/],
}),
)
// Extend nitro config with hook
@ -422,8 +422,8 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
'internal:nuxt:prerender': {
// TODO: resolve upstream where file URLs are not being resolved/inlined correctly
driver: isWindows ? pathToFileURL(cacheDriverPath).href : cacheDriverPath,
base: cacheDir
}
base: cacheDir,
},
})
// Expose nitro to modules and kit
@ -446,12 +446,12 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
if (Array.isArray(config.resolve!.alias)) {
config.resolve!.alias.push({
find: 'vue',
replacement: 'vue/dist/vue.esm-bundler'
replacement: 'vue/dist/vue.esm-bundler',
})
} else {
config.resolve!.alias = {
...config.resolve!.alias,
vue: 'vue/dist/vue.esm-bundler'
vue: 'vue/dist/vue.esm-bundler',
}
}
}
@ -462,7 +462,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
if (Array.isArray(clientConfig!.resolve!.alias)) {
clientConfig!.resolve!.alias.push({
name: 'vue',
alias: 'vue/dist/vue.esm-bundler'
alias: 'vue/dist/vue.esm-bundler',
})
} else {
clientConfig!.resolve!.alias!.vue = 'vue/dist/vue.esm-bundler'
@ -477,7 +477,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
nitro.options.handlers.unshift({
route: '/__nuxt_error',
lazy: true,
handler: resolve(distDir, 'core/runtime/nitro/renderer')
handler: resolve(distDir, 'core/runtime/nitro/renderer'),
})
if (!nuxt.options.dev && nuxt.options.experimental.noVueServer) {

View File

@ -10,13 +10,13 @@ import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
import escapeRE from 'escape-string-regexp'
import fse from 'fs-extra'
import { withoutLeadingSlash } from 'ufo'
/* eslint-disable import/no-restricted-paths */
import defu from 'defu'
import pagesModule from '../pages/module'
import metaModule from '../head/module'
import componentsModule from '../components/module'
import importsModule from '../imports/module'
/* eslint-enable */
import { distDir, pkgDir } from '../dirs'
import { version } from '../../package.json'
import { ImportProtectionPlugin, nuxtImportProtections } from './plugins/import-protection'
@ -46,18 +46,18 @@ export function createNuxt (options: NuxtOptions): Nuxt {
ready: () => initNuxt(nuxt),
close: () => Promise.resolve(hooks.callHook('close', nuxt)),
vfs: {},
apps: {}
apps: {},
}
return nuxt
}
const nightlies = {
nitropack: 'nitropack-nightly',
h3: 'h3-nightly',
nuxt: 'nuxt-nightly',
'nitropack': 'nitropack-nightly',
'h3': 'h3-nightly',
'nuxt': 'nuxt-nightly',
'@nuxt/schema': '@nuxt/schema-nightly',
'@nuxt/kit': '@nuxt/kit-nightly'
'@nuxt/kit': '@nuxt/kit-nightly',
}
async function initNuxt (nuxt: Nuxt) {
@ -98,7 +98,7 @@ async function initNuxt (nuxt: Nuxt) {
// Set nitro resolutions for types that might be obscured with shamefully-hoist=false
nuxt.options.nitro.typescript = defu(nuxt.options.nitro.typescript, {
tsConfig: { compilerOptions: { paths: { ...paths } } }
tsConfig: { compilerOptions: { paths: { ...paths } } },
})
// Add nuxt types
@ -132,7 +132,7 @@ async function initNuxt (nuxt: Nuxt) {
rootDir: nuxt.options.rootDir,
// Exclude top-level resolutions by plugins
exclude: [join(nuxt.options.srcDir, 'index.html')],
patterns: nuxtImportProtections(nuxt)
patterns: nuxtImportProtections(nuxt),
}
addVitePlugin(() => ImportProtectionPlugin.vite(config))
addWebpackPlugin(() => ImportProtectionPlugin.webpack(config))
@ -147,7 +147,7 @@ async function initNuxt (nuxt: Nuxt) {
dev: nuxt.options.dev,
root: nuxt.options.srcDir,
// skip top-level layer (user's project) as the aliases will already be correctly resolved
layers: nuxt.options._layers.slice(1)
layers: nuxt.options._layers.slice(1),
}))
addWebpackPlugin(() => LayerAliasingPlugin.webpack({
sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client,
@ -155,7 +155,7 @@ async function initNuxt (nuxt: Nuxt) {
root: nuxt.options.srcDir,
// skip top-level layer (user's project) as the aliases will already be correctly resolved
layers: nuxt.options._layers.slice(1),
transform: true
transform: true,
}))
}
@ -165,8 +165,8 @@ async function initNuxt (nuxt: Nuxt) {
sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client,
transformerOptions: {
...nuxt.options.optimization.asyncTransforms,
helperModule: await tryResolveModule('unctx', nuxt.options.modulesDir) ?? 'unctx'
}
helperModule: await tryResolveModule('unctx', nuxt.options.modulesDir) ?? 'unctx',
},
} satisfies UnctxTransformPluginOptions
addVitePlugin(() => UnctxTransformPlugin.vite(options))
addWebpackPlugin(() => UnctxTransformPlugin.webpack(options))
@ -174,7 +174,7 @@ async function initNuxt (nuxt: Nuxt) {
// Add composable tree-shaking optimisations
const serverTreeShakeOptions: TreeShakeComposablesPluginOptions = {
sourcemap: !!nuxt.options.sourcemap.server,
composables: nuxt.options.optimization.treeShake.composables.server
composables: nuxt.options.optimization.treeShake.composables.server,
}
if (Object.keys(serverTreeShakeOptions.composables).length) {
addVitePlugin(() => TreeShakeComposablesPlugin.vite(serverTreeShakeOptions), { client: false })
@ -182,7 +182,7 @@ async function initNuxt (nuxt: Nuxt) {
}
const clientTreeShakeOptions: TreeShakeComposablesPluginOptions = {
sourcemap: !!nuxt.options.sourcemap.client,
composables: nuxt.options.optimization.treeShake.composables.client
composables: nuxt.options.optimization.treeShake.composables.client,
}
if (Object.keys(clientTreeShakeOptions.composables).length) {
addVitePlugin(() => TreeShakeComposablesPlugin.vite(clientTreeShakeOptions), { server: false })
@ -206,11 +206,11 @@ async function initNuxt (nuxt: Nuxt) {
addServerPlugin(resolve(distDir, 'core/runtime/nitro/dev-server-logs'))
nuxt.options.nitro = defu(nuxt.options.nitro, {
externals: {
inline: [/#internal\/dev-server-logs-options/]
inline: [/#internal\/dev-server-logs-options/],
},
virtual: {
'#internal/dev-server-logs-options': () => `export const rootDir = ${JSON.stringify(nuxt.options.rootDir)};`
}
'#internal/dev-server-logs-options': () => `export const rootDir = ${JSON.stringify(nuxt.options.rootDir)};`,
},
})
}
@ -236,7 +236,7 @@ async function initNuxt (nuxt: Nuxt) {
// Transpile layers within node_modules
nuxt.options.build.transpile.push(
...nuxt.options._layers.filter(i => i.cwd.includes('node_modules')).map(i => i.cwd as string)
...nuxt.options._layers.filter(i => i.cwd.includes('node_modules')).map(i => i.cwd as string),
)
// Init user modules
@ -258,7 +258,7 @@ async function initNuxt (nuxt: Nuxt) {
const modulesDir = (config.rootDir === nuxt.options.rootDir ? nuxt.options : config).dir?.modules || 'modules'
const layerModules = await resolveFiles(config.srcDir, [
`${modulesDir}/*{${nuxt.options.extensions.join(',')}}`,
`${modulesDir}/*/index{${nuxt.options.extensions.join(',')}}`
`${modulesDir}/*/index{${nuxt.options.extensions.join(',')}}`,
])
for (const mod of layerModules) {
watchedPaths.add(mod)
@ -275,55 +275,55 @@ async function initNuxt (nuxt: Nuxt) {
addComponent({
name: 'NuxtWelcome',
priority: 10, // built-in that we do not expect the user to override
filePath: (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue', nuxt.options.modulesDir))!
filePath: (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue', nuxt.options.modulesDir))!,
})
addComponent({
name: 'NuxtLayout',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/nuxt-layout')
filePath: resolve(nuxt.options.appDir, 'components/nuxt-layout'),
})
// Add <NuxtErrorBoundary>
addComponent({
name: 'NuxtErrorBoundary',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/nuxt-error-boundary')
filePath: resolve(nuxt.options.appDir, 'components/nuxt-error-boundary'),
})
// Add <ClientOnly>
addComponent({
name: 'ClientOnly',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/client-only')
filePath: resolve(nuxt.options.appDir, 'components/client-only'),
})
// Add <DevOnly>
addComponent({
name: 'DevOnly',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/dev-only')
filePath: resolve(nuxt.options.appDir, 'components/dev-only'),
})
// Add <ServerPlaceholder>
addComponent({
name: 'ServerPlaceholder',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/server-placeholder')
filePath: resolve(nuxt.options.appDir, 'components/server-placeholder'),
})
// Add <NuxtLink>
addComponent({
name: 'NuxtLink',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/nuxt-link')
filePath: resolve(nuxt.options.appDir, 'components/nuxt-link'),
})
// Add <NuxtLoadingIndicator>
addComponent({
name: 'NuxtLoadingIndicator',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/nuxt-loading-indicator')
filePath: resolve(nuxt.options.appDir, 'components/nuxt-loading-indicator'),
})
// Add <NuxtClientFallback>
@ -333,7 +333,7 @@ async function initNuxt (nuxt: Nuxt) {
_raw: true,
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/client-fallback.client'),
mode: 'client'
mode: 'client',
})
addComponent({
@ -341,7 +341,7 @@ async function initNuxt (nuxt: Nuxt) {
_raw: true,
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/client-fallback.server'),
mode: 'server'
mode: 'server',
})
}
@ -350,7 +350,7 @@ async function initNuxt (nuxt: Nuxt) {
addComponent({
name: 'NuxtIsland',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/nuxt-island')
filePath: resolve(nuxt.options.appDir, 'components/nuxt-island'),
})
if (!nuxt.options.ssr && nuxt.options.experimental.componentIslands !== 'auto') {
@ -368,7 +368,7 @@ async function initNuxt (nuxt: Nuxt) {
priority: -1,
filePath: resolve(nuxt.options.appDir, 'components/nuxt-stubs'),
// @ts-expect-error TODO: refactor to nuxi
_internal_install: '@nuxt/image'
_internal_install: '@nuxt/image',
})
}
@ -414,10 +414,10 @@ async function initNuxt (nuxt: Nuxt) {
'@nuxt/vite-builder': 'vite/client',
'@nuxt/webpack-builder': 'webpack/module',
// simpler overrides from `typescript.builder` for better DX
vite: 'vite/client',
webpack: 'webpack/module',
'vite': 'vite/client',
'webpack': 'webpack/module',
// default 'merged' builder environment for module authors
shared: '@nuxt/schema/builder-env'
'shared': '@nuxt/schema/builder-env',
}
nuxt.hook('prepare:types', ({ references }) => {
@ -451,7 +451,7 @@ async function initNuxt (nuxt: Nuxt) {
addRouteMiddleware({
name: 'manifest-route-rule',
path: resolve(nuxt.options.appDir, 'middleware/manifest-route-rule'),
global: true
global: true,
})
addPlugin(resolve(nuxt.options.appDir, 'plugins/check-outdated-build.client'))
@ -535,7 +535,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
if (options.builder === '@nuxt/webpack-builder') {
if (!await import('./features').then(r => r.ensurePackageInstalled('@nuxt/webpack-builder', {
rootDir: options.rootDir,
searchPaths: options.modulesDir
searchPaths: options.modulesDir,
}))) {
logger.warn('Failed to install `@nuxt/webpack-builder`, please install it manually, or change the `builder` option to vite in `nuxt.config`')
}
@ -547,15 +547,15 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
transform: {
include: options._layers
.filter(i => i.cwd && i.cwd.includes('node_modules'))
.map(i => new RegExp(`(^|\\/)${escapeRE(i.cwd!.split('node_modules/').pop()!)}(\\/|$)(?!node_modules\\/)`))
}
.map(i => new RegExp(`(^|\\/)${escapeRE(i.cwd!.split('node_modules/').pop()!)}(\\/|$)(?!node_modules\\/)`)),
},
}])
options._modules.push(schemaModule)
options.modulesDir.push(resolve(options.workspaceDir, 'node_modules'))
options.modulesDir.push(resolve(pkgDir, 'node_modules'))
options.build.transpile.push(
'@nuxt/ui-templates', // this exposes vue SFCs
'std-env' // we need to statically replace process.env when used in runtime code
'std-env', // we need to statically replace process.env when used in runtime code
)
options.alias['vue-demi'] = resolve(options.appDir, 'compat/vue-demi')
options.alias['@vue/composition-api'] = resolve(options.appDir, 'compat/capi')

View File

@ -21,9 +21,9 @@ export const AsyncContextInjectionPlugin = (nuxt: Nuxt) => createUnplugin(() =>
code: s.toString(),
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})

View File

@ -33,9 +33,9 @@ export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
code: s.toString(),
map: options.sourcemap
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})

View File

@ -18,12 +18,12 @@ export const nuxtImportProtections = (nuxt: { options: NuxtOptions }, options: {
patterns.push([
/^(nuxt|nuxt3|nuxt-nightly)$/,
'`nuxt`, `nuxt3` or `nuxt-nightly` cannot be imported directly.' + (options.isNitro ? '' : ' Instead, import runtime Nuxt composables from `#app` or `#imports`.')
'`nuxt`, `nuxt3` or `nuxt-nightly` cannot be imported directly.' + (options.isNitro ? '' : ' Instead, import runtime Nuxt composables from `#app` or `#imports`.'),
])
patterns.push([
/^((|~|~~|@|@@)\/)?nuxt\.config(\.|$)/,
'Importing directly from a `nuxt.config` file is not allowed. Instead, use runtime config or a module.'
'Importing directly from a `nuxt.config` file is not allowed. Instead, use runtime config or a module.',
])
patterns.push([/(^|node_modules\/)@vue\/composition-api/])
@ -31,7 +31,7 @@ export const nuxtImportProtections = (nuxt: { options: NuxtOptions }, options: {
for (const mod of nuxt.options.modules.filter(m => typeof m === 'string')) {
patterns.push([
new RegExp(`^${escapeRE(mod as string)}$`),
'Importing directly from module entry-points is not allowed.'
'Importing directly from module entry-points is not allowed.',
])
}
@ -48,7 +48,7 @@ export const nuxtImportProtections = (nuxt: { options: NuxtOptions }, options: {
if (!options.isNitro) {
patterns.push([
new RegExp(escapeRE(relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, nuxt.options.serverDir || 'server'))) + '\\/(api|routes|middleware|plugins)\\/'),
'Importing from server is not allowed in the Vue part of your app.'
'Importing from server is not allowed in the Vue part of your app.',
])
}
@ -88,6 +88,6 @@ export const ImportProtectionPlugin = createUnplugin(function (options: ImportPr
return _require.resolve('unenv/runtime/mock/proxy')
}
return null
}
},
}
})

View File

@ -25,7 +25,7 @@ export const LayerAliasingPlugin = createUnplugin((options: LayerAliasingOptions
'~': layer.config?.alias?.['~'] || srcDir,
'@': layer.config?.alias?.['@'] || srcDir,
'~~': layer.config?.alias?.['~~'] || rootDir,
'@@': layer.config?.alias?.['@@'] || rootDir
'@@': layer.config?.alias?.['@@'] || rootDir,
}
}
const layers = Object.keys(aliases).sort((a, b) => b.length - a.length)
@ -46,8 +46,8 @@ export const LayerAliasingPlugin = createUnplugin((options: LayerAliasingOptions
if (resolvedId !== id) {
return await this.resolve(resolvedId, importer, { skipSelf: true })
}
}
}
},
},
},
// webpack-only transform
@ -69,9 +69,9 @@ export const LayerAliasingPlugin = createUnplugin((options: LayerAliasingOptions
if (s.hasChanged()) {
return {
code: s.toString(),
map: options.sourcemap ? s.generateMap({ hires: true }) : undefined
}
map: options.sourcemap ? s.generateMap({ hires: true }) : undefined,
}
}
},
}
})

View File

@ -11,7 +11,6 @@ import MagicString from 'magic-string'
import { normalize } from 'pathe'
import { logger } from '@nuxt/kit'
// eslint-disable-next-line import/no-restricted-paths
import type { ObjectPlugin, PluginMeta } from '#app'
const internalOrderMap = {
@ -32,13 +31,13 @@ const internalOrderMap = {
// +20: post (user) <-- post mapped to this
'user-post': 20,
// +30: post-all (nuxt)
'nuxt-post-all': 30
'nuxt-post-all': 30,
}
export const orderMap: Record<NonNullable<ObjectPlugin['enforce']>, number> = {
pre: internalOrderMap['user-pre'],
default: internalOrderMap['user-default'],
post: internalOrderMap['user-post']
post: internalOrderMap['user-post'],
}
const metaCache: Record<string, Omit<PluginMeta, 'enforce'>> = {}
@ -50,7 +49,7 @@ export async function extractMetadata (code: string, loader = 'ts' as 'ts' | 'ts
const js = await transform(code, { loader })
walk(parse(js.code, {
sourceType: 'module',
ecmaVersion: 'latest'
ecmaVersion: 'latest',
}) as Node, {
enter (_node) {
if (_node.type !== 'CallExpression' || (_node as CallExpression).callee.type !== 'Identifier') { return }
@ -77,7 +76,7 @@ export async function extractMetadata (code: string, loader = 'ts' as 'ts' | 'ts
meta.order = meta.order || orderMap[meta.enforce || 'default'] || orderMap.default
delete meta.enforce
}
},
})
metaCache[code] = meta
return meta as Omit<PluginMeta, 'enforce'>
@ -88,7 +87,7 @@ const keys: Record<PluginMetaKey, string> = {
name: 'name',
order: 'order',
enforce: 'enforce',
dependsOn: 'dependsOn'
dependsOn: 'dependsOn',
}
function isMetadataKey (key: string): key is PluginMetaKey {
return key in keys
@ -134,7 +133,7 @@ export const RemovePluginMetadataPlugin = (nuxt: Nuxt) => createUnplugin(() => {
s.overwrite(0, code.length, 'export default () => {}')
return {
code: s.toString(),
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null,
}
}
@ -144,7 +143,7 @@ export const RemovePluginMetadataPlugin = (nuxt: Nuxt) => createUnplugin(() => {
try {
walk(this.parse(code, {
sourceType: 'module',
ecmaVersion: 'latest'
ecmaVersion: 'latest',
}) as Node, {
enter (_node) {
if (_node.type === 'ImportSpecifier' && (_node.imported.name === 'defineNuxtPlugin' || _node.imported.name === 'definePayloadPlugin')) {
@ -193,7 +192,7 @@ export const RemovePluginMetadataPlugin = (nuxt: Nuxt) => createUnplugin(() => {
}
}
}
}
},
})
} catch (e) {
logger.error(e)
@ -207,9 +206,9 @@ export const RemovePluginMetadataPlugin = (nuxt: Nuxt) => createUnplugin(() => {
if (s.hasChanged()) {
return {
code: s.toString(),
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null
}
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null,
}
}
},
}
})

View File

@ -21,11 +21,11 @@ export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
return await this.resolve?.(id, dir || pkgDir, { skipSelf: true }) ?? await resolvePath(id, {
url: [dir || pkgDir, ...nuxt.options.modulesDir],
// TODO: respect nitro runtime conditions
conditions: options.ssr ? ['node', 'import', 'require'] : ['import', 'require']
conditions: options.ssr ? ['node', 'import', 'require'] : ['import', 'require'],
}).catch(() => {
logger.debug('Could not resolve id', id, importer)
return null
})
}
},
}
}

View File

@ -40,9 +40,9 @@ export const TreeShakeComposablesPlugin = createUnplugin((options: TreeShakeComp
code: s.toString(),
map: options.sourcemap
? s.generateMap({ hires: true })
: undefined
}
: undefined,
}
}
},
}
})

Some files were not shown because too many files have changed in this diff Show More