Compare commits

...

21 Commits

Author SHA1 Message Date
Peter Buglavecz
8612666471
Merge branch 'main' into main 2024-11-20 21:45:38 +01:00
renovate[bot]
edc299a043
chore(deps): update all non-major dependencies (main) (#29995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 06:35:43 -05:00
renovate[bot]
ad3ab4d310
chore(deps): update all non-major dependencies (main) (#29986)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 23:36:17 -05:00
Jan-Niklas W.
9bf8465806
docs: update getting started to include WebStorm (#29845) 2024-11-19 20:39:14 +00:00
renovate[bot]
f94d3f2bc6
chore(deps): update resolutions @types/node to v22.9.1 (main) (#29981)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 15:32:36 -05:00
renovate[bot]
9c8cd4b74b
chore(deps): update devdependency eslint-plugin-perfectionist to v4 (main) (#29982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Roe <daniel@roe.dev>
2024-11-19 15:32:33 -05:00
Daniel Roe
cf8142b734
test: add import protection test 2024-11-19 13:59:38 -05:00
renovate[bot]
644449409c
chore(deps): update lycheeverse/lychee-action digest to 4aa18b6 (main) (#29976)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 13:59:20 -05:00
renovate[bot]
7b8cca82c8
chore(deps): update devdependency @rspack/core to v1.1.2 (main) (#29977)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 13:59:08 -05:00
Daniel Roe
270dfb8c63
fix(nuxt): do not disallow importing nitro dependencies (#29975) 2024-11-19 16:47:58 +00:00
Daniel Roe
e87f6d3057
fix(nuxt): allow scanning metadata from 2+ files at same path (#29969) 2024-11-19 12:00:57 +00:00
renovate[bot]
da9218da84
chore(deps): update all non-major dependencies (main) (#29950)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 11:53:54 +00:00
Daniel Roe
02b57d49db
refactor(nuxt): define layouts as async vue components (#29957) 2024-11-17 17:06:03 -05:00
Daniel Roe
67456810be
fix(nuxt): do not include <NuxtWelcome> when building (#29956)
Co-authored-by: Julien Huang <julien.huang@outlook.fr>
2024-11-17 21:48:26 +00:00
Daniel Roe
4924e26329
fix(nuxt): recompile templates on change events (#29954) 2024-11-17 21:22:59 +00:00
Daniel Roe
e9f7cb7f89
fix(kit): resolve module paths before appending subpaths (#29955) 2024-11-17 21:20:42 +00:00
Daniel Roe
0a660e8d9d
ci: remove release-pr workflow 2024-11-17 15:11:24 -05:00
Daniel Roe
68b93222a2
fix(nuxt): return null map for empty plugin metadata 2024-11-17 15:05:13 -05:00
Daniel Roe
595b960fda
fix(vite): use resolved nuxt template dst to invalidate modules 2024-11-17 14:38:31 -05:00
Daniel Roe
45824edeee
fix(nuxt): handle empty plugin files 2024-11-17 14:38:31 -05:00
renovate[bot]
93dacc0562
chore(deps): update all non-major dependencies (main) (#29933)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Roe <daniel@roe.dev>
2024-11-17 10:41:21 -05:00
26 changed files with 1200 additions and 1194 deletions

View File

@ -248,7 +248,7 @@ jobs:
TEST_PAYLOAD: ${{ matrix.payload }}
SKIP_BUNDLE_SIZE: ${{ github.event_name != 'push' || matrix.env == 'dev' || matrix.builder == 'webpack' || matrix.context == 'default' || matrix.payload == 'js' || runner.os == 'Windows' }}
- uses: codecov/codecov-action@5c47607acb93fed5485fdbf7232e8a31425f672a # v5.0.2
- uses: codecov/codecov-action@985343d70564a82044c1b7fcb84c2fa05405c1a2 # v5.0.4
if: github.event_name != 'push' && matrix.env == 'built' && matrix.builder == 'vite' && matrix.context == 'default' && matrix.os == 'ubuntu-latest' && matrix.manifest == 'manifest-on'
with:
token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Lychee link checker
uses: lycheeverse/lychee-action@5cd5ba7877bce8b3973756ae3c9474ce1e50be2f # for v1.8.0
uses: lycheeverse/lychee-action@4aa18b6ccdac05029fab067313a6a04f941e6494 # for v1.8.0
with:
# arguments with file types to check
args: >-

View File

@ -1,84 +0,0 @@
name: release-pr
on:
issue_comment:
types: [created]
env:
# 7 GiB by default on GitHub, setting to 6 GiB
NODE_OPTIONS: --max-old-space-size=6144
permissions:
contents: read
jobs:
release-pr:
if: github.repository == 'nuxt/nuxt' && github.event.issue.pull_request && github.event.comment.body == '/trigger release'
concurrency:
group: release
permissions:
id-token: write
pull-requests: write
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Ensure action is by maintainer
uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0
id: check_role
with:
route: GET /repos/nuxt/nuxt/collaborators/${{ github.event.comment.user.login }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get PR Info
id: pr
env:
PR_NUMBER: ${{ github.event.issue.number }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
COMMENT_AT: ${{ github.event.comment.created_at }}
run: |
pr="$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/"${GH_REPO}"/pulls/"${PR_NUMBER}")"
head_sha="$(echo "$pr" | jq -r .head.sha)"
updated_at="$(echo "$pr" | jq -r .updated_at)"
if [[ $(date -d "$updated_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then
exit 1
fi
echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ steps.pr.outputs.head_sha }}
fetch-depth: 1
- run: corepack enable
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 20
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Release Edge
run: ./scripts/release-edge.sh pr-${{ github.event.issue.number }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
NPM_CONFIG_PROVENANCE: true
- name: Post comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `:rocket: Release triggered! You can now install [nuxt@npm:nuxt-nightly@pr-${{ github.event.issue.number }}](https://www.npmjs.com/package/nuxt-nightly/v/pr-${{ github.event.issue.number }})`
})

View File

@ -21,8 +21,8 @@ Or follow the steps below to set up a new Nuxt project on your computer.
<!-- markdownlint-disable-next-line MD001 -->
#### Prerequisites
- **Node.js** - [`v18.0.0`](https://nodejs.org/en) or newer
- **Text editor** - We recommend [Visual Studio Code](https://code.visualstudio.com/) with the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously known as Volar)
- **Node.js** - [`18.x`](https://nodejs.org/en) or newer (but we recommend the [active LTS release](https://github.com/nodejs/release#release-schedule))
- **Text editor** - There is no IDE requirement, but we recommend [Visual Studio Code](https://code.visualstudio.com/) with the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously known as Volar) or [WebStorm](https://www.jetbrains.com/webstorm/), which, along with [other JetBrains IDEs](https://www.jetbrains.com/ides/), offers great Nuxt support right out-of-the-box.
- **Terminal** - In order to run Nuxt commands
::note

View File

@ -189,7 +189,6 @@ export default createConfigForNuxt({
},
},
// Sort rule keys in eslint config
// @ts-expect-error incorrect types 🤔
{
files: ['**/eslint.config.mjs'],
name: 'local/sort-eslint-config',

View File

@ -40,42 +40,42 @@
"@nuxt/ui-templates": "workspace:*",
"@nuxt/vite-builder": "workspace:*",
"@nuxt/webpack-builder": "workspace:*",
"@types/node": "22.9.0",
"@types/node": "22.9.1",
"@unhead/dom": "1.11.11",
"@unhead/shared": "1.11.11",
"@unhead/vue": "1.11.11",
"@unhead/schema": "1.11.11",
"@unhead/ssr": "1.11.11",
"@vue/compiler-core": "3.5.12",
"@vue/compiler-dom": "3.5.12",
"@vue/shared": "3.5.12",
"@vue/compiler-core": "3.5.13",
"@vue/compiler-dom": "3.5.13",
"@vue/shared": "3.5.13",
"c12": "2.0.1",
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
"jiti": "2.4.0",
"magic-string": "^0.30.12",
"magic-string": "^0.30.13",
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
"nuxt": "workspace:*",
"ohash": "1.1.4",
"postcss": "8.4.49",
"rollup": "4.26.0",
"rollup": "4.27.3",
"send": ">=1.1.0",
"typescript": "5.6.3",
"ufo": "1.5.4",
"unbuild": "3.0.0-rc.11",
"unhead": "1.11.11",
"vite": "5.4.11",
"vue": "3.5.12"
"vue": "3.5.13"
},
"devDependencies": {
"@eslint/js": "9.14.0",
"@nuxt/eslint-config": "0.6.1",
"@eslint/js": "9.15.0",
"@nuxt/eslint-config": "0.7.1",
"@nuxt/kit": "workspace:*",
"@nuxt/rspack-builder": "workspace:*",
"@nuxt/test-utils": "3.14.4",
"@nuxt/webpack-builder": "workspace:*",
"@testing-library/vue": "8.1.0",
"@types/eslint__js": "8.42.3",
"@types/node": "22.9.0",
"@types/node": "22.9.1",
"@types/semver": "7.5.8",
"@unhead/schema": "1.11.11",
"@unhead/vue": "1.11.11",
@ -89,9 +89,9 @@
"cssnano": "7.0.6",
"destr": "2.0.3",
"devalue": "5.1.1",
"eslint": "9.14.0",
"eslint": "9.15.0",
"eslint-plugin-no-only-tests": "3.3.0",
"eslint-plugin-perfectionist": "3.9.1",
"eslint-plugin-perfectionist": "4.0.3",
"eslint-typegen": "0.3.2",
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
"happy-dom": "15.11.6",
@ -103,10 +103,10 @@
"nuxt-content-twoslash": "0.1.1",
"ofetch": "1.4.1",
"pathe": "1.1.2",
"playwright-core": "1.48.2",
"playwright-core": "1.49.0",
"rimraf": "6.0.1",
"semver": "7.6.3",
"sherif": "1.0.1",
"sherif": "1.0.2",
"std-env": "3.8.0",
"tinyexec": "0.3.1",
"tinyglobby": "0.2.10",
@ -114,11 +114,11 @@
"ufo": "1.5.4",
"vitest": "2.1.5",
"vitest-environment-nuxt": "1.0.1",
"vue": "3.5.12",
"vue": "3.5.13",
"vue-router": "4.4.5",
"vue-tsc": "2.1.10"
},
"packageManager": "pnpm@9.13.2",
"packageManager": "pnpm@9.14.1",
"engines": {
"node": "^16.10.0 || >=18.0.0"
},

View File

@ -48,7 +48,7 @@
"untyped": "^1.5.1"
},
"devDependencies": {
"@rspack/core": "1.1.1",
"@rspack/core": "1.1.2",
"@types/hash-sum": "1.0.2",
"@types/semver": "7.5.8",
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",

View File

@ -5,6 +5,7 @@ import { dirname, isAbsolute, join, resolve } from 'pathe'
import { defu } from 'defu'
import { createJiti } from 'jiti'
import { resolve as resolveModule } from 'mlly'
import { isRelative } from 'ufo'
import { useNuxt } from '../context'
import { resolveAlias, resolvePath } from '../resolve'
import { logger } from '../logger'
@ -78,14 +79,23 @@ export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, n
// Import if input is string
if (typeof nuxtModule === 'string') {
const paths = [join(nuxtModule, 'nuxt'), join(nuxtModule, 'module'), nuxtModule, join(nuxt.options.rootDir, nuxtModule)]
const paths = new Set<string>()
nuxtModule = resolveAlias(nuxtModule, nuxt.options.alias)
if (isRelative(nuxtModule)) {
nuxtModule = resolve(nuxt.options.rootDir, nuxtModule)
}
paths.add(join(nuxtModule, 'nuxt'))
paths.add(join(nuxtModule, 'module'))
paths.add(nuxtModule)
for (const path of paths) {
for (const parentURL of nuxt.options.modulesDir) {
try {
const resolved = resolveAlias(path, nuxt.options.alias)
const src = isAbsolute(resolved)
? pathToFileURL(await resolvePath(resolved, { cwd: parentURL, fallbackToOriginal: false, extensions: nuxt.options.extensions })).href
: await resolveModule(resolved, { url: pathToFileURL(parentURL.replace(/\/node_modules\/?$/, '')), extensions: nuxt.options.extensions })
const src = isAbsolute(path)
? pathToFileURL(await resolvePath(path, { cwd: parentURL, fallbackToOriginal: false, extensions: nuxt.options.extensions })).href
: await resolveModule(path, { url: pathToFileURL(parentURL.replace(/\/node_modules\/?$/, '')), extensions: nuxt.options.extensions })
nuxtModule = await jiti.import(src, { default: true }) as NuxtModule

View File

@ -69,7 +69,7 @@
"@unhead/shared": "^1.11.11",
"@unhead/ssr": "^1.11.11",
"@unhead/vue": "^1.11.11",
"@vue/shared": "^3.5.12",
"@vue/shared": "^3.5.13",
"acorn": "8.14.0",
"c12": "^2.0.1",
"chokidar": "^4.0.1",
@ -91,7 +91,7 @@
"jiti": "^2.4.0",
"klona": "^2.0.6",
"knitwork": "^1.1.0",
"magic-string": "^0.30.12",
"magic-string": "^0.30.13",
"mlly": "^1.7.3",
"nanotar": "^0.1.1",
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
@ -119,7 +119,7 @@
"unplugin-vue-router": "^0.10.8",
"unstorage": "^1.13.1",
"untyped": "^1.5.1",
"vue": "^3.5.12",
"vue": "^3.5.13",
"vue-bundle-renderer": "^2.1.1",
"vue-devtools-stub": "^0.1.0",
"vue-router": "^4.4.5"
@ -130,7 +130,7 @@
"@parcel/watcher": "2.5.0",
"@types/estree": "1.0.6",
"@vitejs/plugin-vue": "5.2.0",
"@vue/compiler-sfc": "3.5.12",
"@vue/compiler-sfc": "3.5.13",
"unbuild": "3.0.0-rc.11",
"vite": "5.4.11",
"vitest": "2.1.5"

View File

@ -16,7 +16,6 @@ import layouts from '#build/layouts'
// @ts-expect-error virtual file
import { appLayoutTransition as defaultLayoutTransition } from '#build/nuxt.config.mjs'
// TODO: revert back to defineAsyncComponent when https://github.com/vuejs/core/issues/6638 is resolved
const LayoutLoader = defineComponent({
name: 'LayoutLoader',
inheritAttrs: false,
@ -24,13 +23,10 @@ const LayoutLoader = defineComponent({
name: String,
layoutProps: Object,
},
async setup (props, context) {
setup (props, context) {
// This is a deliberate hack - this component must always be called with an explicit key to ensure
// that setup reruns when the name changes.
const LayoutComponent = await layouts[props.name]().then((r: any) => r.default || r)
return () => h(LayoutComponent, props.layoutProps, context.slots)
return () => h(layouts[props.name], props.layoutProps, context.slots)
},
})

View File

@ -10,7 +10,6 @@ import { generateApp as _generateApp, createApp } from './app'
import { checkForExternalConfigurationFiles } from './external-config-files'
import { cleanupCaches, getVueHash } from './cache'
const IS_RESTART_PATH_RE = /^(?:app\.|error\.|plugins\/|middleware\/|layouts\/)/i
export async function build (nuxt: Nuxt) {
const app = createApp(nuxt)
nuxt.apps.default = app
@ -21,19 +20,24 @@ export async function build (nuxt: Nuxt) {
if (nuxt.options.dev) {
watch(nuxt)
nuxt.hook('builder:watch', async (event, relativePath) => {
if (event === 'change') { return }
const path = resolve(nuxt.options.srcDir, relativePath)
const relativePaths = nuxt.options._layers.map(l => relative(l.config.srcDir || l.cwd, path))
const restartPath = relativePaths.find(relativePath => IS_RESTART_PATH_RE.test(relativePath))
if (restartPath) {
if (restartPath.startsWith('app')) {
app.mainComponent = undefined
// Unset mainComponent and errorComponent if app or error component is changed
if (event === 'add' || event === 'unlink') {
const path = resolve(nuxt.options.srcDir, relativePath)
for (const layer of nuxt.options._layers) {
const relativePath = relative(layer.config.srcDir || layer.cwd, path)
if (relativePath.match(/^app\./i)) {
app.mainComponent = undefined
break
}
if (relativePath.match(/^error\./i)) {
app.errorComponent = undefined
break
}
}
if (restartPath.startsWith('error')) {
app.errorComponent = undefined
}
await generateApp()
}
// Recompile app templates
await generateApp()
})
nuxt.hook('builder:generateApp', (options) => {
// Bypass debounce if we are selectively invalidating templates

View File

@ -408,11 +408,15 @@ async function initNuxt (nuxt: Nuxt) {
}
// Add <NuxtWelcome>
addComponent({
name: 'NuxtWelcome',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/welcome'),
})
// TODO: revert when deep server component config is properly bundle-split: https://github.com/nuxt/nuxt/pull/29956
const islandsConfig = nuxt.options.experimental.componentIslands
if (nuxt.options.dev || !(typeof islandsConfig === 'object' && islandsConfig.selectiveClient === 'deep')) {
addComponent({
name: 'NuxtWelcome',
priority: 10, // built-in that we do not expect the user to override
filePath: resolve(nuxt.options.appDir, 'components/welcome'),
})
}
addComponent({
name: 'NuxtLayout',

View File

@ -36,7 +36,7 @@ export const createImportProtectionPatterns = (nuxt: { options: NuxtOptions }, o
])
}
for (const i of [/(^|node_modules\/)@nuxt\/(kit|test-utils)/, /(^|node_modules\/)nuxi/, /(^|node_modules\/)nitro(?:pack)?(?:-nightly)?(?:$|\/)(?!(?:dist\/)?(?:presets|runtime|types))/, /(^|node_modules\/)nuxt\/(config|kit|schema)/]) {
for (const i of [/(^|node_modules\/)@nuxt\/(kit|test-utils)/, /(^|node_modules\/)nuxi/, /(^|node_modules\/)nitro(?:pack)?(?:-nightly)?(?:$|\/)(?!(?:dist\/)?(?:node_modules|presets|runtime|types))/, /(^|node_modules\/)nuxt\/(config|kit|schema)/]) {
patterns.push([i, `This module cannot be imported in ${context}.`])
}

View File

@ -125,18 +125,26 @@ export const RemovePluginMetadataPlugin = (nuxt: Nuxt) => createUnplugin(() => {
const plugin = nuxt.apps.default?.plugins.find(p => p.src === id)
if (!plugin) { return }
const s = new MagicString(code)
if (!code.trim()) {
logger.warn(`Plugin \`${plugin.src}\` has no content.`)
return {
code: 'export default () => {}',
map: null,
}
}
const exports = findExports(code)
const defaultExport = exports.find(e => e.type === 'default' || e.name === 'default')
if (!defaultExport) {
logger.warn(`Plugin \`${plugin.src}\` has no default export and will be ignored at build time. Add \`export default defineNuxtPlugin(() => {})\` to your plugin.`)
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,
code: 'export default () => {}',
map: null,
}
}
const s = new MagicString(code)
let wrapped = false
const wrapperNames = new Set(['defineNuxtPlugin', 'definePayloadPlugin'])

View File

@ -285,9 +285,10 @@ export const layoutTemplate: NuxtTemplate = {
filename: 'layouts.mjs',
getContents ({ app }) {
const layoutsObject = genObjectFromRawEntries(Object.values(app.layouts).map(({ name, file }) => {
return [name, genDynamicImport(file)]
return [name, `defineAsyncComponent(${genDynamicImport(file)})`]
}))
return [
`import { defineAsyncComponent } from 'vue'`,
`export default ${layoutsObject}`,
].join('\n')
},

View File

@ -107,12 +107,9 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
const priorities = nuxt.options._layers.map((layer, i) => [layer.config.srcDir, -i] as const).sort(([a], [b]) => b.length - a.length)
const IMPORTS_TEMPLATE_RE = /\/imports\.(?:d\.ts|mjs)$/
function isImportsTemplate (template: ResolvedNuxtTemplate) {
return [
'/types/imports.d.ts',
'/imports.d.ts',
'/imports.mjs',
].some(i => template.filename.endsWith(i))
return IMPORTS_TEMPLATE_RE.test(template.filename)
}
const regenerateImports = async () => {

View File

@ -77,8 +77,8 @@ export async function resolvePagesRoutes (): Promise<NuxtPage[]> {
} else {
const augmentedPages = await augmentPages(pages, nuxt.vfs)
await nuxt.callHook('pages:extend', pages)
await augmentPages(pages, nuxt.vfs, augmentedPages)
augmentedPages.clear()
await augmentPages(pages, nuxt.vfs, { pagesToSkip: augmentedPages })
augmentedPages?.clear()
}
await nuxt.callHook('pages:resolved', pages)
@ -155,9 +155,14 @@ export function generateRoutesFromFiles (files: ScannedFile[], options: Generate
return prepareRoutes(routes)
}
export async function augmentPages (routes: NuxtPage[], vfs: Record<string, string>, augmentedPages = new Set<string>()) {
interface AugmentPagesContext {
pagesToSkip?: Set<string>
augmentedPages?: Set<string>
}
export async function augmentPages (routes: NuxtPage[], vfs: Record<string, string>, ctx: AugmentPagesContext = {}) {
ctx.augmentedPages ??= new Set()
for (const route of routes) {
if (route.file && !augmentedPages.has(route.file)) {
if (route.file && !ctx.pagesToSkip?.has(route.file)) {
const fileContent = route.file in vfs ? vfs[route.file]! : fs.readFileSync(await resolvePath(route.file), 'utf-8')
const routeMeta = await getRouteMeta(fileContent, route.file)
if (route.meta) {
@ -165,14 +170,14 @@ export async function augmentPages (routes: NuxtPage[], vfs: Record<string, stri
}
Object.assign(route, routeMeta)
augmentedPages.add(route.file)
ctx.augmentedPages.add(route.file)
}
if (route.children && route.children.length > 0) {
await augmentPages(route.children, vfs, augmentedPages)
await augmentPages(route.children, vfs, ctx)
}
}
return augmentedPages
return ctx.augmentedPages
}
const SFC_SCRIPT_RE = /<script(?<attrs>[^>]*)>(?<content>[\s\S]*?)<\/script[^>]*>/gi

View File

@ -24,6 +24,7 @@ const testsToTriggerOn = [
['some-nuxt-module', 'components/Component.vue', true],
['/root/src/server/api/test.ts', 'components/Component.vue', true],
['src/server/api/test.ts', 'components/Component.vue', true],
['node_modules/nitropack/node_modules/crossws/dist/adapters/bun.mjs', 'node_modules/nitropack/dist/presets/bun/runtime/bun.mjs', false],
] as const
describe('import protection', () => {

View File

@ -31,7 +31,7 @@
"dependencies": {
"@nuxt/friendly-errors-webpack-plugin": "^2.6.0",
"@nuxt/kit": "workspace:*",
"@rspack/core": "^1.1.1",
"@rspack/core": "^1.1.2",
"autoprefixer": "^10.4.20",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
@ -48,7 +48,7 @@
"jiti": "^2.4.0",
"knitwork": "^1.1.0",
"lodash-es": "4.17.21",
"magic-string": "^0.30.12",
"magic-string": "^0.30.13",
"memfs": "^4.14.0",
"mlly": "^1.7.3",
"ohash": "^1.1.4",
@ -81,9 +81,9 @@
"@types/pify": "5.0.4",
"@types/webpack-bundle-analyzer": "4.7.0",
"@types/webpack-hot-middleware": "2.25.9",
"rollup": "4.26.0",
"rollup": "4.27.3",
"unbuild": "3.0.0-rc.11",
"vue": "3.5.12"
"vue": "3.5.13"
},
"peerDependencies": {
"vue": "^3.3.4"

View File

@ -42,8 +42,8 @@
"@unhead/schema": "1.11.11",
"@vitejs/plugin-vue": "5.2.0",
"@vitejs/plugin-vue-jsx": "4.1.0",
"@vue/compiler-core": "3.5.12",
"@vue/compiler-sfc": "3.5.12",
"@vue/compiler-core": "3.5.13",
"@vue/compiler-sfc": "3.5.13",
"@vue/language-core": "2.1.10",
"esbuild-loader": "4.2.2",
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
@ -54,7 +54,7 @@
"unctx": "2.3.1",
"unenv": "1.10.0",
"vite": "5.4.11",
"vue": "3.5.12",
"vue": "3.5.13",
"vue-bundle-renderer": "2.1.1",
"vue-loader": "17.4.2",
"vue-router": "4.4.5",

View File

@ -18,7 +18,7 @@
"test": "pnpm lint && pnpm build"
},
"devDependencies": {
"@unocss/reset": "0.64.0",
"@unocss/reset": "0.64.1",
"beasties": "0.1.0",
"html-validate": "8.25.0",
"htmlnano": "2.1.1",
@ -29,7 +29,7 @@
"scule": "1.3.0",
"tinyexec": "0.3.1",
"tinyglobby": "0.2.10",
"unocss": "0.64.0",
"unocss": "0.64.1",
"vite": "5.4.11"
}
}

View File

@ -27,9 +27,9 @@
"@nuxt/schema": "workspace:*",
"@types/clear": "0.1.4",
"@types/estree": "1.0.6",
"rollup": "4.26.0",
"rollup": "4.27.3",
"unbuild": "3.0.0-rc.11",
"vue": "3.5.12"
"vue": "3.5.13"
},
"dependencies": {
"@nuxt/kit": "workspace:*",
@ -49,7 +49,7 @@
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
"jiti": "^2.4.0",
"knitwork": "^1.1.0",
"magic-string": "^0.30.12",
"magic-string": "^0.30.13",
"mlly": "^1.7.3",
"ohash": "^1.1.4",
"pathe": "^1.1.2",

View File

@ -45,11 +45,11 @@ export function viteNodePlugin (ctx: ViteBuildContext): VitePlugin {
markInvalidate(mod)
}
}
for (const plugin of ctx.nuxt.options.plugins) {
markInvalidates(server.moduleGraph.getModulesByFile(typeof plugin === 'string' ? plugin : plugin.src))
}
for (const template of ctx.nuxt.options.build.templates) {
markInvalidates(server.moduleGraph.getModulesByFile(template.dst!))
if (ctx.nuxt.apps.default) {
for (const template of ctx.nuxt.apps.default.templates) {
markInvalidates(server.moduleGraph.getModulesByFile(template.dst!))
}
}
}

View File

@ -47,7 +47,7 @@
"jiti": "^2.4.0",
"knitwork": "^1.1.0",
"lodash-es": "4.17.21",
"magic-string": "^0.30.12",
"magic-string": "^0.30.13",
"memfs": "^4.14.0",
"mini-css-extract-plugin": "^2.9.2",
"mlly": "^1.7.3",
@ -76,15 +76,15 @@
},
"devDependencies": {
"@nuxt/schema": "workspace:*",
"@rspack/core": "1.1.1",
"@rspack/core": "1.1.2",
"@types/hash-sum": "1.0.2",
"@types/lodash-es": "4.17.12",
"@types/pify": "5.0.4",
"@types/webpack-bundle-analyzer": "4.7.0",
"@types/webpack-hot-middleware": "2.25.9",
"rollup": "4.26.0",
"rollup": "4.27.3",
"unbuild": "3.0.0-rc.11",
"vue": "3.5.12"
"vue": "3.5.13"
},
"peerDependencies": {
"vue": "^3.3.4"

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"208k"`)
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1394k"`)
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1396k"`)
const packages = modules.files
.filter(m => m.endsWith('package.json'))
@ -78,7 +78,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
const serverDir = join(rootDir, '.output-inline/server')
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"557k"`)
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"559k"`)
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"94.4k"`)