mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
Merge branch 'main' into patch-21
This commit is contained in:
commit
444e5be6e8
224
.eslintrc
224
.eslintrc
@ -1,224 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/eslintrc",
|
|
||||||
"ignorePatterns": [
|
|
||||||
"dist",
|
|
||||||
"public",
|
|
||||||
"node_modules",
|
|
||||||
"packages/schema/schema"
|
|
||||||
],
|
|
||||||
"globals": {
|
|
||||||
"NodeJS": true,
|
|
||||||
"$fetch": true
|
|
||||||
},
|
|
||||||
"plugins": ["jsdoc", "import", "unicorn", "no-only-tests"],
|
|
||||||
"extends": [
|
|
||||||
"standard",
|
|
||||||
"plugin:jsdoc/recommended",
|
|
||||||
"@nuxt/eslint-config",
|
|
||||||
"plugin:import/typescript"
|
|
||||||
],
|
|
||||||
"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
|
|
||||||
"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",
|
|
||||||
"vue/one-component-per-file": "off",
|
|
||||||
"vue/require-default-prop": "off",
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/ban-ts-comment": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"ts-expect-error": "allow-with-description",
|
|
||||||
"ts-ignore": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/prefer-ts-expect-error": "error",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"argsIgnorePattern": "^_",
|
|
||||||
"varsIgnorePattern": "^_",
|
|
||||||
"ignoreRestSiblings": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"jsdoc/check-tag-names": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"definedTags": ["__NO_SIDE_EFFECTS__"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["packages/schema/**"],
|
|
||||||
"rules": {
|
|
||||||
"jsdoc/valid-types": "off",
|
|
||||||
"jsdoc/check-tag-names": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"definedTags": ["experimental"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["packages/nuxt/src/app/**", "test/**", "**/runtime/**"],
|
|
||||||
"rules": {
|
|
||||||
"no-console": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"jsdoc": {
|
|
||||||
"ignoreInternal": true,
|
|
||||||
"tagNamePreference": {
|
|
||||||
"warning": "warning",
|
|
||||||
"note": "note"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -236,7 +236,7 @@ jobs:
|
|||||||
TEST_CONTEXT: ${{ matrix.context }}
|
TEST_CONTEXT: ${{ matrix.context }}
|
||||||
SKIP_BUNDLE_SIZE: ${{ github.event_name != 'push' || matrix.env == 'dev' || matrix.builder == 'webpack' || matrix.context == 'default' || runner.os == 'Windows' }}
|
SKIP_BUNDLE_SIZE: ${{ github.event_name != 'push' || matrix.env == 'dev' || matrix.builder == 'webpack' || matrix.context == 'default' || runner.os == 'Windows' }}
|
||||||
|
|
||||||
- uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
|
- uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0
|
||||||
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
@ -130,12 +130,12 @@ export const useLocale = () => {
|
|||||||
|
|
||||||
export const useDefaultLocale = (fallback = 'en-US') => {
|
export const useDefaultLocale = (fallback = 'en-US') => {
|
||||||
const locale = ref(fallback)
|
const locale = ref(fallback)
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
|
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
|
||||||
if (reqLocale) {
|
if (reqLocale) {
|
||||||
locale.value = reqLocale
|
locale.value = reqLocale
|
||||||
}
|
}
|
||||||
} else if (process.client) {
|
} else if (import.meta.client) {
|
||||||
const navLang = navigator.language
|
const navLang = navigator.language
|
||||||
if (navLang) {
|
if (navLang) {
|
||||||
locale.value = navLang
|
locale.value = navLang
|
||||||
|
@ -125,12 +125,12 @@ However, if you want to avoid this behaviour you can do so:
|
|||||||
```ts twoslash [middleware/example.ts]
|
```ts twoslash [middleware/example.ts]
|
||||||
export default defineNuxtRouteMiddleware(to => {
|
export default defineNuxtRouteMiddleware(to => {
|
||||||
// skip middleware on server
|
// skip middleware on server
|
||||||
if (process.server) return
|
if (import.meta.server) return
|
||||||
// skip middleware on client side entirely
|
// skip middleware on client side entirely
|
||||||
if (process.client) return
|
if (import.meta.client) return
|
||||||
// or only skip middleware on initial client load
|
// or only skip middleware on initial client load
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
if (process.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
|
if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ export default defineNuxtPlugin({
|
|||||||
|
|
||||||
::note
|
::note
|
||||||
If you are using the object-syntax, the properties may be statically analyzed in future to produce a more optimized build. So you should not define them at runtime. :br
|
If you are using the object-syntax, the properties may be statically analyzed in future to produce a more optimized build. So you should not define them at runtime. :br
|
||||||
For example, setting `enforce: process.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
|
For example, setting `enforce: import.meta.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
|
||||||
::
|
::
|
||||||
|
|
||||||
## Registration Order
|
## Registration Order
|
||||||
|
@ -98,7 +98,7 @@ The behavior is different between the client-side and server-side:
|
|||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
console.log('Runtime config:', config)
|
console.log('Runtime config:', config)
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
console.log('API secret:', config.apiSecret)
|
console.log('API secret:', config.apiSecret)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -105,7 +105,7 @@ export default defineNuxtConfig({
|
|||||||
const resolver = createResolver(import.meta.url)
|
const resolver = createResolver(import.meta.url)
|
||||||
// add a route
|
// add a route
|
||||||
files.push({
|
files.push({
|
||||||
path: resolver.resolve('./runtime/app/router-options')
|
path: resolver.resolve('./runtime/app/router-options'),
|
||||||
optional: true
|
optional: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -172,6 +172,6 @@ import { createMemoryHistory } from 'vue-router'
|
|||||||
|
|
||||||
export default <RouterConfig> {
|
export default <RouterConfig> {
|
||||||
// https://router.vuejs.org/api/interfaces/routeroptions.html
|
// https://router.vuejs.org/api/interfaces/routeroptions.html
|
||||||
history: base => process.client ? createMemoryHistory(base) : null /* default */
|
history: base => import.meta.client ? createMemoryHistory(base) : null /* default */
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -51,7 +51,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
})
|
})
|
||||||
nuxtApp.hook('vue:error', (..._args) => {
|
nuxtApp.hook('vue:error', (..._args) => {
|
||||||
console.log('vue:error')
|
console.log('vue:error')
|
||||||
// if (process.client) {
|
// if (import.meta.client) {
|
||||||
// console.log(..._args)
|
// console.log(..._args)
|
||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
@ -120,7 +120,7 @@ Nuxt exposes the following properties through `ssrContext`:
|
|||||||
export const useColor = () => useState<string>('color', () => 'pink')
|
export const useColor = () => useState<string>('color', () => 'pink')
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
const color = useColor()
|
const color = useColor()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -159,7 +159,7 @@ export default defineComponent({
|
|||||||
setup (_props, { slots, emit }) {
|
setup (_props, { slots, emit }) {
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
onErrorCaptured((err) => {
|
onErrorCaptured((err) => {
|
||||||
if (process.client && !nuxtApp.isHydrating) {
|
if (import.meta.client && !nuxtApp.isHydrating) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -117,7 +117,7 @@ import { defineNuxtPlugin } from '#imports'
|
|||||||
import metaConfig from '#build/meta.config.mjs'
|
import metaConfig from '#build/meta.config.mjs'
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
const createHead = process.server ? createServerHead : createClientHead
|
const createHead = import.meta.server ? createServerHead : createClientHead
|
||||||
const head = createHead()
|
const head = createHead()
|
||||||
head.push(metaConfig.globalMeta)
|
head.push(metaConfig.globalMeta)
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
nuxtApp.vueApp.use(VueFire, { firebaseApp })
|
nuxtApp.vueApp.use(VueFire, { firebaseApp })
|
||||||
|
|
||||||
<% if(options.ssr) { %>
|
<% if(options.ssr) { %>
|
||||||
if (process.server) {
|
if (import.meta.server) {
|
||||||
nuxtApp.payload.vuefire = useSSRInitialState(undefined, firebaseApp)
|
nuxtApp.payload.vuefire = useSSRInitialState(undefined, firebaseApp)
|
||||||
} else if (nuxtApp.payload?.vuefire) {
|
} else if (nuxtApp.payload?.vuefire) {
|
||||||
useSSRInitialState(nuxtApp.payload.vuefire, firebaseApp)
|
useSSRInitialState(nuxtApp.payload.vuefire, firebaseApp)
|
||||||
|
280
eslint.config.mjs
Normal file
280
eslint.config.mjs
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
// 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'
|
||||||
|
import noOnlyTests from 'eslint-plugin-no-only-tests'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
jsdoc,
|
||||||
|
import: esImport,
|
||||||
|
unicorn,
|
||||||
|
'no-only-tests': noOnlyTests
|
||||||
|
},
|
||||||
|
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
|
||||||
|
'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',
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'@typescript-eslint/ban-ts-comment': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'ts-expect-error': 'allow-with-description',
|
||||||
|
'ts-ignore': true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'@typescript-eslint/prefer-ts-expect-error': 'error',
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
ignoreRestSiblings: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'jsdoc/check-tag-names': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
definedTags: ['__NO_SIDE_EFFECTS__']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
jsdoc: {
|
||||||
|
ignoreInternal: true,
|
||||||
|
tagNamePreference: {
|
||||||
|
warning: 'warning',
|
||||||
|
note: 'note'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['packages/schema/**'],
|
||||||
|
rules: {
|
||||||
|
'jsdoc/valid-types': 'off',
|
||||||
|
'jsdoc/check-tag-names': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
definedTags: ['experimental']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['packages/nuxt/src/app/**', 'test/**', '**/runtime/**', '**/*.test.ts'],
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/fixtures/**'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'vue/valid-v-for': 'off'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
22
package.json
22
package.json
@ -13,8 +13,8 @@
|
|||||||
"cleanup": "rimraf 'packages/**/node_modules' 'playground/node_modules' 'node_modules'",
|
"cleanup": "rimraf 'packages/**/node_modules' 'playground/node_modules' 'node_modules'",
|
||||||
"dev": "pnpm play",
|
"dev": "pnpm play",
|
||||||
"dev:prepare": "pnpm --filter './packages/**' prepack --stub",
|
"dev:prepare": "pnpm --filter './packages/**' prepack --stub",
|
||||||
"lint": "eslint --ext .vue,.ts,.js,.mjs .",
|
"lint": "eslint .",
|
||||||
"lint:fix": "eslint --ext .vue,.ts,.js,.mjs . --fix",
|
"lint:fix": "eslint . --fix",
|
||||||
"lint:docs": "markdownlint ./docs && case-police 'docs/**/*.md' *.md",
|
"lint:docs": "markdownlint ./docs && case-police 'docs/**/*.md' *.md",
|
||||||
"lint:docs:fix": "markdownlint ./docs --fix && case-police 'docs/**/*.md' *.md --fix",
|
"lint:docs:fix": "markdownlint ./docs --fix && case-police 'docs/**/*.md' *.md --fix",
|
||||||
"lint:knip": "pnpx knip",
|
"lint:knip": "pnpx knip",
|
||||||
@ -37,20 +37,22 @@
|
|||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"@nuxt/vite-builder": "workspace:*",
|
"@nuxt/vite-builder": "workspace:*",
|
||||||
"@nuxt/webpack-builder": "workspace:*",
|
"@nuxt/webpack-builder": "workspace:*",
|
||||||
"rollup": "^4.13.2",
|
"rollup": "^4.14.0",
|
||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"vite": "5.2.7",
|
"vite": "5.2.8",
|
||||||
"vue": "3.4.21",
|
"vue": "3.4.21",
|
||||||
"magic-string": "^0.30.8"
|
"magic-string": "^0.30.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "3.0.2",
|
||||||
|
"@eslint/js": "8.57.0",
|
||||||
"@nuxt/eslint-config": "0.2.0",
|
"@nuxt/eslint-config": "0.2.0",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@nuxt/test-utils": "3.12.0",
|
"@nuxt/test-utils": "3.12.0",
|
||||||
"@nuxt/webpack-builder": "workspace:*",
|
"@nuxt/webpack-builder": "workspace:*",
|
||||||
"@testing-library/vue": "8.0.3",
|
"@testing-library/vue": "8.0.3",
|
||||||
"@types/fs-extra": "11.0.4",
|
"@types/fs-extra": "11.0.4",
|
||||||
"@types/node": "20.12.2",
|
"@types/node": "20.12.4",
|
||||||
"@types/semver": "7.5.8",
|
"@types/semver": "7.5.8",
|
||||||
"@vitest/coverage-v8": "1.4.0",
|
"@vitest/coverage-v8": "1.4.0",
|
||||||
"@vue/test-utils": "2.4.5",
|
"@vue/test-utils": "2.4.5",
|
||||||
@ -63,15 +65,15 @@
|
|||||||
"eslint-plugin-import": "2.29.1",
|
"eslint-plugin-import": "2.29.1",
|
||||||
"eslint-plugin-jsdoc": "48.2.2",
|
"eslint-plugin-jsdoc": "48.2.2",
|
||||||
"eslint-plugin-no-only-tests": "3.1.0",
|
"eslint-plugin-no-only-tests": "3.1.0",
|
||||||
"eslint-plugin-unicorn": "51.0.1",
|
"eslint-plugin-unicorn": "52.0.0",
|
||||||
"execa": "8.0.1",
|
"execa": "8.0.1",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
"globby": "14.0.1",
|
"globby": "14.0.1",
|
||||||
"h3": "1.11.1",
|
"h3": "1.11.1",
|
||||||
"happy-dom": "14.3.9",
|
"happy-dom": "14.4.0",
|
||||||
"jiti": "1.21.0",
|
"jiti": "1.21.0",
|
||||||
"markdownlint-cli": "0.39.0",
|
"markdownlint-cli": "0.39.0",
|
||||||
"nitropack": "2.9.5",
|
"nitropack": "2.9.6",
|
||||||
"nuxi": "3.11.1",
|
"nuxi": "3.11.1",
|
||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"nuxt-content-twoslash": "0.0.10",
|
"nuxt-content-twoslash": "0.0.10",
|
||||||
@ -89,7 +91,7 @@
|
|||||||
"vue-router": "4.3.0",
|
"vue-router": "4.3.0",
|
||||||
"vue-tsc": "2.0.7"
|
"vue-tsc": "2.0.7"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.15.5",
|
"packageManager": "pnpm@8.15.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.18.0 || >=16.10.0"
|
"node": "^14.18.0 || >=16.10.0"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/kit",
|
"name": "@nuxt/kit",
|
||||||
"version": "3.11.1",
|
"version": "3.11.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nuxt/nuxt.git",
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
||||||
@ -50,9 +50,9 @@
|
|||||||
"@types/lodash-es": "4.17.12",
|
"@types/lodash-es": "4.17.12",
|
||||||
"@types/semver": "7.5.8",
|
"@types/semver": "7.5.8",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"nitropack": "2.9.5",
|
"nitropack": "2.9.6",
|
||||||
"unbuild": "latest",
|
"unbuild": "latest",
|
||||||
"vite": "5.2.7",
|
"vite": "5.2.8",
|
||||||
"vitest": "1.4.0",
|
"vitest": "1.4.0",
|
||||||
"webpack": "5.91.0"
|
"webpack": "5.91.0"
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable jsdoc/require-jsdoc */
|
||||||
function defineNuxtConfig (config) {
|
function defineNuxtConfig (config) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nuxt",
|
"name": "nuxt",
|
||||||
"version": "3.11.1",
|
"version": "3.11.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nuxt/nuxt.git",
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
||||||
@ -64,11 +64,11 @@
|
|||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"@nuxt/telemetry": "^2.5.3",
|
"@nuxt/telemetry": "^2.5.3",
|
||||||
"@nuxt/ui-templates": "^1.3.1",
|
"@nuxt/ui-templates": "^1.3.2",
|
||||||
"@nuxt/vite-builder": "workspace:*",
|
"@nuxt/vite-builder": "workspace:*",
|
||||||
"@unhead/dom": "^1.9.3",
|
"@unhead/dom": "^1.9.4",
|
||||||
"@unhead/ssr": "^1.9.3",
|
"@unhead/ssr": "^1.9.4",
|
||||||
"@unhead/vue": "^1.9.3",
|
"@unhead/vue": "^1.9.4",
|
||||||
"@vue/shared": "^3.4.21",
|
"@vue/shared": "^3.4.21",
|
||||||
"acorn": "8.11.3",
|
"acorn": "8.11.3",
|
||||||
"c12": "^1.10.0",
|
"c12": "^1.10.0",
|
||||||
@ -87,9 +87,9 @@
|
|||||||
"jiti": "^1.21.0",
|
"jiti": "^1.21.0",
|
||||||
"klona": "^2.0.6",
|
"klona": "^2.0.6",
|
||||||
"knitwork": "^1.1.0",
|
"knitwork": "^1.1.0",
|
||||||
"magic-string": "^0.30.8",
|
"magic-string": "^0.30.9",
|
||||||
"mlly": "^1.6.1",
|
"mlly": "^1.6.1",
|
||||||
"nitropack": "^2.9.5",
|
"nitropack": "^2.9.6",
|
||||||
"nuxi": "^3.11.1",
|
"nuxi": "^3.11.1",
|
||||||
"nypm": "^0.3.8",
|
"nypm": "^0.3.8",
|
||||||
"ofetch": "^1.3.4",
|
"ofetch": "^1.3.4",
|
||||||
@ -122,7 +122,7 @@
|
|||||||
"@types/fs-extra": "11.0.4",
|
"@types/fs-extra": "11.0.4",
|
||||||
"@vitejs/plugin-vue": "5.0.4",
|
"@vitejs/plugin-vue": "5.0.4",
|
||||||
"unbuild": "latest",
|
"unbuild": "latest",
|
||||||
"vite": "5.2.7",
|
"vite": "5.2.8",
|
||||||
"vitest": "1.4.0"
|
"vitest": "1.4.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// eslint-disable-next-line import/export
|
||||||
export * from 'vue'
|
export * from 'vue'
|
||||||
|
|
||||||
export const install = () => {}
|
export const install = () => {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { computed, getCurrentInstance, onBeforeMount, onServerPrefetch, onUnmounted, ref, shallowRef, toRef, unref, watch } from 'vue'
|
import { computed, getCurrentInstance, getCurrentScope, onBeforeMount, onScopeDispose, onServerPrefetch, onUnmounted, ref, shallowRef, toRef, unref, watch } from 'vue'
|
||||||
import type { Ref, WatchSource } from 'vue'
|
import type { Ref, WatchSource } from 'vue'
|
||||||
import type { NuxtApp } from '../nuxt'
|
import type { NuxtApp } from '../nuxt'
|
||||||
import { useNuxtApp } from '../nuxt'
|
import { useNuxtApp } from '../nuxt'
|
||||||
@ -370,16 +370,20 @@ export function useAsyncData<
|
|||||||
// 4. Navigation (lazy: false) - or plugin usage: await fetch
|
// 4. Navigation (lazy: false) - or plugin usage: await fetch
|
||||||
initialFetch()
|
initialFetch()
|
||||||
}
|
}
|
||||||
|
const hasScope = getCurrentScope()
|
||||||
if (options.watch) {
|
if (options.watch) {
|
||||||
watch(options.watch, () => asyncData.refresh())
|
const unsub = watch(options.watch, () => asyncData.refresh())
|
||||||
|
if (hasScope) {
|
||||||
|
onScopeDispose(unsub)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const off = nuxtApp.hook('app:data:refresh', async (keys) => {
|
const off = nuxtApp.hook('app:data:refresh', async (keys) => {
|
||||||
if (!keys || keys.includes(key)) {
|
if (!keys || keys.includes(key)) {
|
||||||
await asyncData.refresh()
|
await asyncData.refresh()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (instance) {
|
if (hasScope) {
|
||||||
onUnmounted(off)
|
onScopeDispose(off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +85,7 @@ const isProcessingMiddleware = () => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Within an async middleware
|
return false
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import MagicString from 'magic-string'
|
|||||||
import { ELEMENT_NODE, parse, walk } from 'ultrahtml'
|
import { ELEMENT_NODE, parse, walk } from 'ultrahtml'
|
||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
import { resolvePath } from '@nuxt/kit'
|
import { resolvePath } from '@nuxt/kit'
|
||||||
|
import defu from 'defu'
|
||||||
import { isVue } from '../core/utils'
|
import { isVue } from '../core/utils'
|
||||||
|
|
||||||
interface ServerOnlyComponentTransformPluginOptions {
|
interface ServerOnlyComponentTransformPluginOptions {
|
||||||
@ -146,7 +147,7 @@ export const islandsTransform = createUnplugin((options: ServerOnlyComponentTran
|
|||||||
* extract attributes from a node
|
* extract attributes from a node
|
||||||
*/
|
*/
|
||||||
function extractAttributes (attributes: Record<string, string>, names: string[]) {
|
function extractAttributes (attributes: Record<string, string>, names: string[]) {
|
||||||
const extracted:Record<string, string> = {}
|
const extracted: Record<string, string> = {}
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
if (name in attributes) {
|
if (name in attributes) {
|
||||||
extracted[name] = attributes[name]
|
extracted[name] = attributes[name]
|
||||||
@ -182,15 +183,27 @@ export const componentsChunkPlugin = createUnplugin((options: ComponentChunkOpti
|
|||||||
vite: {
|
vite: {
|
||||||
async config (config) {
|
async config (config) {
|
||||||
const components = options.getComponents()
|
const components = options.getComponents()
|
||||||
config.build = config.build || {}
|
|
||||||
config.build.rollupOptions = config.build.rollupOptions || {}
|
config.build = defu(config.build, {
|
||||||
config.build.rollupOptions.output = config.build.rollupOptions.output || {}
|
rollupOptions: {
|
||||||
config.build.rollupOptions.input = config.build.rollupOptions.input || {}
|
input: {},
|
||||||
|
output: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const rollupOptions = config.build.rollupOptions!
|
||||||
|
|
||||||
|
if (typeof rollupOptions.input === 'string') {
|
||||||
|
rollupOptions.input = { entry: rollupOptions.input }
|
||||||
|
} else if (typeof rollupOptions.input === 'object' && Array.isArray(rollupOptions.input)) {
|
||||||
|
rollupOptions.input = rollupOptions.input.reduce<{ [key: string]: string }>((acc, input) => { acc[input] = input; return acc }, {})
|
||||||
|
}
|
||||||
|
|
||||||
// don't use 'strict', this would create another "facade" chunk for the entry file, causing the ssr styles to not detect everything
|
// don't use 'strict', this would create another "facade" chunk for the entry file, causing the ssr styles to not detect everything
|
||||||
config.build.rollupOptions.preserveEntrySignatures = 'allow-extension'
|
rollupOptions.preserveEntrySignatures = 'allow-extension'
|
||||||
for (const component of components) {
|
for (const component of components) {
|
||||||
if (component.mode === 'client' || component.mode === 'all') {
|
if (component.mode === 'client' || component.mode === 'all') {
|
||||||
(config.build.rollupOptions.input as Record<string, string>)[component.pascalName] = await resolvePath(component.filePath)
|
rollupOptions.input![component.pascalName] = await resolvePath(component.filePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@ import { createUnplugin } from 'unplugin'
|
|||||||
import { parseURL } from 'ufo'
|
import { parseURL } from 'ufo'
|
||||||
import { parseQuery } from 'vue-router'
|
import { parseQuery } from 'vue-router'
|
||||||
import { normalize, resolve } from 'pathe'
|
import { normalize, resolve } from 'pathe'
|
||||||
|
import { genImport } from 'knitwork'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../dirs'
|
||||||
import type { getComponentsT } from './module'
|
import type { getComponentsT } from './module'
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
|
|||||||
const components = getComponents(mode)
|
const components = getComponents(mode)
|
||||||
return components.flatMap((c): Import[] => {
|
return components.flatMap((c): Import[] => {
|
||||||
const withMode = (mode: string | undefined) => mode
|
const withMode = (mode: string | undefined) => mode
|
||||||
? `${c.filePath}${c.filePath.includes('?') ? '&' : '?'}nuxt_component=${mode}&nuxt_component_name=${c.pascalName}`
|
? `${c.filePath}${c.filePath.includes('?') ? '&' : '?'}nuxt_component=${mode}&nuxt_component_name=${c.pascalName}&nuxt_component_export=${c.export || 'default'}`
|
||||||
: c.filePath
|
: c.filePath
|
||||||
|
|
||||||
const mode = !c._raw && c.mode && ['client', 'server'].includes(c.mode) ? c.mode : undefined
|
const mode = !c._raw && c.mode && ['client', 'server'].includes(c.mode) ? c.mode : undefined
|
||||||
@ -60,20 +61,22 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
|
|||||||
const query = parseQuery(search)
|
const query = parseQuery(search)
|
||||||
const mode = query.nuxt_component
|
const mode = query.nuxt_component
|
||||||
const bare = id.replace(/\?.*/, '')
|
const bare = id.replace(/\?.*/, '')
|
||||||
|
const componentExport = query.nuxt_component_export as string || 'default'
|
||||||
|
const exportWording = componentExport === 'default' ? 'export default' : `export const ${componentExport} =`
|
||||||
if (mode === 'async') {
|
if (mode === 'async') {
|
||||||
return {
|
return {
|
||||||
code: [
|
code: [
|
||||||
'import { defineAsyncComponent } from "vue"',
|
'import { defineAsyncComponent } from "vue"',
|
||||||
`export default defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r.default))`
|
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))`
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
map: null
|
map: null
|
||||||
}
|
}
|
||||||
} else if (mode === 'client') {
|
} else if (mode === 'client') {
|
||||||
return {
|
return {
|
||||||
code: [
|
code: [
|
||||||
`import __component from ${JSON.stringify(bare)}`,
|
genImport(bare, [{ name: componentExport, as: '__component' }]),
|
||||||
'import { createClientOnly } from "#app/components/client-only"',
|
'import { createClientOnly } from "#app/components/client-only"',
|
||||||
'export default createClientOnly(__component)'
|
`${exportWording} createClientOnly(__component)`
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
map: null
|
map: null
|
||||||
}
|
}
|
||||||
@ -82,7 +85,7 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
|
|||||||
code: [
|
code: [
|
||||||
'import { defineAsyncComponent } from "vue"',
|
'import { defineAsyncComponent } from "vue"',
|
||||||
'import { createClientOnly } from "#app/components/client-only"',
|
'import { createClientOnly } from "#app/components/client-only"',
|
||||||
`export default defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r.default)))`
|
`${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))`
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
map: null
|
map: null
|
||||||
}
|
}
|
||||||
@ -91,7 +94,7 @@ export function createTransformPlugin (nuxt: Nuxt, getComponents: getComponentsT
|
|||||||
return {
|
return {
|
||||||
code: [
|
code: [
|
||||||
`import { createServerComponent } from ${JSON.stringify(serverComponentRuntime)}`,
|
`import { createServerComponent } from ${JSON.stringify(serverComponentRuntime)}`,
|
||||||
`export default createServerComponent(${JSON.stringify(name)})`
|
`${exportWording} createServerComponent(${JSON.stringify(name)})`
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
map: null
|
map: null
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ function isComponentNotCalledInSetup (codeAst: Node, name: string): string | voi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve the component identifier being used on ssrRender callExpression
|
* retrieve the component identifier being used on ssrRender callExpression
|
||||||
* @param {CallExpression} ssrRenderNode - ssrRender callExpression
|
* @param ssrRenderNode - ssrRender callExpression
|
||||||
*/
|
*/
|
||||||
function getComponentName (ssrRenderNode: AcornNode<CallExpression>): string {
|
function getComponentName (ssrRenderNode: AcornNode<CallExpression>): string {
|
||||||
const componentCall = ssrRenderNode.arguments[0] as Identifier | MemberExpression | CallExpression
|
const componentCall = ssrRenderNode.arguments[0] as Identifier | MemberExpression | CallExpression
|
||||||
|
@ -12,6 +12,7 @@ import escapeRE from 'escape-string-regexp'
|
|||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import fsExtra from 'fs-extra'
|
import fsExtra from 'fs-extra'
|
||||||
import { dynamicEventHandler } from 'h3'
|
import { dynamicEventHandler } from 'h3'
|
||||||
|
import { isWindows } from 'std-env'
|
||||||
import type { Nuxt, NuxtOptions, RuntimeConfig } from 'nuxt/schema'
|
import type { Nuxt, NuxtOptions, RuntimeConfig } from 'nuxt/schema'
|
||||||
// @ts-expect-error TODO: add legacy type support for subpath imports
|
// @ts-expect-error TODO: add legacy type support for subpath imports
|
||||||
import { template as defaultSpaLoadingTemplate } from '@nuxt/ui-templates/templates/spa-loading-icon.mjs'
|
import { template as defaultSpaLoadingTemplate } from '@nuxt/ui-templates/templates/spa-loading-icon.mjs'
|
||||||
@ -416,10 +417,12 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const cacheDir = resolve(nuxt.options.buildDir, 'cache/nitro/prerender')
|
const cacheDir = resolve(nuxt.options.buildDir, 'cache/nitro/prerender')
|
||||||
|
const cacheDriverPath = await resolvePath(join(distDir, 'core/runtime/nitro/cache-driver'))
|
||||||
await fsp.rm(cacheDir, { recursive: true, force: true }).catch(() => {})
|
await fsp.rm(cacheDir, { recursive: true, force: true }).catch(() => {})
|
||||||
nitro.options._config.storage = defu(nitro.options._config.storage, {
|
nitro.options._config.storage = defu(nitro.options._config.storage, {
|
||||||
'internal:nuxt:prerender': {
|
'internal:nuxt:prerender': {
|
||||||
driver: pathToFileURL(await resolvePath(join(distDir, 'core/runtime/nitro/cache-driver'))).href,
|
// TODO: resolve upstream where file URLs are not being resolved/inlined correctly
|
||||||
|
driver: isWindows ? pathToFileURL(cacheDriverPath).href : cacheDriverPath,
|
||||||
base: cacheDir
|
base: cacheDir
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
createWebHistory
|
createWebHistory
|
||||||
} from '#vue-router'
|
} from '#vue-router'
|
||||||
import { createError } from 'h3'
|
import { createError } from 'h3'
|
||||||
import { isEqual, withoutBase } from 'ufo'
|
import { isEqual, isSamePath, withoutBase } from 'ufo'
|
||||||
|
|
||||||
import type { PageMeta } from '../composables'
|
import type { PageMeta } from '../composables'
|
||||||
|
|
||||||
@ -70,9 +70,6 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
const routes = routerOptions.routes?.(_routes) ?? _routes
|
const routes = routerOptions.routes?.(_routes) ?? _routes
|
||||||
|
|
||||||
let startPosition: Parameters<RouterScrollBehavior>[2] | null
|
let startPosition: Parameters<RouterScrollBehavior>[2] | null
|
||||||
const initialURL = import.meta.server
|
|
||||||
? nuxtApp.ssrContext!.url
|
|
||||||
: createCurrentLocation(routerBase, window.location, nuxtApp.payload.path)
|
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
...routerOptions,
|
...routerOptions,
|
||||||
@ -111,8 +108,12 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
get: () => previousRoute.value
|
get: () => previousRoute.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const initialURL = import.meta.server
|
||||||
|
? nuxtApp.ssrContext!.url
|
||||||
|
: createCurrentLocation(routerBase, window.location, nuxtApp.payload.path)
|
||||||
|
|
||||||
// Allows suspending the route object until page navigation completes
|
// Allows suspending the route object until page navigation completes
|
||||||
const _route = shallowRef(router.resolve(initialURL) as RouteLocation)
|
const _route = shallowRef(router.currentRoute.value)
|
||||||
const syncCurrentRoute = () => { _route.value = router.currentRoute.value }
|
const syncCurrentRoute = () => { _route.value = router.currentRoute.value }
|
||||||
nuxtApp.hook('page:finish', syncCurrentRoute)
|
nuxtApp.hook('page:finish', syncCurrentRoute)
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
@ -138,19 +139,21 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
named: {}
|
named: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const error = useError()
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (import.meta.server) {
|
if (import.meta.server) {
|
||||||
await router.push(initialURL)
|
await router.push(initialURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// We'll catch 404s here
|
// We'll catch 404s here
|
||||||
await nuxtApp.runWithContext(() => showError(error))
|
await nuxtApp.runWithContext(() => showError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resolvedInitialRoute = import.meta.client && initialURL !== router.currentRoute.value.fullPath
|
||||||
|
? router.resolve(initialURL)
|
||||||
|
: router.currentRoute.value
|
||||||
|
syncCurrentRoute()
|
||||||
|
|
||||||
if (import.meta.server && nuxtApp.ssrContext?.islandContext) {
|
if (import.meta.server && nuxtApp.ssrContext?.islandContext) {
|
||||||
// We're in an island context, and don't need to handle middleware or redirections
|
// We're in an island context, and don't need to handle middleware or redirections
|
||||||
return { provide: { router } }
|
return { provide: { router } }
|
||||||
@ -225,6 +228,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
await nuxtApp.callHook('page:loading:end')
|
await nuxtApp.callHook('page:loading:end')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const error = useError()
|
||||||
router.afterEach(async (to, _from, failure) => {
|
router.afterEach(async (to, _from, failure) => {
|
||||||
delete nuxtApp._processingMiddleware
|
delete nuxtApp._processingMiddleware
|
||||||
|
|
||||||
@ -247,18 +251,19 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
path: to.fullPath
|
path: to.fullPath
|
||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
} else if (import.meta.server && to.redirectedFrom && to.fullPath !== initialURL) {
|
} else if (import.meta.server && to.fullPath !== initialURL && (to.redirectedFrom || !isSamePath(to.fullPath, initialURL))) {
|
||||||
await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/'))
|
await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
nuxtApp.hooks.hookOnce('app:created', async () => {
|
nuxtApp.hooks.hookOnce('app:created', async () => {
|
||||||
try {
|
try {
|
||||||
const to = router.resolve(initialURL)
|
|
||||||
// #4920, #4982
|
// #4920, #4982
|
||||||
if ('name' in to) { to.name = undefined }
|
if ('name' in resolvedInitialRoute) {
|
||||||
|
resolvedInitialRoute.name = undefined
|
||||||
|
}
|
||||||
await router.replace({
|
await router.replace({
|
||||||
...to,
|
...resolvedInitialRoute,
|
||||||
force: true
|
force: true
|
||||||
})
|
})
|
||||||
// reset scroll behavior to initial value
|
// reset scroll behavior to initial value
|
||||||
|
112
packages/nuxt/test/components-transform.test.ts
Normal file
112
packages/nuxt/test/components-transform.test.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import type { Component, Nuxt } from '@nuxt/schema'
|
||||||
|
import { kebabCase } from 'scule'
|
||||||
|
|
||||||
|
import { createTransformPlugin } from '../src/components/transform'
|
||||||
|
|
||||||
|
describe('components:transform', () => {
|
||||||
|
it('should transform #components imports', async () => {
|
||||||
|
const transform = createTransformer([
|
||||||
|
createComponent('Foo'),
|
||||||
|
createComponent('Bar', { export: 'Bar' })
|
||||||
|
])
|
||||||
|
|
||||||
|
const code = await transform('import { Foo, Bar } from \'#components\'', '/app.vue')
|
||||||
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"import Foo from '/Foo.vue';
|
||||||
|
import { Bar } from '/Bar.vue';
|
||||||
|
"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should correctly resolve server-only components', async () => {
|
||||||
|
const transform = createTransformer([
|
||||||
|
createComponent('Foo', { mode: 'server' })
|
||||||
|
])
|
||||||
|
|
||||||
|
const code = await transform('import { Foo, LazyFoo } from \'#components\'', '/app.vue')
|
||||||
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"import Foo from '/Foo.vue?nuxt_component=server&nuxt_component_name=Foo&nuxt_component_export=default';
|
||||||
|
import LazyFoo from '/Foo.vue?nuxt_component=server,async&nuxt_component_name=Foo&nuxt_component_export=default';
|
||||||
|
"
|
||||||
|
`)
|
||||||
|
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=server&nuxt_component_name=Foo&nuxt_component_export=default')).toMatchInlineSnapshot(`
|
||||||
|
"import { createServerComponent } from "<repo>/nuxt/src/components/runtime/server-component"
|
||||||
|
export default createServerComponent("Foo")"
|
||||||
|
`)
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=server,async&nuxt_component_name=Foo&nuxt_component_export=default')).toMatchInlineSnapshot(`
|
||||||
|
"import { createServerComponent } from "<repo>/nuxt/src/components/runtime/server-component"
|
||||||
|
export default createServerComponent("Foo")"
|
||||||
|
`)
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=server&nuxt_component_name=Foo&nuxt_component_export=Foo')).toMatchInlineSnapshot(`
|
||||||
|
"import { createServerComponent } from "<repo>/nuxt/src/components/runtime/server-component"
|
||||||
|
export const Foo = createServerComponent("Foo")"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should correctly resolve client-only components', async () => {
|
||||||
|
const transform = createTransformer([
|
||||||
|
createComponent('Foo', { mode: 'client' })
|
||||||
|
])
|
||||||
|
|
||||||
|
const code = await transform('import { Foo, LazyFoo } from \'#components\'', '/app.vue')
|
||||||
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"import Foo from '/Foo.vue?nuxt_component=client&nuxt_component_name=Foo&nuxt_component_export=default';
|
||||||
|
import LazyFoo from '/Foo.vue?nuxt_component=client,async&nuxt_component_name=Foo&nuxt_component_export=default';
|
||||||
|
"
|
||||||
|
`)
|
||||||
|
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=client&nuxt_component_name=Foo&nuxt_component_export=default')).toMatchInlineSnapshot(`
|
||||||
|
"import { default as __component } from "/Foo.vue";
|
||||||
|
import { createClientOnly } from "#app/components/client-only"
|
||||||
|
export default createClientOnly(__component)"
|
||||||
|
`)
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=client,async&nuxt_component_name=Foo&nuxt_component_export=default')).toMatchInlineSnapshot(`
|
||||||
|
"import { defineAsyncComponent } from "vue"
|
||||||
|
import { createClientOnly } from "#app/components/client-only"
|
||||||
|
export default defineAsyncComponent(() => import("/Foo.vue").then(r => createClientOnly(r["default"] || r.default || r)))"
|
||||||
|
`)
|
||||||
|
expect(await transform('', '/Foo.vue?nuxt_component=client,async&nuxt_component_name=Foo&nuxt_component_export=Foo')).toMatchInlineSnapshot(`
|
||||||
|
"import { defineAsyncComponent } from "vue"
|
||||||
|
import { createClientOnly } from "#app/components/client-only"
|
||||||
|
export const Foo = defineAsyncComponent(() => import("/Foo.vue").then(r => createClientOnly(r["Foo"] || r.default || r)))"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const rootDir = fileURLToPath(new URL('../..', import.meta.url))
|
||||||
|
|
||||||
|
function createTransformer (components: Component[], mode: 'client' | 'server' | 'all' = 'all') {
|
||||||
|
const stubNuxt = {
|
||||||
|
options: {
|
||||||
|
buildDir: '/',
|
||||||
|
sourcemap: {
|
||||||
|
server: false,
|
||||||
|
client: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as Nuxt
|
||||||
|
const plugin = createTransformPlugin(stubNuxt, () => components, mode).vite()
|
||||||
|
|
||||||
|
return async (code: string, id: string) => {
|
||||||
|
const result = await (plugin as any).transform!(code, id)
|
||||||
|
return (typeof result === 'string' ? result : result?.code)?.replaceAll(rootDir, '<repo>/')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createComponent (pascalName: string, options: Partial<Component> = {}) {
|
||||||
|
return {
|
||||||
|
filePath: `/${pascalName}.vue`,
|
||||||
|
pascalName,
|
||||||
|
export: 'default',
|
||||||
|
chunkName: `components/${pascalName.toLowerCase()}`,
|
||||||
|
kebabName: kebabCase(pascalName),
|
||||||
|
mode: 'all',
|
||||||
|
prefetch: false,
|
||||||
|
preload: false,
|
||||||
|
shortPath: `components/${pascalName}.vue`,
|
||||||
|
...options
|
||||||
|
} satisfies Component
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference types="nitropack" />
|
/// <reference types="nitropack" />
|
||||||
export * from './dist/index.js'
|
|
||||||
|
|
||||||
import type { DefineNuxtConfig } from 'nuxt/config'
|
import type { DefineNuxtConfig } from 'nuxt/config'
|
||||||
import type { RuntimeConfig, SchemaDefinition } from 'nuxt/schema'
|
import type { RuntimeConfig, SchemaDefinition } from 'nuxt/schema'
|
||||||
@ -7,6 +6,8 @@ import type { H3Event } from 'h3'
|
|||||||
import type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from './dist/app/types.js'
|
import type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from './dist/app/types.js'
|
||||||
import type { LogObject } from 'consola'
|
import type { LogObject } from 'consola'
|
||||||
|
|
||||||
|
export * from './dist/index.js'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
const defineNuxtConfig: DefineNuxtConfig
|
const defineNuxtConfig: DefineNuxtConfig
|
||||||
const defineNuxtSchema: (schema: SchemaDefinition) => SchemaDefinition
|
const defineNuxtSchema: (schema: SchemaDefinition) => SchemaDefinition
|
||||||
|
@ -56,6 +56,7 @@ export default defineBuildConfig({
|
|||||||
'@vue/language-core',
|
'@vue/language-core',
|
||||||
// Implicit
|
// Implicit
|
||||||
'@vue/compiler-core',
|
'@vue/compiler-core',
|
||||||
|
'@vue/compiler-sfc',
|
||||||
'@vue/shared',
|
'@vue/shared',
|
||||||
'untyped'
|
'untyped'
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/schema",
|
"name": "@nuxt/schema",
|
||||||
"version": "3.11.1",
|
"version": "3.11.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nuxt/nuxt.git",
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
||||||
@ -38,30 +38,31 @@
|
|||||||
"@types/file-loader": "5.0.4",
|
"@types/file-loader": "5.0.4",
|
||||||
"@types/pug": "2.0.10",
|
"@types/pug": "2.0.10",
|
||||||
"@types/sass-loader": "8.0.8",
|
"@types/sass-loader": "8.0.8",
|
||||||
"@unhead/schema": "1.9.3",
|
"@unhead/schema": "1.9.4",
|
||||||
"@vitejs/plugin-vue": "5.0.4",
|
"@vitejs/plugin-vue": "5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "3.1.0",
|
"@vitejs/plugin-vue-jsx": "3.1.0",
|
||||||
"@vue/compiler-core": "3.4.21",
|
"@vue/compiler-core": "3.4.21",
|
||||||
|
"@vue/compiler-sfc": "3.4.21",
|
||||||
"@vue/language-core": "2.0.7",
|
"@vue/language-core": "2.0.7",
|
||||||
"c12": "1.10.0",
|
"c12": "1.10.0",
|
||||||
"esbuild-loader": "4.1.0",
|
"esbuild-loader": "4.1.0",
|
||||||
"h3": "1.11.1",
|
"h3": "1.11.1",
|
||||||
"ignore": "5.3.1",
|
"ignore": "5.3.1",
|
||||||
"nitropack": "2.9.5",
|
"nitropack": "2.9.6",
|
||||||
"ofetch": "1.3.4",
|
"ofetch": "1.3.4",
|
||||||
"unbuild": "latest",
|
"unbuild": "latest",
|
||||||
"unctx": "2.3.1",
|
"unctx": "2.3.1",
|
||||||
"unenv": "1.9.0",
|
"unenv": "1.9.0",
|
||||||
"vite": "5.2.7",
|
"vite": "5.2.8",
|
||||||
"vue": "3.4.21",
|
"vue": "3.4.21",
|
||||||
"vue-bundle-renderer": "2.0.0",
|
"vue-bundle-renderer": "2.0.0",
|
||||||
"vue-loader": "17.4.2",
|
"vue-loader": "17.4.2",
|
||||||
"vue-router": "4.3.0",
|
"vue-router": "4.3.0",
|
||||||
"webpack": "5.91.0",
|
"webpack": "5.91.0",
|
||||||
"webpack-dev-middleware": "7.2.0"
|
"webpack-dev-middleware": "7.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui-templates": "^1.3.1",
|
"@nuxt/ui-templates": "^1.3.2",
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"hookable": "^5.5.3",
|
"hookable": "^5.5.3",
|
||||||
|
@ -8,6 +8,14 @@ export default defineUntypedSchema({
|
|||||||
* Vue.js config
|
* Vue.js config
|
||||||
*/
|
*/
|
||||||
vue: {
|
vue: {
|
||||||
|
/** @type {typeof import('@vue/compiler-sfc').AssetURLTagConfig} */
|
||||||
|
transformAssetUrls: {
|
||||||
|
video: ['src', 'poster'],
|
||||||
|
source: ['src'],
|
||||||
|
img: ['src'],
|
||||||
|
image: ['xlink:href', 'href'],
|
||||||
|
use: ['xlink:href', 'href']
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Options for the Vue compiler that will be passed at build time.
|
* Options for the Vue compiler that will be passed at build time.
|
||||||
* @see [documentation](https://vuejs.org/api/application.html#app-config-compileroptions)
|
* @see [documentation](https://vuejs.org/api/application.html#app-config-compileroptions)
|
||||||
|
@ -43,6 +43,7 @@ export default defineUntypedSchema({
|
|||||||
'@unhead/vue',
|
'@unhead/vue',
|
||||||
'vue',
|
'vue',
|
||||||
'@vue/runtime-core',
|
'@vue/runtime-core',
|
||||||
|
'@vue/compiler-sfc',
|
||||||
'@vue/runtime-dom',
|
'@vue/runtime-dom',
|
||||||
'vue-router',
|
'vue-router',
|
||||||
'@nuxt/schema',
|
'@nuxt/schema',
|
||||||
@ -78,6 +79,9 @@ export default defineUntypedSchema({
|
|||||||
*
|
*
|
||||||
* We recommend instead letting the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
* We recommend instead letting the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||||
* generate accurate types for your components.
|
* generate accurate types for your components.
|
||||||
|
*
|
||||||
|
* Note that you may wish to set this to `true` if you are using other libraries, such as ESLint,
|
||||||
|
* that are unable to understand the type of `.vue` files.
|
||||||
*/
|
*/
|
||||||
shim: false
|
shim: false
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,17 @@ export default defineUntypedSchema({
|
|||||||
template: {
|
template: {
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
$resolve: async (val, get) => val ?? (await get('vue') as Record<string, any>).compilerOptions
|
$resolve: async (val, get) => val ?? (await get('vue') as Record<string, any>).compilerOptions
|
||||||
|
},
|
||||||
|
transformAssetUrls: {
|
||||||
|
$resolve: async (val, get) => val ?? (await get('vue') as Record<string, any>).transformAssetUrls
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
script: {
|
script: {
|
||||||
propsDestructure: {
|
propsDestructure: {
|
||||||
$resolve: async (val, get) => val ?? Boolean((await get('vue') as Record<string, any>).propsDestructure)
|
$resolve: async (val, get) => val ?? Boolean((await get('vue') as Record<string, any>).propsDestructure)
|
||||||
|
},
|
||||||
|
hoistStatic: {
|
||||||
|
$resolve: async (val, get) => val ?? (await get('vue') as Record<string, any>).compilerOptions?.hoistStatic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { defineUntypedSchema } from 'untyped'
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
import type { VueLoaderOptions } from 'vue-loader'
|
||||||
|
|
||||||
export default defineUntypedSchema({
|
export default defineUntypedSchema({
|
||||||
webpack: {
|
webpack: {
|
||||||
@ -200,14 +201,15 @@ export default defineUntypedSchema({
|
|||||||
*/
|
*/
|
||||||
vue: {
|
vue: {
|
||||||
transformAssetUrls: {
|
transformAssetUrls: {
|
||||||
video: 'src',
|
$resolve: async (val, get) => (val ?? (await get('vue.transformAssetUrls'))) as VueLoaderOptions['transformAssetUrls']
|
||||||
source: 'src',
|
|
||||||
object: 'src',
|
|
||||||
embed: 'src'
|
|
||||||
},
|
},
|
||||||
compilerOptions: { $resolve: async (val, get) => val ?? (await get('vue.compilerOptions')) },
|
compilerOptions: {
|
||||||
propsDestructure: { $resolve: async (val, get) => val ?? Boolean(await get('vue.propsDestructure')) }
|
$resolve: async (val, get) => (val ?? (await get('vue.compilerOptions'))) as VueLoaderOptions['compilerOptions']
|
||||||
},
|
},
|
||||||
|
propsDestructure: {
|
||||||
|
$resolve: async (val, get) => Boolean(val ?? await get('vue.propsDestructure'))
|
||||||
|
}
|
||||||
|
} satisfies { [K in keyof VueLoaderOptions]: { $resolve: (val: unknown, get: (id: string) => Promise<unknown>) => Promise<VueLoaderOptions[K]> } },
|
||||||
|
|
||||||
css: {
|
css: {
|
||||||
importLoaders: 0,
|
importLoaders: 0,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/vite-builder",
|
"name": "@nuxt/vite-builder",
|
||||||
"version": "3.11.1",
|
"version": "3.11.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nuxt/nuxt.git",
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
||||||
@ -49,7 +49,7 @@
|
|||||||
"get-port-please": "^3.1.2",
|
"get-port-please": "^3.1.2",
|
||||||
"h3": "^1.11.1",
|
"h3": "^1.11.1",
|
||||||
"knitwork": "^1.1.0",
|
"knitwork": "^1.1.0",
|
||||||
"magic-string": "^0.30.8",
|
"magic-string": "^0.30.9",
|
||||||
"mlly": "^1.6.1",
|
"mlly": "^1.6.1",
|
||||||
"ohash": "^1.1.3",
|
"ohash": "^1.1.3",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"ufo": "^1.5.3",
|
"ufo": "^1.5.3",
|
||||||
"unenv": "^1.9.0",
|
"unenv": "^1.9.0",
|
||||||
"unplugin": "^1.10.1",
|
"unplugin": "^1.10.1",
|
||||||
"vite": "^5.2.7",
|
"vite": "^5.2.8",
|
||||||
"vite-node": "^1.4.0",
|
"vite-node": "^1.4.0",
|
||||||
"vite-plugin-checker": "^0.6.4",
|
"vite-plugin-checker": "^0.6.4",
|
||||||
"vue-bundle-renderer": "^2.0.0"
|
"vue-bundle-renderer": "^2.0.0"
|
||||||
|
@ -112,17 +112,6 @@ export const bundle: NuxtBuilder['bundle'] = async (nuxt) => {
|
|||||||
}),
|
}),
|
||||||
virtual(nuxt.vfs)
|
virtual(nuxt.vfs)
|
||||||
],
|
],
|
||||||
vue: {
|
|
||||||
template: {
|
|
||||||
transformAssetUrls: {
|
|
||||||
video: ['src', 'poster'],
|
|
||||||
source: ['src'],
|
|
||||||
img: ['src'],
|
|
||||||
image: ['xlink:href', 'href'],
|
|
||||||
use: ['xlink:href', 'href']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
server: {
|
server: {
|
||||||
watch: { ignored: isIgnored },
|
watch: { ignored: isIgnored },
|
||||||
fs: {
|
fs: {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/webpack-builder",
|
"name": "@nuxt/webpack-builder",
|
||||||
"version": "3.11.1",
|
"version": "3.11.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/nuxt/nuxt.git",
|
"url": "git+https://github.com/nuxt/nuxt.git",
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"@nuxt/friendly-errors-webpack-plugin": "^2.6.0",
|
"@nuxt/friendly-errors-webpack-plugin": "^2.6.0",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"css-loader": "^6.10.0",
|
"css-loader": "^6.11.0",
|
||||||
"css-minimizer-webpack-plugin": "^6.0.0",
|
"css-minimizer-webpack-plugin": "^6.0.0",
|
||||||
"cssnano": "^6.1.2",
|
"cssnano": "^6.1.2",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
@ -41,8 +41,8 @@
|
|||||||
"h3": "^1.11.1",
|
"h3": "^1.11.1",
|
||||||
"hash-sum": "^2.0.0",
|
"hash-sum": "^2.0.0",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"magic-string": "^0.30.8",
|
"magic-string": "^0.30.9",
|
||||||
"memfs": "^4.8.0",
|
"memfs": "^4.8.1",
|
||||||
"mini-css-extract-plugin": "^2.8.1",
|
"mini-css-extract-plugin": "^2.8.1",
|
||||||
"mlly": "^1.6.1",
|
"mlly": "^1.6.1",
|
||||||
"ohash": "^1.1.3",
|
"ohash": "^1.1.3",
|
||||||
@ -64,7 +64,7 @@
|
|||||||
"vue-loader": "^17.4.2",
|
"vue-loader": "^17.4.2",
|
||||||
"webpack": "^5.91.0",
|
"webpack": "^5.91.0",
|
||||||
"webpack-bundle-analyzer": "^4.10.1",
|
"webpack-bundle-analyzer": "^4.10.1",
|
||||||
"webpack-dev-middleware": "^7.2.0",
|
"webpack-dev-middleware": "^7.2.1",
|
||||||
"webpack-hot-middleware": "^2.26.1",
|
"webpack-hot-middleware": "^2.26.1",
|
||||||
"webpack-virtual-modules": "^0.6.1",
|
"webpack-virtual-modules": "^0.6.1",
|
||||||
"webpackbar": "^6.0.1"
|
"webpackbar": "^6.0.1"
|
||||||
|
826
pnpm-lock.yaml
826
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
const serverDir = join(rootDir, '.output/server')
|
const serverDir = join(rootDir, '.output/server')
|
||||||
|
|
||||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"208k"')
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"209k"')
|
||||||
|
|
||||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"1335k"')
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"1335k"')
|
||||||
@ -72,10 +72,10 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
const serverDir = join(rootDir, '.output-inline/server')
|
const serverDir = join(rootDir, '.output-inline/server')
|
||||||
|
|
||||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"526k"')
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"527k"')
|
||||||
|
|
||||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"75.5k"')
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"75.6k"')
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
|
2
test/fixtures/basic/pages/preview/index.vue
vendored
2
test/fixtures/basic/pages/preview/index.vue
vendored
@ -4,7 +4,7 @@ const { enabled: isPreview } = usePreviewMode()
|
|||||||
const { data } = await useAsyncData(async () => {
|
const { data } = await useAsyncData(async () => {
|
||||||
await new Promise(resolve => setTimeout(resolve, 200))
|
await new Promise(resolve => setTimeout(resolve, 200))
|
||||||
|
|
||||||
const fetchedOnClient = process.client
|
const fetchedOnClient = import.meta.client
|
||||||
|
|
||||||
console.log(fetchedOnClient)
|
console.log(fetchedOnClient)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user