mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +00:00
chore: cleanup eslint rules with latest @nuxt/eslint-config
(#26653)
This commit is contained in:
parent
ee608cea2c
commit
f209158352
2
.gitignore
vendored
2
.gitignore
vendored
@ -73,3 +73,5 @@ Temporary Items
|
||||
|
||||
fixtures-temp
|
||||
.pnpm-store
|
||||
eslint-typegen.d.ts
|
||||
.eslintcache
|
||||
|
@ -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 [
|
||||
{
|
||||
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'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.vue', '**/*.ts', '**/*.mts', '**/*.js', '**/*.cjs', '**/*.mjs'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
NodeJS: 'readonly',
|
||||
$fetch: 'readonly'
|
||||
}
|
||||
.prepend(
|
||||
{
|
||||
// Ignores have to be a separate object to be treated as global ignores
|
||||
// Don't add other attributes to this object
|
||||
ignores: [
|
||||
'packages/schema/schema/**',
|
||||
],
|
||||
},
|
||||
plugins: {
|
||||
jsdoc,
|
||||
import: esImport,
|
||||
unicorn,
|
||||
'no-only-tests': noOnlyTests
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
$fetch: 'readonly',
|
||||
NodeJS: 'readonly',
|
||||
},
|
||||
},
|
||||
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': [
|
||||
'error',
|
||||
{
|
||||
multiline: 'always',
|
||||
singleline: 'always'
|
||||
}
|
||||
],
|
||||
'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': [
|
||||
'error',
|
||||
'always',
|
||||
{
|
||||
exceptions: ['-']
|
||||
}
|
||||
],
|
||||
'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',
|
||||
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
'jsdoc/require-param': 'off',
|
||||
'jsdoc/require-returns': 'off',
|
||||
'jsdoc/require-param-type': 'off',
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
pathGroups: [
|
||||
{
|
||||
pattern: '#vue-router',
|
||||
group: 'external'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'import/no-restricted-paths': [
|
||||
'error',
|
||||
{
|
||||
zones: [
|
||||
{
|
||||
from: 'packages/nuxt/src/!(core)/**/*',
|
||||
target: 'packages/nuxt/src/core',
|
||||
message: 'core should not directly import from modules.'
|
||||
},
|
||||
{
|
||||
from: 'packages/nuxt/src/!(app)/**/*',
|
||||
target: 'packages/nuxt/src/app',
|
||||
message: 'app should not directly import from modules.'
|
||||
},
|
||||
{
|
||||
from: 'packages/nuxt/src/app/**/index.ts',
|
||||
target: 'packages/nuxt/src',
|
||||
message: 'should not import from barrel/index files'
|
||||
},
|
||||
{
|
||||
from: 'packages/nitro',
|
||||
target: 'packages/!(nitro)/**/*',
|
||||
message: 'nitro should not directly import other packages.'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{
|
||||
disallowTypeAnnotations: false
|
||||
}
|
||||
],
|
||||
.override('nuxt/typescript/rules', {
|
||||
rules: {
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
'error',
|
||||
{
|
||||
'ts-expect-error': 'allow-with-description',
|
||||
'ts-ignore': true
|
||||
}
|
||||
'ts-ignore': true,
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/prefer-ts-expect-error': 'error',
|
||||
'@typescript-eslint/no-dynamic-delete': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
ignoreRestSiblings: true,
|
||||
varsIgnorePattern: '^_',
|
||||
ignoreRestSiblings: true
|
||||
}
|
||||
},
|
||||
],
|
||||
'jsdoc/check-tag-names': [
|
||||
'error',
|
||||
{
|
||||
definedTags: ['__NO_SIDE_EFFECTS__']
|
||||
}
|
||||
]
|
||||
'@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',
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
jsdoc: {
|
||||
ignoreInternal: true,
|
||||
tagNamePreference: {
|
||||
warning: 'warning',
|
||||
note: 'note'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['packages/schema/**'],
|
||||
})
|
||||
|
||||
.override('nuxt/tooling/unicorn', {
|
||||
rules: {
|
||||
'jsdoc/valid-types': 'off',
|
||||
'jsdoc/check-tag-names': [
|
||||
'error',
|
||||
{
|
||||
definedTags: ['experimental']
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['packages/nuxt/src/app/**', 'test/**', '**/runtime/**', '**/*.test.ts'],
|
||||
'unicorn/no-new-array': 'off',
|
||||
'unicorn/prefer-dom-node-text-content': 'off',
|
||||
},
|
||||
})
|
||||
|
||||
.override('nuxt/vue/rules', {
|
||||
rules: {
|
||||
'no-console': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['test/fixtures/**'],
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
// Stylistic rules
|
||||
.override('nuxt/stylistic', {
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'vue/valid-v-for': 'off'
|
||||
}
|
||||
}
|
||||
]
|
||||
'@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(
|
||||
{
|
||||
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',
|
||||
},
|
||||
{
|
||||
from: 'packages/nuxt/src/!(app)/**/*',
|
||||
message: 'app should not directly import from modules.',
|
||||
target: 'packages/nuxt/src/app',
|
||||
},
|
||||
{
|
||||
from: 'packages/nuxt/src/app/**/index.ts',
|
||||
message: 'should not import from barrel/index files',
|
||||
target: 'packages/nuxt/src',
|
||||
},
|
||||
{
|
||||
from: 'packages/nitro',
|
||||
message: 'nitro should not directly import other packages.',
|
||||
target: 'packages/!(nitro)/**/*',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
pathGroups: [
|
||||
{
|
||||
group: 'external',
|
||||
pattern: '#vue-router',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'jsdoc/check-tag-names': [
|
||||
'error',
|
||||
{
|
||||
definedTags: [
|
||||
'experimental',
|
||||
'__NO_SIDE_EFFECTS__',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['packages/nuxt/src/app/**', 'test/**', '**/runtime/**', '**/*.test.ts'],
|
||||
name: 'local/disables/client-console',
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/fixtures/**', '**/fixture/**'],
|
||||
name: 'local/disables/fixtures',
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': '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)
|
||||
})
|
||||
|
@ -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\' })',
|
||||
})
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
})
|
||||
|
14
package.json
14
package.json
@ -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",
|
||||
|
@ -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,
|
||||
})
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ export async function addComponent (opts: AddComponentOptions) {
|
||||
shortPath: opts.filePath,
|
||||
priority: 0,
|
||||
meta: {},
|
||||
...opts
|
||||
...opts,
|
||||
}
|
||||
|
||||
nuxt.hook('components:extend', (components: Component[]) => {
|
||||
|
@ -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',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
@ -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'
|
||||
|
@ -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),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ function normalizeHandlerMethod (handler: NitroEventHandler) {
|
||||
return {
|
||||
method,
|
||||
...handler,
|
||||
handler: normalize(handler.handler)
|
||||
handler: normalize(handler.handler),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 }),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(`
|
||||
[
|
||||
|
@ -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', () => {
|
||||
|
@ -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',
|
||||
],
|
||||
})
|
||||
|
@ -1,8 +1,7 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
function defineNuxtConfig (config) {
|
||||
return config
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
defineNuxtConfig
|
||||
defineNuxtConfig,
|
||||
}
|
||||
|
1
packages/nuxt/config.d.ts
vendored
1
packages/nuxt/config.d.ts
vendored
@ -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> {}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line import/export
|
||||
export * from 'vue'
|
||||
|
||||
export const install = () => {}
|
||||
|
@ -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)
|
||||
}))
|
||||
|
@ -8,7 +8,7 @@ export const setInterval = import.meta.client
|
||||
if (import.meta.dev) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
message: intervalError
|
||||
message: intervalError,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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?.()
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -7,5 +7,5 @@ export default defineComponent({
|
||||
return () => props.slots.default?.()
|
||||
}
|
||||
return () => props.slots.fallback?.()
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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': '' })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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?.()
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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')
|
||||
: ''
|
||||
|
@ -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),
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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>'),
|
||||
}
|
||||
|
@ -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)]
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -4,5 +4,5 @@ export default defineComponent({
|
||||
name: 'ServerPlaceholder',
|
||||
render () {
|
||||
return createElementBlock('div')
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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 }),
|
||||
]),
|
||||
]
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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)
|
||||
|
@ -17,19 +17,19 @@ export type _Transform<Input = any, Output = any> = (input: Input) => Output | P
|
||||
export type PickFrom<T, K extends Array<string>> = T extends Array<any>
|
||||
? T
|
||||
: T extends Record<string, any>
|
||||
? keyof T extends K[number]
|
||||
? T // Exact same keys as the target, skip Pick
|
||||
: K[number] extends never
|
||||
? T
|
||||
: Pick<T, K[number]>
|
||||
: T
|
||||
? keyof T extends K[number]
|
||||
? T // Exact same keys as the target, skip Pick
|
||||
: K[number] extends never
|
||||
? T
|
||||
: Pick<T, K[number]>
|
||||
: T
|
||||
|
||||
export type KeysOf<T> = Array<
|
||||
T extends T // Include all keys of union types, not just common keys
|
||||
? keyof T extends string
|
||||
? keyof T
|
||||
: never
|
||||
: never
|
||||
? keyof T extends string
|
||||
? keyof T
|
||||
: never
|
||||
: never
|
||||
>
|
||||
|
||||
export type KeyOfRes<Transform extends _Transform> = KeysOf<ReturnType<Transform>>
|
||||
@ -223,8 +223,8 @@ export function useAsyncData<
|
||||
|
||||
const promise = nuxtApp.runWithContext(_handler)
|
||||
|
||||
nuxtApp.ssrContext!._sharedPrerenderCache!.set(key, promise)
|
||||
return promise
|
||||
nuxtApp.ssrContext!._sharedPrerenderCache!.set(key, promise)
|
||||
return promise
|
||||
}
|
||||
|
||||
// Used to get default values
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -148,7 +148,7 @@ function createLoadingIndicator (opts: Partial<LoadingIndicatorOpts> = {}) {
|
||||
start,
|
||||
set,
|
||||
finish,
|
||||
clear
|
||||
clear,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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.')
|
||||
|
@ -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)
|
||||
|
@ -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']),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,6 @@ export default defineNuxtPlugin({
|
||||
}
|
||||
},
|
||||
env: {
|
||||
islands: false
|
||||
}
|
||||
islands: false,
|
||||
},
|
||||
})
|
||||
|
@ -30,5 +30,5 @@ export default defineNuxtPlugin({
|
||||
reloadAppAtPath(to)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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()],
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -6,5 +6,5 @@ export default defineNuxtPlugin({
|
||||
enforce: 'pre',
|
||||
setup (nuxtApp) {
|
||||
createDebugger(nuxtApp.hooks, { tag: 'nuxt-app' })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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) {
|
||||
|
@ -32,5 +32,5 @@ export default defineNuxtPlugin({
|
||||
setTimeout(getAppManifest, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -8,7 +8,7 @@ export default defineNuxtPlugin({
|
||||
const { _registeredComponents } = this.$nuxt.ssrContext
|
||||
const { __moduleIdentifier } = this.$options
|
||||
_registeredComponents.add(__moduleIdentifier)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -15,6 +15,6 @@ export default defineNuxtPlugin({
|
||||
} catch {
|
||||
// don't throw an error if we have issues reading sessionStorage
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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])
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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'
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -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)}`)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -99,10 +99,10 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
||||
code: s.toString(),
|
||||
map: options.sourcemap
|
||||
? s.generateMap({ hires: true })
|
||||
: undefined
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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>({
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -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),
|
||||
}),
|
||||
])
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -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),
|
||||
])
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -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}`,
|
||||
)
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -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) {
|
||||
|
@ -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')
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -33,9 +33,9 @@ export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
|
||||
code: s.toString(),
|
||||
map: options.sourcemap
|
||||
? s.generateMap({ hires: true })
|
||||
: undefined
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user