mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat: auto global imports (#410)
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
parent
50acd3dda5
commit
b2b4c64807
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -51,6 +51,9 @@ jobs:
|
|||||||
- name: Stub
|
- name: Stub
|
||||||
run: yarn stub
|
run: yarn stub
|
||||||
|
|
||||||
|
- name: Test (unit)
|
||||||
|
run: yarn test:unit
|
||||||
|
|
||||||
- name: Test (presets)
|
- name: Test (presets)
|
||||||
run: yarn test:presets
|
run: yarn test:presets
|
||||||
|
|
||||||
|
@ -32,8 +32,6 @@ This helper only works with:
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { asyncData, defineNuxtComponent } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
setup () {
|
setup () {
|
||||||
const { data } = asyncData('time', () => $fetch('/api/count'))
|
const { data } = asyncData('time', () => $fetch('/api/count'))
|
||||||
@ -47,8 +45,6 @@ When using with the `<script setup>` syntax, an addition attribute `nuxt` is req
|
|||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup nuxt>
|
<script setup nuxt>
|
||||||
import { asyncData } from '@nuxt/app'
|
|
||||||
|
|
||||||
const { data } = asyncData('time', () => $fetch('/api/count'))
|
const { data } = asyncData('time', () => $fetch('/api/count'))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -8,9 +8,6 @@ Within your `setup()` function you can call `useMeta` with an object of meta pro
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
```ts
|
```ts
|
||||||
import { ref } from 'vue'
|
|
||||||
import { useMeta } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup () {
|
setup () {
|
||||||
useMeta({
|
useMeta({
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
<script nuxt setup lang="ts">
|
<script nuxt setup lang="ts">
|
||||||
import { asyncData } from '@nuxt/app'
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { data } = asyncData('time', () => $fetch('/api/count'))
|
const { data } = asyncData('time', () => $fetch('/api/count'))
|
||||||
</script>
|
</script>
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineNuxtComponent, asyncData } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
setup () {
|
setup () {
|
||||||
const { data } = asyncData('time', () => $fetch('/api/count'))
|
const { data } = asyncData('time', () => $fetch('/api/count'))
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineNuxtComponent } from '@nuxt/app'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
fetchKey: 'custom',
|
fetchKey: 'custom',
|
||||||
asyncData ({ route }) {
|
asyncData ({ route }) {
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref } from 'vue'
|
|
||||||
import { useMeta } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup () {
|
setup () {
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineNuxtComponent } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
layout: 'custom'
|
layout: 'custom'
|
||||||
})
|
})
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ContentLoader } from 'vue-content-loader'
|
import { ContentLoader } from 'vue-content-loader'
|
||||||
import { defineNuxtComponent, asyncData } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
components: { ContentLoader },
|
components: { ContentLoader },
|
||||||
setup () {
|
setup () {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"test": "yarn lint && yarn test:presets",
|
"test": "yarn lint && yarn test:presets",
|
||||||
"test:presets": "mocha test/presets/*.mjs",
|
"test:presets": "mocha test/presets/*.mjs",
|
||||||
"test:compat": "TEST_COMPAT=1 yarn test:presets",
|
"test:compat": "TEST_COMPAT=1 yarn test:presets",
|
||||||
|
"test:unit": "mocha -r jiti/register packages/**/test/*.test.*",
|
||||||
"version": "yarn && git add yarn.lock"
|
"version": "yarn && git add yarn.lock"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
8
packages/global-imports/build.config.ts
Normal file
8
packages/global-imports/build.config.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { defineBuildConfig } from 'unbuild'
|
||||||
|
|
||||||
|
export default defineBuildConfig({
|
||||||
|
declaration: true,
|
||||||
|
entries: [
|
||||||
|
'src/module'
|
||||||
|
]
|
||||||
|
})
|
1
packages/global-imports/module.js
Normal file
1
packages/global-imports/module.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = require('./dist/module')
|
28
packages/global-imports/package.json
Normal file
28
packages/global-imports/package.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "@nuxt/global-imports",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"repository": "nuxt/framework",
|
||||||
|
"license": "MIT",
|
||||||
|
"exports": {
|
||||||
|
"./module": {
|
||||||
|
"import": "./dist/module.mjs",
|
||||||
|
"require": "./dist/module.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"types": "./dist/module.d.ts",
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prepack": "unbuild"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxt/kit": "^0.6.4",
|
||||||
|
"ufo": "^0.7.7",
|
||||||
|
"unplugin": "^0.0.5",
|
||||||
|
"upath": "^2.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"unbuild": "^0.4.2"
|
||||||
|
}
|
||||||
|
}
|
57
packages/global-imports/src/identifiers.ts
Normal file
57
packages/global-imports/src/identifiers.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
const VueAPIs = [
|
||||||
|
// lifecycle
|
||||||
|
'onActivated',
|
||||||
|
'onBeforeMount',
|
||||||
|
'onBeforeUnmount',
|
||||||
|
'onBeforeUpdate',
|
||||||
|
'onDeactivated',
|
||||||
|
'onErrorCaptured',
|
||||||
|
'onMounted',
|
||||||
|
'onServerPrefetch',
|
||||||
|
'onUnmounted',
|
||||||
|
'onUpdated',
|
||||||
|
|
||||||
|
// reactivity,
|
||||||
|
'computed',
|
||||||
|
'customRef',
|
||||||
|
'isReadonly',
|
||||||
|
'isRef',
|
||||||
|
'markRaw',
|
||||||
|
'reactive',
|
||||||
|
'readonly',
|
||||||
|
'ref',
|
||||||
|
'shallowReactive',
|
||||||
|
'shallowReadonly',
|
||||||
|
'shallowRef',
|
||||||
|
'toRaw',
|
||||||
|
'toRef',
|
||||||
|
'toRefs',
|
||||||
|
'triggerRef',
|
||||||
|
'unref',
|
||||||
|
'watch',
|
||||||
|
'watchEffect',
|
||||||
|
|
||||||
|
// component
|
||||||
|
'defineComponent',
|
||||||
|
'defineAsyncComponent',
|
||||||
|
'getCurrentInstance',
|
||||||
|
'h',
|
||||||
|
'inject',
|
||||||
|
'nextTick',
|
||||||
|
'provide',
|
||||||
|
'useCssModule'
|
||||||
|
]
|
||||||
|
|
||||||
|
const nuxtComposition = [
|
||||||
|
'useAsyncData',
|
||||||
|
'asyncData',
|
||||||
|
'defineNuxtComponent',
|
||||||
|
'useNuxt',
|
||||||
|
'defineNuxtPlugin',
|
||||||
|
'useMeta'
|
||||||
|
]
|
||||||
|
|
||||||
|
export const defaultIdentifiers = Object.fromEntries([
|
||||||
|
...VueAPIs.map(name => [name, 'vue']),
|
||||||
|
...nuxtComposition.map(name => [name, '@nuxt/app'])
|
||||||
|
])
|
57
packages/global-imports/src/module.ts
Normal file
57
packages/global-imports/src/module.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, addPluginTemplate } from '@nuxt/kit'
|
||||||
|
import { resolve } from 'upath'
|
||||||
|
import type { Identifiers, GlobalImportsOptions } from './types'
|
||||||
|
import { TrsnsformPlugin } from './transform'
|
||||||
|
import { defaultIdentifiers } from './identifiers'
|
||||||
|
|
||||||
|
export default defineNuxtModule<GlobalImportsOptions>({
|
||||||
|
name: 'global-imports',
|
||||||
|
configKey: 'globalImports',
|
||||||
|
defaults: { identifiers: defaultIdentifiers },
|
||||||
|
setup ({ identifiers }, nuxt) {
|
||||||
|
if (nuxt.options.dev) {
|
||||||
|
// Add all imports to globalThis in development mode
|
||||||
|
addPluginTemplate({
|
||||||
|
filename: 'global-imports.mjs',
|
||||||
|
src: '',
|
||||||
|
getContents: () => {
|
||||||
|
const imports = toImports(Object.entries(identifiers))
|
||||||
|
const globalThisSet = Object.keys(identifiers).map(name => `globalThis.${name} = ${name};`).join('\n')
|
||||||
|
return `${imports}\n\n${globalThisSet}\n\nexport default () => {};`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Transform to inject imports in production mode
|
||||||
|
addVitePlugin(TrsnsformPlugin.vite(identifiers))
|
||||||
|
addWebpackPlugin(TrsnsformPlugin.webpack(identifiers))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add types
|
||||||
|
addTemplate({
|
||||||
|
filename: 'global-imports.d.ts',
|
||||||
|
write: true,
|
||||||
|
getContents: () => `// Generated by global imports
|
||||||
|
declare global {
|
||||||
|
${Object.entries(identifiers).map(([api, moduleName]) => ` const ${api}: typeof import('${moduleName}')['${api}']`).join('\n')}
|
||||||
|
}\nexport {}`
|
||||||
|
})
|
||||||
|
nuxt.hook('prepare:types', ({ references }) => {
|
||||||
|
references.push({ path: resolve(nuxt.options.buildDir, 'global-imports.d.ts') })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function toImports (identifiers: Identifiers) {
|
||||||
|
const map: Record<string, Set<string>> = {}
|
||||||
|
|
||||||
|
identifiers.forEach(([name, moduleName]) => {
|
||||||
|
if (!map[moduleName]) {
|
||||||
|
map[moduleName] = new Set()
|
||||||
|
}
|
||||||
|
map[moduleName].add(name)
|
||||||
|
})
|
||||||
|
|
||||||
|
return Object.entries(map)
|
||||||
|
.map(([name, imports]) => `import { ${Array.from(imports).join(', ')} } from '${name}';`)
|
||||||
|
.join('\n')
|
||||||
|
}
|
68
packages/global-imports/src/transform.ts
Normal file
68
packages/global-imports/src/transform.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { createUnplugin } from 'unplugin'
|
||||||
|
import { parseQuery, parseURL } from 'ufo'
|
||||||
|
import { IdentifierMap } from './types'
|
||||||
|
|
||||||
|
const excludeRegex = [
|
||||||
|
// imported from other module
|
||||||
|
/\bimport\s*\{([\s\S]*?)\}\s*from\b/g,
|
||||||
|
// defined as function
|
||||||
|
/\bfunction\s*([\s\S]+?)\s*\(/g,
|
||||||
|
// defined as local variable
|
||||||
|
/\b(?:const|let|var)\s*([\w\d_$]+?)\b/g
|
||||||
|
]
|
||||||
|
|
||||||
|
export const TrsnsformPlugin = createUnplugin((map: IdentifierMap) => {
|
||||||
|
const regex = new RegExp('\\b(' + (Object.keys(map).join('|')) + ')\\b', 'g')
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'nuxt-global-imports-transform',
|
||||||
|
enforce: 'post',
|
||||||
|
transformInclude (id) {
|
||||||
|
const { pathname, search } = parseURL(id)
|
||||||
|
const query = parseQuery(search)
|
||||||
|
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// vue files
|
||||||
|
if (pathname.endsWith('.vue') && (query.type === 'template' || !search)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// js files
|
||||||
|
if (pathname.match(/\.((c|m)?j|t)sx?/g)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transform (code) {
|
||||||
|
// find all possible injection
|
||||||
|
const matched = new Set(Array.from(code.matchAll(regex)).map(i => i[1]))
|
||||||
|
|
||||||
|
// remove those already defined
|
||||||
|
for (const regex of excludeRegex) {
|
||||||
|
Array.from(code.matchAll(regex))
|
||||||
|
.flatMap(i => i[1]?.split(',') || [])
|
||||||
|
.forEach(i => matched.delete(i.trim()))
|
||||||
|
}
|
||||||
|
|
||||||
|
const modules: Record<string, string[]> = {}
|
||||||
|
|
||||||
|
// group by module name
|
||||||
|
Array.from(matched).forEach((name) => {
|
||||||
|
const moduleName = map[name]!
|
||||||
|
if (!modules[moduleName]) {
|
||||||
|
modules[moduleName] = []
|
||||||
|
}
|
||||||
|
modules[moduleName].push(name)
|
||||||
|
})
|
||||||
|
|
||||||
|
// stringify import
|
||||||
|
const imports = Object.entries(modules)
|
||||||
|
.map(([moduleName, names]) => `import { ${names.join(',')} } from '${moduleName}';`)
|
||||||
|
.join('')
|
||||||
|
|
||||||
|
return imports + code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
6
packages/global-imports/src/types.ts
Normal file
6
packages/global-imports/src/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export type IdentifierMap = Record<string, string>
|
||||||
|
export type Identifiers = [string, string][]
|
||||||
|
|
||||||
|
export interface GlobalImportsOptions {
|
||||||
|
identifiers?: IdentifierMap
|
||||||
|
}
|
16
packages/global-imports/test/build.test.ts
Normal file
16
packages/global-imports/test/build.test.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { expect } from 'chai'
|
||||||
|
import { TrsnsformPlugin } from '../src/transform'
|
||||||
|
|
||||||
|
describe('module:global-imports:build', () => {
|
||||||
|
const { transform } = TrsnsformPlugin.raw({ ref: 'vue' })
|
||||||
|
|
||||||
|
it('should correct inject', () => {
|
||||||
|
expect(transform('const a = ref(0)', ''))
|
||||||
|
.to.equal('import { ref } from \'vue\';const a = ref(0)')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should ignore imported', () => {
|
||||||
|
expect(transform('import { ref } from "foo";const a = ref(0)', ''))
|
||||||
|
.to.equal('import { ref } from "foo";const a = ref(0)')
|
||||||
|
})
|
||||||
|
})
|
@ -36,6 +36,8 @@ export function normalizeTemplate (template: NuxtTemplate | string): NuxtTemplat
|
|||||||
// Normalize
|
// Normalize
|
||||||
if (typeof template === 'string') {
|
if (typeof template === 'string') {
|
||||||
template = { src: template }
|
template = { src: template }
|
||||||
|
} else {
|
||||||
|
template = { ...template }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use src if provided
|
// Use src if provided
|
||||||
@ -74,7 +76,10 @@ export function normalizePlugin (plugin: NuxtPlugin | string): NuxtPlugin {
|
|||||||
// Normalize src
|
// Normalize src
|
||||||
if (typeof plugin === 'string') {
|
if (typeof plugin === 'string') {
|
||||||
plugin = { src: plugin }
|
plugin = { src: plugin }
|
||||||
|
} else {
|
||||||
|
plugin = { ...plugin }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plugin.src) {
|
if (!plugin.src) {
|
||||||
throw new Error('Invalid plugin. src option is required: ' + JSON.stringify(plugin))
|
throw new Error('Invalid plugin. src option is required: ' + JSON.stringify(plugin))
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/app": "^0.5.0",
|
"@nuxt/app": "^0.5.0",
|
||||||
"@nuxt/component-discovery": "^0.2.0",
|
"@nuxt/component-discovery": "^0.2.0",
|
||||||
|
"@nuxt/global-imports": "^0.1.0",
|
||||||
"@nuxt/kit": "^0.6.4",
|
"@nuxt/kit": "^0.6.4",
|
||||||
"@nuxt/meta": "^0.1.0",
|
"@nuxt/meta": "^0.1.0",
|
||||||
"@nuxt/nitro": "^0.9.1",
|
"@nuxt/nitro": "^0.9.1",
|
||||||
|
@ -57,6 +57,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
|||||||
options.buildModules.push(normalize(require.resolve('@nuxt/pages/module')))
|
options.buildModules.push(normalize(require.resolve('@nuxt/pages/module')))
|
||||||
options.buildModules.push(normalize(require.resolve('@nuxt/meta/module')))
|
options.buildModules.push(normalize(require.resolve('@nuxt/meta/module')))
|
||||||
options.buildModules.push(normalize(require.resolve('@nuxt/component-discovery/module')))
|
options.buildModules.push(normalize(require.resolve('@nuxt/component-discovery/module')))
|
||||||
|
options.buildModules.push(normalize(require.resolve('@nuxt/global-imports/module')))
|
||||||
|
|
||||||
const nuxt = createNuxt(options)
|
const nuxt = createNuxt(options)
|
||||||
|
|
||||||
|
8
playground/nuxt.d.ts
vendored
8
playground/nuxt.d.ts
vendored
@ -1,7 +1,13 @@
|
|||||||
// Declarations auto generated by `nuxt prepare`. Please do not manually modify this file.
|
// This file is auto generated by `nuxt prepare`
|
||||||
|
// Please do not manually modify this file.
|
||||||
|
|
||||||
/// <reference types="@nuxt/kit" />
|
/// <reference types="@nuxt/kit" />
|
||||||
|
/// <reference types="@nuxt/app" />
|
||||||
/// <reference types="@nuxt/nitro" />
|
/// <reference types="@nuxt/nitro" />
|
||||||
/// <reference types="@nuxt/pages" />
|
/// <reference types="@nuxt/pages" />
|
||||||
/// <reference types="@nuxt/meta" />
|
/// <reference types="@nuxt/meta" />
|
||||||
/// <reference types="@nuxt/component-discovery" />
|
/// <reference types="@nuxt/component-discovery" />
|
||||||
|
/// <reference types="@nuxt/global-imports" />
|
||||||
|
/// <reference path=".nuxt/components.d.ts" />
|
||||||
|
/// <reference path=".nuxt/global-imports.d.ts" />
|
||||||
|
export {}
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineNuxtComponent } from '@nuxt/app'
|
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
export default defineNuxtComponent({
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"mocha",
|
"mocha",
|
||||||
"chai",
|
"chai",
|
||||||
"@nuxt/app",
|
"@nuxt/app",
|
||||||
"@nuxt/nitro",
|
"@nuxt/nitro"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"exclude": ["./packages/*/dist/*"]
|
"exclude": ["./packages/*/dist/*"]
|
||||||
|
13
yarn.lock
13
yarn.lock
@ -1335,6 +1335,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@nuxt/global-imports@^0.1.0, @nuxt/global-imports@workspace:packages/global-imports":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@nuxt/global-imports@workspace:packages/global-imports"
|
||||||
|
dependencies:
|
||||||
|
"@nuxt/kit": ^0.6.4
|
||||||
|
ufo: ^0.7.7
|
||||||
|
unbuild: ^0.4.2
|
||||||
|
unplugin: ^0.0.5
|
||||||
|
upath: ^2.0.1
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@nuxt/kit@^0.6.4, @nuxt/kit@workspace:packages/kit":
|
"@nuxt/kit@^0.6.4, @nuxt/kit@workspace:packages/kit":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@nuxt/kit@workspace:packages/kit"
|
resolution: "@nuxt/kit@workspace:packages/kit"
|
||||||
@ -8735,6 +8747,7 @@ fsevents@~2.3.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@nuxt/app": ^0.5.0
|
"@nuxt/app": ^0.5.0
|
||||||
"@nuxt/component-discovery": ^0.2.0
|
"@nuxt/component-discovery": ^0.2.0
|
||||||
|
"@nuxt/global-imports": ^0.1.0
|
||||||
"@nuxt/kit": ^0.6.4
|
"@nuxt/kit": ^0.6.4
|
||||||
"@nuxt/meta": ^0.1.0
|
"@nuxt/meta": ^0.1.0
|
||||||
"@nuxt/nitro": ^0.9.1
|
"@nuxt/nitro": ^0.9.1
|
||||||
|
Loading…
Reference in New Issue
Block a user