mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-22 11:22:43 +00:00
Merge branch 'main' into feat/nuxt_async_context
This commit is contained in:
commit
97af928232
@ -1,4 +1,4 @@
|
|||||||
FROM node:lts@sha256:0e910f435308c36ea60b4cfd7b80208044d77a074d16b768a81901ce938a62dc
|
FROM node:lts@sha256:99981c3d1aac0d98cd9f03f74b92dddf30f30ffb0b34e6df8bd96283f62f12c6
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -fy libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdbus-1-3 libdrm2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 && \
|
apt-get install -fy libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdbus-1-3 libdrm2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 && \
|
||||||
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -60,7 +60,7 @@ jobs:
|
|||||||
run: pnpm test:attw
|
run: pnpm test:attw
|
||||||
|
|
||||||
- name: Cache dist
|
- name: Cache dist
|
||||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
with:
|
with:
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
name: dist
|
name: dist
|
||||||
|
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@ -59,7 +59,7 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
if: github.repository == 'nuxt/nuxt' && success()
|
if: github.repository == 'nuxt/nuxt' && success()
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
|
@ -147,7 +147,7 @@ If you have not fetched data on the server (for example, with `server: false`),
|
|||||||
|
|
||||||
```ts [Signature]
|
```ts [Signature]
|
||||||
function useFetch<DataT, ErrorT>(
|
function useFetch<DataT, ErrorT>(
|
||||||
url: string | Request | Ref<string | Request> | (() => string) | Request,
|
url: string | Request | Ref<string | Request> | (() => string | Request),
|
||||||
options?: UseFetchOptions<DataT>
|
options?: UseFetchOptions<DataT>
|
||||||
): Promise<AsyncData<DataT, ErrorT>>
|
): Promise<AsyncData<DataT, ErrorT>>
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ Each active version has its own nightly releases which are generated automatical
|
|||||||
|
|
||||||
Release | | Initial release | End Of Life | Docs
|
Release | | Initial release | End Of Life | Docs
|
||||||
----------------------------------------|---------------------------------------------------------------------------------------------------|-----------------|--------------|-------
|
----------------------------------------|---------------------------------------------------------------------------------------------------|-----------------|--------------|-------
|
||||||
**4.x** (scheduled) | | 2024 Q3 | |
|
**4.x** (scheduled) | | approximately 1 month after release of nitro v3 | |
|
||||||
**3.x** (stable) | <a href="https://npmjs.com/package/nuxt"><img alt="Nuxt latest 3.x version" src="https://flat.badgen.net/npm/v/nuxt?label=" class="not-prose"></a> | 2022-11-16 | TBA | [nuxt.com](/docs)
|
**3.x** (stable) | <a href="https://npmjs.com/package/nuxt"><img alt="Nuxt latest 3.x version" src="https://flat.badgen.net/npm/v/nuxt?label=" class="not-prose"></a> | 2022-11-16 | TBA | [nuxt.com](/docs)
|
||||||
**2.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 2.x version" src="https://flat.badgen.net/npm/v/nuxt/2x?label=" class="not-prose"></a> | 2018-09-21 | 2024-06-30 | [v2.nuxt.com](https://v2.nuxt.com/docs)
|
**2.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 2.x version" src="https://flat.badgen.net/npm/v/nuxt/2x?label=" class="not-prose"></a> | 2018-09-21 | 2024-06-30 | [v2.nuxt.com](https://v2.nuxt.com/docs)
|
||||||
**1.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 1.x version" src="https://flat.badgen.net/npm/v/nuxt/1x?label=" class="not-prose"></a> | 2018-01-08 | 2019-09-21 |
|
**1.x** (unsupported) | <a href="https://www.npmjs.com/package/nuxt?activeTab=versions"><img alt="Nuxt 1.x version" src="https://flat.badgen.net/npm/v/nuxt/1x?label=" class="not-prose"></a> | 2018-01-08 | 2019-09-21 |
|
||||||
|
34
package.json
34
package.json
@ -40,11 +40,11 @@
|
|||||||
"@nuxt/vite-builder": "workspace:*",
|
"@nuxt/vite-builder": "workspace:*",
|
||||||
"@nuxt/webpack-builder": "workspace:*",
|
"@nuxt/webpack-builder": "workspace:*",
|
||||||
"@types/node": "22.10.5",
|
"@types/node": "22.10.5",
|
||||||
"@unhead/dom": "1.11.14",
|
"@unhead/dom": "1.11.15",
|
||||||
"@unhead/schema": "1.11.14",
|
"@unhead/schema": "1.11.15",
|
||||||
"@unhead/shared": "1.11.14",
|
"@unhead/shared": "1.11.15",
|
||||||
"@unhead/ssr": "1.11.14",
|
"@unhead/ssr": "1.11.15",
|
||||||
"@unhead/vue": "1.11.14",
|
"@unhead/vue": "1.11.15",
|
||||||
"@vue/compiler-core": "3.5.13",
|
"@vue/compiler-core": "3.5.13",
|
||||||
"@vue/compiler-dom": "3.5.13",
|
"@vue/compiler-dom": "3.5.13",
|
||||||
"@vue/shared": "3.5.13",
|
"@vue/shared": "3.5.13",
|
||||||
@ -56,19 +56,19 @@
|
|||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"ohash": "1.1.4",
|
"ohash": "1.1.4",
|
||||||
"postcss": "8.4.49",
|
"postcss": "8.4.49",
|
||||||
"rollup": "4.30.0",
|
"rollup": "4.30.1",
|
||||||
"send": ">=1.1.0",
|
"send": ">=1.1.0",
|
||||||
"typescript": "5.7.2",
|
"typescript": "5.7.3",
|
||||||
"ufo": "1.5.4",
|
"ufo": "1.5.4",
|
||||||
"unbuild": "3.2.0",
|
"unbuild": "3.2.0",
|
||||||
"unhead": "1.11.14",
|
"unhead": "1.11.15",
|
||||||
"unimport": "3.14.5",
|
"unimport": "3.14.5",
|
||||||
"vite": "6.0.7",
|
"vite": "6.0.7",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arethetypeswrong/cli": "0.17.2",
|
"@arethetypeswrong/cli": "0.17.2",
|
||||||
"@nuxt/eslint-config": "0.7.4",
|
"@nuxt/eslint-config": "0.7.5",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@nuxt/rspack-builder": "workspace:*",
|
"@nuxt/rspack-builder": "workspace:*",
|
||||||
"@nuxt/test-utils": "3.15.1",
|
"@nuxt/test-utils": "3.15.1",
|
||||||
@ -76,8 +76,8 @@
|
|||||||
"@testing-library/vue": "8.1.0",
|
"@testing-library/vue": "8.1.0",
|
||||||
"@types/node": "22.10.5",
|
"@types/node": "22.10.5",
|
||||||
"@types/semver": "7.5.8",
|
"@types/semver": "7.5.8",
|
||||||
"@unhead/schema": "1.11.14",
|
"@unhead/schema": "1.11.15",
|
||||||
"@unhead/vue": "1.11.14",
|
"@unhead/vue": "1.11.15",
|
||||||
"@vitest/coverage-v8": "2.1.8",
|
"@vitest/coverage-v8": "2.1.8",
|
||||||
"@vue/test-utils": "2.4.6",
|
"@vue/test-utils": "2.4.6",
|
||||||
"autoprefixer": "10.4.20",
|
"autoprefixer": "10.4.20",
|
||||||
@ -90,27 +90,27 @@
|
|||||||
"eslint": "9.17.0",
|
"eslint": "9.17.0",
|
||||||
"eslint-plugin-no-only-tests": "3.3.0",
|
"eslint-plugin-no-only-tests": "3.3.0",
|
||||||
"eslint-plugin-perfectionist": "4.6.0",
|
"eslint-plugin-perfectionist": "4.6.0",
|
||||||
"eslint-typegen": "0.3.2",
|
"eslint-typegen": "1.0.0",
|
||||||
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
|
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
|
||||||
"happy-dom": "16.3.0",
|
"happy-dom": "16.5.3",
|
||||||
"installed-check": "9.3.0",
|
"installed-check": "9.3.0",
|
||||||
"jiti": "2.4.2",
|
"jiti": "2.4.2",
|
||||||
"knip": "5.41.1",
|
"knip": "5.42.0",
|
||||||
"markdownlint-cli": "0.43.0",
|
"markdownlint-cli": "0.43.0",
|
||||||
"memfs": "4.15.3",
|
"memfs": "4.17.0",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
|
||||||
"nuxi": "3.18.2",
|
"nuxi": "3.18.2",
|
||||||
"nuxt": "workspace:*",
|
"nuxt": "workspace:*",
|
||||||
"nuxt-content-twoslash": "0.1.2",
|
"nuxt-content-twoslash": "0.1.2",
|
||||||
"ofetch": "1.4.1",
|
"ofetch": "1.4.1",
|
||||||
"pathe": "2.0.0",
|
"pathe": "2.0.1",
|
||||||
"playwright-core": "1.49.1",
|
"playwright-core": "1.49.1",
|
||||||
"semver": "7.6.3",
|
"semver": "7.6.3",
|
||||||
"sherif": "1.1.1",
|
"sherif": "1.1.1",
|
||||||
"std-env": "3.8.0",
|
"std-env": "3.8.0",
|
||||||
"tinyexec": "0.3.2",
|
"tinyexec": "0.3.2",
|
||||||
"tinyglobby": "0.2.10",
|
"tinyglobby": "0.2.10",
|
||||||
"typescript": "5.7.2",
|
"typescript": "5.7.3",
|
||||||
"ufo": "1.5.4",
|
"ufo": "1.5.4",
|
||||||
"vitest": "2.1.8",
|
"vitest": "2.1.8",
|
||||||
"vitest-environment-nuxt": "1.0.1",
|
"vitest-environment-nuxt": "1.0.1",
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
"klona": "^2.0.6",
|
"klona": "^2.0.6",
|
||||||
"mlly": "^1.7.3",
|
"mlly": "^1.7.3",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^1.1.4",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"pkg-types": "^1.3.0",
|
"pkg-types": "^1.3.0",
|
||||||
"scule": "^1.3.0",
|
"scule": "^1.3.0",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
|
@ -291,6 +291,10 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure `#build` is placed at the end of the paths object.
|
||||||
|
// https://github.com/nuxt/nuxt/issues/30325
|
||||||
|
sortTsPaths(tsConfig.compilerOptions.paths)
|
||||||
|
|
||||||
tsConfig.include = [...new Set(tsConfig.include.map(p => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))]
|
tsConfig.include = [...new Set(tsConfig.include.map(p => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))]
|
||||||
tsConfig.exclude = [...new Set(tsConfig.exclude!.map(p => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))]
|
tsConfig.exclude = [...new Set(tsConfig.exclude!.map(p => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))]
|
||||||
|
|
||||||
@ -330,6 +334,17 @@ export async function writeTypes (nuxt: Nuxt) {
|
|||||||
await writeFile()
|
await writeFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortTsPaths (paths: Record<string, string[]>) {
|
||||||
|
for (const pathKey in paths) {
|
||||||
|
if (pathKey.startsWith('#build')) {
|
||||||
|
const pathValue = paths[pathKey]!
|
||||||
|
// Delete & Reassign to ensure key is inserted at the end of object.
|
||||||
|
delete paths[pathKey]
|
||||||
|
paths[pathKey] = pathValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function renderAttrs (obj: Record<string, string>) {
|
function renderAttrs (obj: Record<string, string>) {
|
||||||
const attrs: string[] = []
|
const attrs: string[] = []
|
||||||
for (const key in obj) {
|
for (const key in obj) {
|
||||||
|
@ -59,4 +59,42 @@ describe('tsConfig generation', () => {
|
|||||||
]
|
]
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should add #build after #components to paths', async () => {
|
||||||
|
const { tsConfig } = await _generateTypes(mockNuxtWithOptions({
|
||||||
|
alias: {
|
||||||
|
'~': '/my-app',
|
||||||
|
'@': '/my-app',
|
||||||
|
'some-custom-alias': '/my-app/some-alias',
|
||||||
|
'#build': './build-dir',
|
||||||
|
'#build/*': './build-dir/*',
|
||||||
|
'#imports': './imports',
|
||||||
|
'#components': './components',
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
expect(tsConfig.compilerOptions?.paths).toMatchObject({
|
||||||
|
'~': [
|
||||||
|
'..',
|
||||||
|
],
|
||||||
|
'some-custom-alias': [
|
||||||
|
'../some-alias',
|
||||||
|
],
|
||||||
|
'@': [
|
||||||
|
'..',
|
||||||
|
],
|
||||||
|
'#imports': [
|
||||||
|
'./imports',
|
||||||
|
],
|
||||||
|
'#components': [
|
||||||
|
'./components',
|
||||||
|
],
|
||||||
|
'#build': [
|
||||||
|
'./build-dir',
|
||||||
|
],
|
||||||
|
'#build/*': [
|
||||||
|
'./build-dir/*',
|
||||||
|
],
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import 'nuxi/cli'
|
import '@nuxt/cli/cli'
|
||||||
|
@ -22,7 +22,7 @@ export default defineBuildConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'nuxi',
|
'@nuxt/cli',
|
||||||
'vue-router',
|
'vue-router',
|
||||||
'ofetch',
|
'ofetch',
|
||||||
],
|
],
|
||||||
|
@ -64,16 +64,17 @@
|
|||||||
"test:attw": "attw --pack"
|
"test:attw": "attw --pack"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@nuxt/cli": "^3.20.0",
|
||||||
"@nuxt/devalue": "^2.0.2",
|
"@nuxt/devalue": "^2.0.2",
|
||||||
"@nuxt/devtools": "^1.7.0",
|
"@nuxt/devtools": "^1.7.0",
|
||||||
"@nuxt/kit": "workspace:*",
|
"@nuxt/kit": "workspace:*",
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"@nuxt/telemetry": "^2.6.4",
|
"@nuxt/telemetry": "^2.6.4",
|
||||||
"@nuxt/vite-builder": "workspace:*",
|
"@nuxt/vite-builder": "workspace:*",
|
||||||
"@unhead/dom": "^1.11.14",
|
"@unhead/dom": "^1.11.15",
|
||||||
"@unhead/shared": "^1.11.14",
|
"@unhead/shared": "^1.11.15",
|
||||||
"@unhead/ssr": "^1.11.14",
|
"@unhead/ssr": "^1.11.15",
|
||||||
"@unhead/vue": "^1.11.14",
|
"@unhead/vue": "^1.11.15",
|
||||||
"@vue/shared": "^3.5.13",
|
"@vue/shared": "^3.5.13",
|
||||||
"acorn": "8.14.0",
|
"acorn": "8.14.0",
|
||||||
"c12": "^2.0.1",
|
"c12": "^2.0.1",
|
||||||
@ -100,11 +101,10 @@
|
|||||||
"mlly": "^1.7.3",
|
"mlly": "^1.7.3",
|
||||||
"nanotar": "^0.1.1",
|
"nanotar": "^0.1.1",
|
||||||
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
|
"nitro": "npm:nitro-nightly@3.0.0-beta-28796231.359af68d",
|
||||||
"nuxi": "^3.18.2",
|
|
||||||
"nypm": "^0.4.1",
|
"nypm": "^0.4.1",
|
||||||
"ofetch": "^1.4.1",
|
"ofetch": "^1.4.1",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^1.1.4",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"perfect-debounce": "^1.0.0",
|
"perfect-debounce": "^1.0.0",
|
||||||
"pkg-types": "^1.3.0",
|
"pkg-types": "^1.3.0",
|
||||||
"radix3": "^1.1.2",
|
"radix3": "^1.1.2",
|
||||||
@ -118,7 +118,7 @@
|
|||||||
"uncrypto": "^0.1.3",
|
"uncrypto": "^0.1.3",
|
||||||
"unctx": "^2.4.1",
|
"unctx": "^2.4.1",
|
||||||
"unenv": "^1.10.0",
|
"unenv": "^1.10.0",
|
||||||
"unhead": "^1.11.14",
|
"unhead": "^1.11.15",
|
||||||
"unimport": "^3.14.5",
|
"unimport": "^3.14.5",
|
||||||
"unplugin": "^2.1.2",
|
"unplugin": "^2.1.2",
|
||||||
"unplugin-vue-router": "^0.10.9",
|
"unplugin-vue-router": "^0.10.9",
|
||||||
|
@ -53,7 +53,7 @@ export function installNuxtModule (name: string, options?: EnsurePackageInstalle
|
|||||||
installPrompts.add(name)
|
installPrompts.add(name)
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
return promptToInstall(name, async () => {
|
return promptToInstall(name, async () => {
|
||||||
const { runCommand } = await import('nuxi')
|
const { runCommand } = await import('@nuxt/cli')
|
||||||
await runCommand('module', ['add', name, '--cwd', nuxt.options.rootDir])
|
await runCommand('module', ['add', name, '--cwd', nuxt.options.rootDir])
|
||||||
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options })
|
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options })
|
||||||
}
|
}
|
||||||
|
@ -53,12 +53,30 @@ export function withLocations<T> (node: T): WithLocations<T> {
|
|||||||
return node as WithLocations<T>
|
return node as WithLocations<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to check whether scope A is a child of scope B.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* isChildScope('0-1-2', '0-1') // true
|
||||||
|
* isChildScope('0-1', '0-1') // false
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param a the child scope
|
||||||
|
* @param b the parent scope
|
||||||
|
* @returns true if scope A is a child of scope B, false otherwise (also when they are the same)
|
||||||
|
*/
|
||||||
|
function isChildScope (a: string, b: string) {
|
||||||
|
return a.startsWith(b) && a.length > b.length
|
||||||
|
}
|
||||||
|
|
||||||
abstract class BaseNode<T extends Node = Node> {
|
abstract class BaseNode<T extends Node = Node> {
|
||||||
abstract type: string
|
abstract type: string
|
||||||
|
readonly scope: string
|
||||||
node: WithLocations<T>
|
node: WithLocations<T>
|
||||||
|
|
||||||
constructor (node: WithLocations<T>) {
|
constructor (node: WithLocations<T>, scope: string) {
|
||||||
this.node = node
|
this.node = node
|
||||||
|
this.scope = scope
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,6 +90,14 @@ abstract class BaseNode<T extends Node = Node> {
|
|||||||
* For instance, for a function parameter, this would be the end of the function declaration.
|
* For instance, for a function parameter, this would be the end of the function declaration.
|
||||||
*/
|
*/
|
||||||
abstract get end (): number
|
abstract get end (): number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the node is defined under a specific scope.
|
||||||
|
* @param scope
|
||||||
|
*/
|
||||||
|
isUnderScope (scope: string) {
|
||||||
|
return isChildScope(this.scope, scope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IdentifierNode extends BaseNode<Identifier> {
|
class IdentifierNode extends BaseNode<Identifier> {
|
||||||
@ -90,8 +116,8 @@ class FunctionParamNode extends BaseNode {
|
|||||||
type = 'FunctionParam' as const
|
type = 'FunctionParam' as const
|
||||||
fnNode: WithLocations<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>
|
fnNode: WithLocations<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>
|
||||||
|
|
||||||
constructor (node: WithLocations<Node>, fnNode: WithLocations<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>) {
|
constructor (node: WithLocations<Node>, scope: string, fnNode: WithLocations<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>) {
|
||||||
super(node)
|
super(node, scope)
|
||||||
this.fnNode = fnNode
|
this.fnNode = fnNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +146,8 @@ class VariableNode extends BaseNode<Identifier> {
|
|||||||
type = 'Variable' as const
|
type = 'Variable' as const
|
||||||
variableNode: WithLocations<VariableDeclaration>
|
variableNode: WithLocations<VariableDeclaration>
|
||||||
|
|
||||||
constructor (node: WithLocations<Identifier>, variableNode: WithLocations<VariableDeclaration>) {
|
constructor (node: WithLocations<Identifier>, scope: string, variableNode: WithLocations<VariableDeclaration>) {
|
||||||
super(node)
|
super(node, scope)
|
||||||
this.variableNode = variableNode
|
this.variableNode = variableNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +164,8 @@ class ImportNode extends BaseNode<ImportSpecifier | ImportDefaultSpecifier | Imp
|
|||||||
type = 'Import' as const
|
type = 'Import' as const
|
||||||
importNode: WithLocations<Node>
|
importNode: WithLocations<Node>
|
||||||
|
|
||||||
constructor (node: WithLocations<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>, importNode: WithLocations<Node>) {
|
constructor (node: WithLocations<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>, scope: string, importNode: WithLocations<Node>) {
|
||||||
super(node)
|
super(node, scope)
|
||||||
this.importNode = importNode
|
this.importNode = importNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,8 +182,8 @@ class CatchParamNode extends BaseNode {
|
|||||||
type = 'CatchParam' as const
|
type = 'CatchParam' as const
|
||||||
catchNode: WithLocations<CatchClause>
|
catchNode: WithLocations<CatchClause>
|
||||||
|
|
||||||
constructor (node: WithLocations<Node>, catchNode: WithLocations<CatchClause>) {
|
constructor (node: WithLocations<Node>, scope: string, catchNode: WithLocations<CatchClause>) {
|
||||||
super(node)
|
super(node, scope)
|
||||||
this.catchNode = catchNode
|
this.catchNode = catchNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +290,7 @@ export class ScopeTracker {
|
|||||||
|
|
||||||
const identifiers = getPatternIdentifiers(param)
|
const identifiers = getPatternIdentifiers(param)
|
||||||
for (const identifier of identifiers) {
|
for (const identifier of identifiers) {
|
||||||
this.declareIdentifier(identifier.name, new FunctionParamNode(identifier, fn))
|
this.declareIdentifier(identifier.name, new FunctionParamNode(identifier, this.scopeIndexKey, fn))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,10 +302,10 @@ export class ScopeTracker {
|
|||||||
this.declareIdentifier(
|
this.declareIdentifier(
|
||||||
identifier.name,
|
identifier.name,
|
||||||
parent.type === 'VariableDeclaration'
|
parent.type === 'VariableDeclaration'
|
||||||
? new VariableNode(identifier, parent)
|
? new VariableNode(identifier, this.scopeIndexKey, parent)
|
||||||
: parent.type === 'CatchClause'
|
: parent.type === 'CatchClause'
|
||||||
? new CatchParamNode(identifier, parent)
|
? new CatchParamNode(identifier, this.scopeIndexKey, parent)
|
||||||
: new FunctionParamNode(identifier, parent),
|
: new FunctionParamNode(identifier, this.scopeIndexKey, parent),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,7 +321,7 @@ export class ScopeTracker {
|
|||||||
case 'FunctionDeclaration':
|
case 'FunctionDeclaration':
|
||||||
// declare function name for named functions, skip for `export default`
|
// declare function name for named functions, skip for `export default`
|
||||||
if (node.id?.name) {
|
if (node.id?.name) {
|
||||||
this.declareIdentifier(node.id.name, new FunctionNode(node))
|
this.declareIdentifier(node.id.name, new FunctionNode(node, this.scopeIndexKey))
|
||||||
}
|
}
|
||||||
this.pushScope()
|
this.pushScope()
|
||||||
for (const param of node.params) {
|
for (const param of node.params) {
|
||||||
@ -309,7 +335,7 @@ export class ScopeTracker {
|
|||||||
this.pushScope()
|
this.pushScope()
|
||||||
// can be undefined, for example in class method definitions
|
// can be undefined, for example in class method definitions
|
||||||
if (node.id?.name) {
|
if (node.id?.name) {
|
||||||
this.declareIdentifier(node.id.name, new FunctionNode(node))
|
this.declareIdentifier(node.id.name, new FunctionNode(node, this.scopeIndexKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pushScope()
|
this.pushScope()
|
||||||
@ -333,7 +359,7 @@ export class ScopeTracker {
|
|||||||
case 'ClassDeclaration':
|
case 'ClassDeclaration':
|
||||||
// declare class name for named classes, skip for `export default`
|
// declare class name for named classes, skip for `export default`
|
||||||
if (node.id?.name) {
|
if (node.id?.name) {
|
||||||
this.declareIdentifier(node.id.name, new IdentifierNode(withLocations(node.id)))
|
this.declareIdentifier(node.id.name, new IdentifierNode(withLocations(node.id), this.scopeIndexKey))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -342,13 +368,13 @@ export class ScopeTracker {
|
|||||||
// e.g. const MyClass = class InternalClassName { // InternalClassName is only available within the class body
|
// e.g. const MyClass = class InternalClassName { // InternalClassName is only available within the class body
|
||||||
this.pushScope()
|
this.pushScope()
|
||||||
if (node.id?.name) {
|
if (node.id?.name) {
|
||||||
this.declareIdentifier(node.id.name, new IdentifierNode(withLocations(node.id)))
|
this.declareIdentifier(node.id.name, new IdentifierNode(withLocations(node.id), this.scopeIndexKey))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'ImportDeclaration':
|
case 'ImportDeclaration':
|
||||||
for (const specifier of node.specifiers) {
|
for (const specifier of node.specifiers) {
|
||||||
this.declareIdentifier(specifier.local.name, new ImportNode(withLocations(specifier), node))
|
this.declareIdentifier(specifier.local.name, new ImportNode(withLocations(specifier), this.scopeIndexKey, node))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -429,6 +455,26 @@ export class ScopeTracker {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentScope () {
|
||||||
|
return this.scopeIndexKey
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current scope is a child of a specific scope.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* // current scope is 0-1
|
||||||
|
* isCurrentScopeUnder('0') // true
|
||||||
|
* isCurrentScopeUnder('0-1') // false
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param scope the parent scope
|
||||||
|
* @returns `true` if the current scope is a child of the specified scope, `false` otherwise (also when they are the same)
|
||||||
|
*/
|
||||||
|
isCurrentScopeUnder (scope: string) {
|
||||||
|
return isChildScope(this.scopeIndexKey, scope)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Freezes the scope tracker, preventing further declarations.
|
* Freezes the scope tracker, preventing further declarations.
|
||||||
* It also resets the scope index stack to its initial state, so that the scope tracker can be reused.
|
* It also resets the scope index stack to its initial state, so that the scope tracker can be reused.
|
||||||
|
@ -228,6 +228,8 @@ export const PageMetaPlugin = (options: PageMetaPluginOptions = {}) => createUnp
|
|||||||
|
|
||||||
if (!meta) { return }
|
if (!meta) { return }
|
||||||
|
|
||||||
|
const definePageMetaScope = scopeTracker.getCurrentScope()
|
||||||
|
|
||||||
walk(meta, {
|
walk(meta, {
|
||||||
scopeTracker,
|
scopeTracker,
|
||||||
enter (node, parent) {
|
enter (node, parent) {
|
||||||
@ -236,10 +238,24 @@ export const PageMetaPlugin = (options: PageMetaPluginOptions = {}) => createUnp
|
|||||||
|| node.type !== 'Identifier' // checking for `node.type` to narrow down the type
|
|| node.type !== 'Identifier' // checking for `node.type` to narrow down the type
|
||||||
) { return }
|
) { return }
|
||||||
|
|
||||||
|
const declaration = scopeTracker.getDeclaration(node.name)
|
||||||
|
if (declaration) {
|
||||||
|
// check if the declaration was made inside `definePageMeta` and if so, do not process it
|
||||||
|
// (ensures that we don't hoist local variables in inline middleware, for example)
|
||||||
|
if (
|
||||||
|
declaration.isUnderScope(definePageMetaScope)
|
||||||
|
// ensures that we compare the correct declaration to the reference
|
||||||
|
// (when in the same scope, the declaration must come before the reference, otherwise it must be in a parent scope)
|
||||||
|
&& (scopeTracker.isCurrentScopeUnder(declaration.scope) || declaration.start < node.start)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isStaticIdentifier(node.name)) {
|
if (isStaticIdentifier(node.name)) {
|
||||||
addImport(node.name)
|
addImport(node.name)
|
||||||
} else {
|
} else if (declaration) {
|
||||||
processDeclaration(scopeTracker.getDeclaration(node.name))
|
processDeclaration(declaration)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -393,6 +393,188 @@ definePageMeta({
|
|||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not import static identifiers when shadowed in the same scope', () => {
|
||||||
|
const sfc = `
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: () => {
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' })
|
||||||
|
expect(transformPlugin.transform.call({
|
||||||
|
parse: (code: string, opts: any = {}) => Parser.parse(code, {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
locations: true,
|
||||||
|
...opts,
|
||||||
|
}),
|
||||||
|
}, res.content, 'component.vue?macro=true')?.code).toMatchInlineSnapshot(`
|
||||||
|
"const __nuxt_page_meta = {
|
||||||
|
middleware: () => {
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default __nuxt_page_meta"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not import static identifiers when shadowed in parent scope', () => {
|
||||||
|
const sfc = `
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: () => {
|
||||||
|
function isLoggedIn() {
|
||||||
|
const auth = useState('auth')
|
||||||
|
return auth.value.isLoggedIn
|
||||||
|
}
|
||||||
|
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' })
|
||||||
|
expect(transformPlugin.transform.call({
|
||||||
|
parse: (code: string, opts: any = {}) => Parser.parse(code, {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
locations: true,
|
||||||
|
...opts,
|
||||||
|
}),
|
||||||
|
}, res.content, 'component.vue?macro=true')?.code).toMatchInlineSnapshot(`
|
||||||
|
"const __nuxt_page_meta = {
|
||||||
|
middleware: () => {
|
||||||
|
function isLoggedIn() {
|
||||||
|
const auth = useState('auth')
|
||||||
|
return auth.value.isLoggedIn
|
||||||
|
}
|
||||||
|
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default __nuxt_page_meta"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should import static identifiers when a shadowed and a non-shadowed one is used', () => {
|
||||||
|
const sfc = `
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: [
|
||||||
|
() => {
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' })
|
||||||
|
expect(transformPlugin.transform.call({
|
||||||
|
parse: (code: string, opts: any = {}) => Parser.parse(code, {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
locations: true,
|
||||||
|
...opts,
|
||||||
|
}),
|
||||||
|
}, res.content, 'component.vue?macro=true')?.code).toMatchInlineSnapshot(`
|
||||||
|
"import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
const __nuxt_page_meta = {
|
||||||
|
middleware: [
|
||||||
|
() => {
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
const auth = useState('auth')
|
||||||
|
if (!auth.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export default __nuxt_page_meta"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should import static identifiers when a shadowed and a non-shadowed one is used in the same scope', () => {
|
||||||
|
const sfc = `
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: () => {
|
||||||
|
const auth1 = useState('auth')
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth2 = useState('auth')
|
||||||
|
if (!auth1.value.isLoggedIn || !auth2.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' })
|
||||||
|
expect(transformPlugin.transform.call({
|
||||||
|
parse: (code: string, opts: any = {}) => Parser.parse(code, {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
locations: true,
|
||||||
|
...opts,
|
||||||
|
}),
|
||||||
|
}, res.content, 'component.vue?macro=true')?.code).toMatchInlineSnapshot(`
|
||||||
|
"import { useState } from '#app/composables/state'
|
||||||
|
|
||||||
|
const __nuxt_page_meta = {
|
||||||
|
middleware: () => {
|
||||||
|
const auth1 = useState('auth')
|
||||||
|
const useState = (key) => ({ value: { isLoggedIn: false } })
|
||||||
|
const auth2 = useState('auth')
|
||||||
|
if (!auth1.value.isLoggedIn || !auth2.value.isLoggedIn) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default __nuxt_page_meta"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
it('should work with esbuild.keepNames = true', async () => {
|
it('should work with esbuild.keepNames = true', async () => {
|
||||||
const sfc = `
|
const sfc = `
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -516,7 +698,12 @@ definePageMeta({
|
|||||||
test () {}
|
test () {}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(hoisted.value)
|
const someFunction = () => {
|
||||||
|
const someValue = 'someValue'
|
||||||
|
console.log(someValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(hoisted.value, val)
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
validate: (route) => {
|
validate: (route) => {
|
||||||
@ -564,7 +751,12 @@ const hoisted = ref('hoisted')
|
|||||||
test () {}
|
test () {}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(hoisted.value)
|
const someFunction = () => {
|
||||||
|
const someValue = 'someValue'
|
||||||
|
console.log(someValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(hoisted.value, val)
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
validate: (route) => {
|
validate: (route) => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { assert, describe, expect, it } from 'vitest'
|
||||||
import { getUndeclaredIdentifiersInFunction, parseAndWalk } from '../src/core/utils/parse'
|
import { getUndeclaredIdentifiersInFunction, parseAndWalk } from '../src/core/utils/parse'
|
||||||
import { TestScopeTracker } from './fixture/scope-tracker'
|
import { TestScopeTracker } from './fixture/scope-tracker'
|
||||||
|
|
||||||
@ -667,4 +667,87 @@ describe('parsing', () => {
|
|||||||
|
|
||||||
expect(processedFunctions).toBe(5)
|
expect(processedFunctions).toBe(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it ('should correctly compare identifiers defined in different scopes', () => {
|
||||||
|
const code = `
|
||||||
|
// ""
|
||||||
|
const a = 1
|
||||||
|
|
||||||
|
// ""
|
||||||
|
const func = () => {
|
||||||
|
// "0-0"
|
||||||
|
const b = 2
|
||||||
|
|
||||||
|
// "0-0"
|
||||||
|
function foo() {
|
||||||
|
// "0-0-0-0"
|
||||||
|
const c = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ""
|
||||||
|
const func2 = () => {
|
||||||
|
// "1-0"
|
||||||
|
const d = 2
|
||||||
|
|
||||||
|
// "1-0"
|
||||||
|
function bar() {
|
||||||
|
// "1-0-0-0"
|
||||||
|
const e = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ""
|
||||||
|
const f = 4
|
||||||
|
`
|
||||||
|
|
||||||
|
const scopeTracker = new TestScopeTracker({
|
||||||
|
keepExitedScopes: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
parseAndWalk(code, filename, {
|
||||||
|
scopeTracker,
|
||||||
|
})
|
||||||
|
|
||||||
|
const a = scopeTracker.getDeclarationFromScope('a', '')
|
||||||
|
const func = scopeTracker.getDeclarationFromScope('func', '')
|
||||||
|
const foo = scopeTracker.getDeclarationFromScope('foo', '0-0')
|
||||||
|
const b = scopeTracker.getDeclarationFromScope('b', '0-0')
|
||||||
|
const c = scopeTracker.getDeclarationFromScope('c', '0-0-0-0')
|
||||||
|
const func2 = scopeTracker.getDeclarationFromScope('func2', '')
|
||||||
|
const bar = scopeTracker.getDeclarationFromScope('bar', '1-0')
|
||||||
|
const d = scopeTracker.getDeclarationFromScope('d', '1-0')
|
||||||
|
const e = scopeTracker.getDeclarationFromScope('e', '1-0-0-0')
|
||||||
|
const f = scopeTracker.getDeclarationFromScope('f', '')
|
||||||
|
|
||||||
|
assert(a && func && foo && b && c && func2 && bar && d && e && f, 'All declarations should be found')
|
||||||
|
|
||||||
|
// identifiers in the same scope should be equal
|
||||||
|
expect(f.isUnderScope(a.scope)).toBe(false)
|
||||||
|
expect(func.isUnderScope(a.scope)).toBe(false)
|
||||||
|
expect(d.isUnderScope(bar.scope)).toBe(false)
|
||||||
|
|
||||||
|
// identifiers in deeper scopes should be under the scope of the parent scope
|
||||||
|
expect(b.isUnderScope(a.scope)).toBe(true)
|
||||||
|
expect(b.isUnderScope(func.scope)).toBe(true)
|
||||||
|
expect(c.isUnderScope(a.scope)).toBe(true)
|
||||||
|
expect(c.isUnderScope(b.scope)).toBe(true)
|
||||||
|
expect(d.isUnderScope(a.scope)).toBe(true)
|
||||||
|
expect(d.isUnderScope(func2.scope)).toBe(true)
|
||||||
|
expect(e.isUnderScope(a.scope)).toBe(true)
|
||||||
|
expect(e.isUnderScope(d.scope)).toBe(true)
|
||||||
|
|
||||||
|
// identifiers in parent scope should not be under the scope of the children
|
||||||
|
expect(a.isUnderScope(b.scope)).toBe(false)
|
||||||
|
expect(a.isUnderScope(c.scope)).toBe(false)
|
||||||
|
expect(a.isUnderScope(d.scope)).toBe(false)
|
||||||
|
expect(a.isUnderScope(e.scope)).toBe(false)
|
||||||
|
expect(b.isUnderScope(c.scope)).toBe(false)
|
||||||
|
|
||||||
|
// identifiers in parallel scopes should not influence each other
|
||||||
|
expect(d.isUnderScope(b.scope)).toBe(false)
|
||||||
|
expect(e.isUnderScope(b.scope)).toBe(false)
|
||||||
|
expect(b.isUnderScope(d.scope)).toBe(false)
|
||||||
|
expect(c.isUnderScope(e.scope)).toBe(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -47,9 +47,9 @@
|
|||||||
"jiti": "^2.4.2",
|
"jiti": "^2.4.2",
|
||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"memfs": "^4.15.3",
|
"memfs": "^4.17.0",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^1.1.4",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"pify": "^6.1.0",
|
"pify": "^6.1.0",
|
||||||
"postcss": "^8.4.49",
|
"postcss": "^8.4.49",
|
||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"@types/pify": "5.0.4",
|
"@types/pify": "5.0.4",
|
||||||
"@types/webpack-bundle-analyzer": "4.7.0",
|
"@types/webpack-bundle-analyzer": "4.7.0",
|
||||||
"@types/webpack-hot-middleware": "2.25.9",
|
"@types/webpack-hot-middleware": "2.25.9",
|
||||||
"rollup": "4.30.0",
|
"rollup": "4.30.1",
|
||||||
"unbuild": "3.2.0",
|
"unbuild": "3.2.0",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/pug": "2.0.10",
|
"@types/pug": "2.0.10",
|
||||||
"@unhead/schema": "1.11.14",
|
"@unhead/schema": "1.11.15",
|
||||||
"@vitejs/plugin-vue": "5.2.1",
|
"@vitejs/plugin-vue": "5.2.1",
|
||||||
"@vitejs/plugin-vue-jsx": "4.1.1",
|
"@vitejs/plugin-vue-jsx": "4.1.1",
|
||||||
"@vue/compiler-core": "3.5.13",
|
"@vue/compiler-core": "3.5.13",
|
||||||
@ -70,7 +70,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"consola": "^3.3.3",
|
"consola": "^3.3.3",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"std-env": "^3.8.0"
|
"std-env": "^3.8.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -17,19 +17,19 @@
|
|||||||
"prerender": "pnpm build && jiti ./lib/prerender"
|
"prerender": "pnpm build && jiti ./lib/prerender"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@unocss/reset": "0.65.3",
|
"@unocss/reset": "65.4.0",
|
||||||
"beasties": "0.2.0",
|
"beasties": "0.2.0",
|
||||||
"html-validate": "9.1.1",
|
"html-validate": "9.1.3",
|
||||||
"htmlnano": "2.1.1",
|
"htmlnano": "2.1.1",
|
||||||
"jiti": "2.4.2",
|
"jiti": "2.4.2",
|
||||||
"knitwork": "1.2.0",
|
"knitwork": "1.2.0",
|
||||||
"pathe": "2.0.0",
|
"pathe": "2.0.1",
|
||||||
"prettier": "3.4.2",
|
"prettier": "3.4.2",
|
||||||
"scule": "1.3.0",
|
"scule": "1.3.0",
|
||||||
"svgo": "3.3.2",
|
"svgo": "3.3.2",
|
||||||
"tinyexec": "0.3.2",
|
"tinyexec": "0.3.2",
|
||||||
"tinyglobby": "0.2.10",
|
"tinyglobby": "0.2.10",
|
||||||
"unocss": "0.65.3",
|
"unocss": "65.4.0",
|
||||||
"vite": "6.0.7"
|
"vite": "6.0.7"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/schema": "workspace:*",
|
"@nuxt/schema": "workspace:*",
|
||||||
"rollup": "4.30.0",
|
"rollup": "4.30.1",
|
||||||
"unbuild": "3.2.0",
|
"unbuild": "3.2.0",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
@ -48,7 +48,7 @@
|
|||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"mlly": "^1.7.3",
|
"mlly": "^1.7.3",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"pkg-types": "^1.3.0",
|
"pkg-types": "^1.3.0",
|
||||||
"postcss": "^8.4.49",
|
"postcss": "^8.4.49",
|
||||||
"rollup-plugin-visualizer": "^5.13.1",
|
"rollup-plugin-visualizer": "^5.13.1",
|
||||||
|
@ -46,10 +46,10 @@
|
|||||||
"jiti": "^2.4.2",
|
"jiti": "^2.4.2",
|
||||||
"knitwork": "^1.2.0",
|
"knitwork": "^1.2.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"memfs": "^4.15.3",
|
"memfs": "^4.17.0",
|
||||||
"mini-css-extract-plugin": "^2.9.2",
|
"mini-css-extract-plugin": "^2.9.2",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^1.1.4",
|
||||||
"pathe": "^2.0.0",
|
"pathe": "^2.0.1",
|
||||||
"pify": "^6.1.0",
|
"pify": "^6.1.0",
|
||||||
"postcss": "^8.4.49",
|
"postcss": "^8.4.49",
|
||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
@ -77,7 +77,7 @@
|
|||||||
"@types/pify": "5.0.4",
|
"@types/pify": "5.0.4",
|
||||||
"@types/webpack-bundle-analyzer": "4.7.0",
|
"@types/webpack-bundle-analyzer": "4.7.0",
|
||||||
"@types/webpack-hot-middleware": "2.25.9",
|
"@types/webpack-hot-middleware": "2.25.9",
|
||||||
"rollup": "4.30.0",
|
"rollup": "4.30.1",
|
||||||
"unbuild": "3.2.0",
|
"unbuild": "3.2.0",
|
||||||
"vue": "3.5.13"
|
"vue": "3.5.13"
|
||||||
},
|
},
|
||||||
|
4175
pnpm-lock.yaml
4175
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -61,7 +61,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"210k"`)
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"210k"`)
|
||||||
|
|
||||||
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1396k"`)
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1398k"`)
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
@ -86,6 +86,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
"entities",
|
"entities",
|
||||||
"estree-walker",
|
"estree-walker",
|
||||||
"hookable",
|
"hookable",
|
||||||
|
"packrup",
|
||||||
"source-map-js",
|
"source-map-js",
|
||||||
"ufo",
|
"ufo",
|
||||||
"unhead",
|
"unhead",
|
||||||
@ -102,7 +103,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"561k"`)
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"561k"`)
|
||||||
|
|
||||||
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"94.4k"`)
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"96.4k"`)
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
@ -116,6 +117,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
"db0",
|
"db0",
|
||||||
"devalue",
|
"devalue",
|
||||||
"hookable",
|
"hookable",
|
||||||
|
"packrup",
|
||||||
"unhead",
|
"unhead",
|
||||||
]
|
]
|
||||||
`)
|
`)
|
||||||
@ -128,7 +130,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"303k"`)
|
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"303k"`)
|
||||||
|
|
||||||
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
|
||||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1396k"`)
|
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1398k"`)
|
||||||
|
|
||||||
const packages = modules.files
|
const packages = modules.files
|
||||||
.filter(m => m.endsWith('package.json'))
|
.filter(m => m.endsWith('package.json'))
|
||||||
@ -153,6 +155,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
|||||||
"entities",
|
"entities",
|
||||||
"estree-walker",
|
"estree-walker",
|
||||||
"hookable",
|
"hookable",
|
||||||
|
"packrup",
|
||||||
"source-map-js",
|
"source-map-js",
|
||||||
"ufo",
|
"ufo",
|
||||||
"unhead",
|
"unhead",
|
||||||
|
Loading…
Reference in New Issue
Block a user