mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 07:05:11 +00:00
feat: module utils and improvements (#38)
This commit is contained in:
parent
1b9edfafb9
commit
b3f3dc94f3
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@ package-lock.json
|
||||
dist
|
||||
.nuxt*
|
||||
.output
|
||||
.gen
|
||||
|
||||
# Junit reports
|
||||
reports
|
||||
|
16
package.json
16
package.json
@ -7,12 +7,13 @@
|
||||
],
|
||||
"scripts": {
|
||||
"link": "lerna link",
|
||||
"build": "yarn workspaces run build --silent",
|
||||
"stub": "yarn workspaces run stub --silent",
|
||||
"play": "yarn nu dev playground",
|
||||
"lint": "eslint --ext .vue,.ts,.js .",
|
||||
"test": "yarn lint",
|
||||
"postinstall": "yarn stub"
|
||||
"build": "yarn -s workspaces run build",
|
||||
"stub": "yarn -s build --stub",
|
||||
"gentypes": "yarn -s --cwd packages/kit gentypes",
|
||||
"play": "yarn -s nu dev playground",
|
||||
"lint": "yarn -s gentypes && eslint --ext .vue,.ts,.js .",
|
||||
"test": "yarn -s lint",
|
||||
"postinstall": "yarn -s stub"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^6.0.0",
|
||||
@ -26,10 +27,11 @@
|
||||
"defu": "^3.2.2",
|
||||
"esbuild": "^0.10.2",
|
||||
"eslint": "^7.23.0",
|
||||
"execa": "^5.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"jiti": "^1.6.4",
|
||||
"lerna": "^4.0.0",
|
||||
"mkdist": "^0.1.2",
|
||||
"mkdist": "^0.1.3",
|
||||
"pretty-bytes": "^5.6.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.43.1",
|
||||
|
@ -3,29 +3,22 @@
|
||||
"version": "0.0.0",
|
||||
"repository": "nuxt/framework",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.ts",
|
||||
"main": "./dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "mkdist",
|
||||
"stub": "rm -rf dist && ln -s src dist #",
|
||||
"build": "jiti ../../scripts/build .",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"dependencies": {
|
||||
"create-require": "^1.1.1",
|
||||
"defu": "^3.2.2",
|
||||
"dotenv": "^8.2.0",
|
||||
"jiti": "^1.6.4",
|
||||
"rc9": "^1.2.0",
|
||||
"scule": "^0.1.1",
|
||||
"std-env": "^2.3.0",
|
||||
"ufo": "^0.6.10",
|
||||
"untyped": "^0.2.2"
|
||||
"hookable": "^4.4.1",
|
||||
"vue": "^3.0.10"
|
||||
},
|
||||
"build": {
|
||||
"entries": {
|
||||
"index": {}
|
||||
"index": { "distDir": ".gen" },
|
||||
"/": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ async function initApp () {
|
||||
await app.$nuxt.hooks.callHook('app:created', app)
|
||||
await app.$nuxt.hooks.callHook('app:beforeMount', app)
|
||||
|
||||
app.mount('#<%= globals.id %>')
|
||||
app.mount('#__nuxt')
|
||||
|
||||
await app.$nuxt.hooks.callHook('app:mounted', app)
|
||||
await nextTick()
|
||||
|
10
packages/app/src/declarations/node.d.ts
vendored
10
packages/app/src/declarations/node.d.ts
vendored
@ -1,10 +0,0 @@
|
||||
declare module NodeJS {
|
||||
interface Process {
|
||||
browser: boolean
|
||||
client: boolean
|
||||
mode: 'spa' | 'universal'
|
||||
modern: boolean
|
||||
server: boolean
|
||||
static: boolean
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
declare module 'nuxt/build/routes' {
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
const _default: RouteRecordRaw[]
|
||||
export default _default
|
||||
}
|
5
packages/app/src/declarations/shim.d.ts
vendored
5
packages/app/src/declarations/shim.d.ts
vendored
@ -1,5 +0,0 @@
|
||||
declare module '*.vue' {
|
||||
import { Component } from 'vue'
|
||||
const component: Component
|
||||
export default component
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { Nuxt } from '@nuxt/app'
|
||||
|
||||
declare module 'vue' {
|
||||
interface App {
|
||||
$nuxt: Nuxt
|
||||
}
|
||||
}
|
3
packages/app/src/declarations/window.d.ts
vendored
3
packages/app/src/declarations/window.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
interface Window {
|
||||
__NUXT__?: Record<string, any>
|
||||
}
|
1
packages/app/src/index.js
Normal file
1
packages/app/src/index.js
Normal file
@ -0,0 +1 @@
|
||||
export * from './index.ts'
|
@ -1,2 +1,4 @@
|
||||
export { useNuxt } from './nuxt/composables'
|
||||
|
||||
export * from './nuxt'
|
||||
export * from './shim'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { getCurrentInstance } from 'vue'
|
||||
import type { Nuxt } from '@nuxt/app'
|
||||
import type { Nuxt } from '../nuxt'
|
||||
|
||||
let currentNuxtInstance: Nuxt | null
|
||||
|
||||
|
24
packages/app/src/shim.ts
Normal file
24
packages/app/src/shim.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { Nuxt } from './nuxt'
|
||||
|
||||
declare module 'vue' {
|
||||
interface App {
|
||||
$nuxt: Nuxt
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__NUXT__?: Record<string, any>
|
||||
}
|
||||
|
||||
namespace NodeJS {
|
||||
interface Process {
|
||||
browser: boolean
|
||||
client: boolean
|
||||
mode: 'spa' | 'universal'
|
||||
modern: boolean
|
||||
server: boolean
|
||||
static: boolean
|
||||
}
|
||||
}
|
||||
}
|
@ -10,24 +10,26 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "jiti ../../scripts/build .",
|
||||
"genconfig": "jiti ./scripts/genconfig",
|
||||
"stub": "yarn build --stub",
|
||||
"prepublishOnly": "yarn build && yarn genconfig"
|
||||
"gentypes": "jiti ./scripts/gentypes",
|
||||
"prepublishOnly": "yarn build && yarn gentypes"
|
||||
},
|
||||
"dependencies": {
|
||||
"consola": "^2.15.3",
|
||||
"create-require": "^1.1.1",
|
||||
"defu": "^3.2.2",
|
||||
"dotenv": "^8.2.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"jiti": "^1.6.4",
|
||||
"lodash": "^4.17.21",
|
||||
"rc9": "^1.2.0",
|
||||
"scule": "^0.1.1",
|
||||
"std-env": "^2.3.0",
|
||||
"ufo": "^0.6.10",
|
||||
"untyped": "^0.2.2"
|
||||
"unctx": "^0.0.3",
|
||||
"untyped": "^0.2.2",
|
||||
"upath": "^2.0.1"
|
||||
},
|
||||
"build": {
|
||||
"prebuild": "yarn -s gentypes",
|
||||
"entries": {
|
||||
"index": {
|
||||
"format": "cjs"
|
||||
|
@ -3,7 +3,7 @@ import { mkdir, writeFile } from 'fs/promises'
|
||||
import { resolveSchema, generateTypes, generateMarkdown } from 'untyped'
|
||||
|
||||
async function main () {
|
||||
const genDir = resolve(__dirname, '../dist/config')
|
||||
const genDir = resolve(__dirname, '../.gen')
|
||||
const srcConfig = await import('../src/config/schema').then(r => r.default)
|
||||
|
||||
const defaults = { rootDir: '/<dir>/' }
|
||||
@ -11,9 +11,9 @@ async function main () {
|
||||
|
||||
await mkdir(genDir).catch(() => { })
|
||||
await writeFile(resolve(genDir, 'config.md'), generateMarkdown(schema))
|
||||
await writeFile(resolve(genDir, 'schema.json'), JSON.stringify(schema, null, 2))
|
||||
await writeFile(resolve(genDir, 'defaults.json'), JSON.stringify(defaults, null, 2))
|
||||
await writeFile(resolve(genDir, 'config.d.ts'), 'export default ' + generateTypes(schema, 'Config'))
|
||||
await writeFile(resolve(genDir, 'config.schema.json'), JSON.stringify(schema, null, 2))
|
||||
await writeFile(resolve(genDir, 'config.defaults.json'), JSON.stringify(defaults, null, 2))
|
||||
await writeFile(resolve(genDir, 'config.d.ts'), 'export ' + generateTypes(schema, 'ConfigSchema'))
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
@ -3,6 +3,7 @@ import defu from 'defu'
|
||||
import jiti from 'jiti'
|
||||
import { applyDefaults } from 'untyped'
|
||||
import * as rc from 'rc9'
|
||||
import { NuxtOptions } from '../types/config'
|
||||
import nuxtConfigSchema from './schema'
|
||||
|
||||
export interface LoadNuxtConfigOptions {
|
||||
@ -11,7 +12,7 @@ export interface LoadNuxtConfigOptions {
|
||||
config?: any
|
||||
}
|
||||
|
||||
export function loadNuxtConfig (opts: LoadNuxtConfigOptions) {
|
||||
export function loadNuxtConfig (opts: LoadNuxtConfigOptions): NuxtOptions {
|
||||
const rootDir = resolve(process.cwd(), opts.rootDir || '.')
|
||||
|
||||
const _require = jiti(rootDir)
|
||||
@ -53,5 +54,5 @@ export function loadNuxtConfig (opts: LoadNuxtConfigOptions) {
|
||||
}
|
||||
|
||||
// Resolve and apply defaults
|
||||
return applyDefaults(nuxtConfigSchema, nuxtConfig)
|
||||
return applyDefaults(nuxtConfigSchema, nuxtConfig) as NuxtOptions
|
||||
}
|
||||
|
@ -112,10 +112,10 @@ export default {
|
||||
},
|
||||
|
||||
extensions: {
|
||||
$resolve: val => ['js', 'mjs', 'ts', 'tsx', 'vue'].concat(val).filter(Boolean)
|
||||
$resolve: val => ['.js', '.mjs', '.ts', '.tsx', '.vue'].concat(val).filter(Boolean)
|
||||
},
|
||||
|
||||
styleExtensions: ['css', 'pcss', 'postcss', 'styl', 'stylus', 'scss', 'sass', 'less'],
|
||||
styleExtensions: ['.css', '.pcss', '.postcss', '.styl', '.stylus', '.scss', '.sass', '.less'],
|
||||
|
||||
alias: {
|
||||
$resolve: (val, get) => ({
|
||||
|
11
packages/kit/src/config/schema/_internal.ts
Normal file
11
packages/kit/src/config/schema/_internal.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
_majorVersion: 2,
|
||||
_legacyGenerate: false,
|
||||
_start: false,
|
||||
_build: false,
|
||||
_generate: false,
|
||||
_cli: false,
|
||||
_requiredModules: {},
|
||||
appDir: '',
|
||||
vite: false
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
|
||||
import _app from './_app'
|
||||
import _common from './_common'
|
||||
import _internal from './_internal'
|
||||
import build from './build'
|
||||
import messages from './messages'
|
||||
import render from './render'
|
||||
@ -30,6 +31,7 @@ TODO for top level normalizations: (nuxt2)
|
||||
export default {
|
||||
..._app,
|
||||
..._common,
|
||||
..._internal,
|
||||
build,
|
||||
messages,
|
||||
render,
|
||||
|
@ -1,3 +1,22 @@
|
||||
// Config
|
||||
export * from './config/load'
|
||||
export * from './config/env'
|
||||
export * from './utils'
|
||||
|
||||
// Nuxt
|
||||
export * from './nuxt'
|
||||
|
||||
// Module
|
||||
export * from './module/container'
|
||||
export * from './module/define'
|
||||
export * from './module/install'
|
||||
export * from './module/utils'
|
||||
|
||||
// Utils
|
||||
export * from './utils/cjs'
|
||||
export * from './utils/resolve'
|
||||
|
||||
// Types
|
||||
export * from './types/config'
|
||||
export * from './types/hooks'
|
||||
export * from './types/module'
|
||||
export * from './types/nuxt'
|
||||
|
73
packages/kit/src/module/container.ts
Normal file
73
packages/kit/src/module/container.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import type { Nuxt } from '../types/nuxt'
|
||||
import type { NuxtOptions } from '../types/config'
|
||||
import type { TemplateOpts, PluginTemplateOpts } from '../types/module'
|
||||
import { nuxtCtx } from '../nuxt'
|
||||
import { installModule } from './install'
|
||||
import {
|
||||
addTemplate,
|
||||
addErrorLayout,
|
||||
addLayout,
|
||||
addPlugin,
|
||||
addServerMiddleware,
|
||||
extendBuild,
|
||||
extendRoutes
|
||||
} from './utils'
|
||||
|
||||
export class ModuleContainer {
|
||||
nuxt: Nuxt
|
||||
options: NuxtOptions
|
||||
|
||||
constructor (nuxt: Nuxt) {
|
||||
this.nuxt = nuxt
|
||||
this.options = nuxt.options
|
||||
}
|
||||
|
||||
private _call<F extends (...args: any) => any>(fn: F, ...args: Parameters<F>): ReturnType<F> {
|
||||
// @ts-ignore
|
||||
return nuxtCtx.call(this.nuxt, () => fn(...args))
|
||||
}
|
||||
|
||||
ready () {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
addVendor () {
|
||||
console.warn('addVendor has been deprecated')
|
||||
}
|
||||
|
||||
addTemplate (tmpl: TemplateOpts | string) {
|
||||
return this._call(addTemplate, tmpl)
|
||||
}
|
||||
|
||||
addPlugin (tmpl: PluginTemplateOpts) {
|
||||
return this._call(addPlugin, tmpl)
|
||||
}
|
||||
|
||||
addLayout (tmpl: TemplateOpts, name: string) {
|
||||
return this._call(addLayout, tmpl, name)
|
||||
}
|
||||
|
||||
addErrorLayout (dst: string) {
|
||||
return this._call(addErrorLayout, dst)
|
||||
}
|
||||
|
||||
addServerMiddleware (middleware) {
|
||||
return this._call(addServerMiddleware, middleware)
|
||||
}
|
||||
|
||||
extendBuild (fn) {
|
||||
return this._call(extendBuild, fn)
|
||||
}
|
||||
|
||||
extendRoutes (fn) {
|
||||
return this._call(extendRoutes, fn)
|
||||
}
|
||||
|
||||
requireModule (moduleOpts) {
|
||||
return installModule(this.nuxt, moduleOpts)
|
||||
}
|
||||
|
||||
addModule (moduleOpts) {
|
||||
return installModule(this.nuxt, moduleOpts)
|
||||
}
|
||||
}
|
44
packages/kit/src/module/define.ts
Normal file
44
packages/kit/src/module/define.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import defu from 'defu'
|
||||
import { applyDefaults } from 'untyped'
|
||||
import { useNuxt, nuxtCtx } from '../nuxt'
|
||||
import type { Nuxt } from '../types/nuxt'
|
||||
import type { NuxtModule, LegacyNuxtModule, ModuleOptions } from '../types/module'
|
||||
|
||||
export function defineNuxtModule<OptionsT extends ModuleOptions> (input: NuxtModule<OptionsT> | ((nuxt: Nuxt) => NuxtModule<OptionsT>)): LegacyNuxtModule {
|
||||
let mod: NuxtModule<OptionsT>
|
||||
|
||||
function wrappedModule (inlineOptions: OptionsT) {
|
||||
// Get nuxt context
|
||||
const nuxt: Nuxt = this.nuxt || useNuxt()
|
||||
|
||||
// Resolve function
|
||||
if (typeof input === 'function') {
|
||||
const fn = input
|
||||
mod = nuxtCtx.call(nuxt, () => fn(nuxt))
|
||||
} else {
|
||||
mod = input
|
||||
}
|
||||
|
||||
// Install hooks
|
||||
if (mod.hooks) {
|
||||
nuxt.hooks.addHooks(mod.hooks)
|
||||
}
|
||||
|
||||
// Stop if no install provided
|
||||
if (typeof mod.setup !== 'function') {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve options
|
||||
const configKey = mod.configKey || mod.name
|
||||
const userOptions = defu(inlineOptions, nuxt.options[configKey]) as OptionsT
|
||||
const resolvedOptions = applyDefaults(mod.defaults as any, userOptions) as OptionsT
|
||||
|
||||
// Call setup
|
||||
return nuxtCtx.call(nuxt, () => mod.setup.call(null, resolvedOptions, nuxt))
|
||||
}
|
||||
|
||||
wrappedModule.meta = mod
|
||||
|
||||
return wrappedModule
|
||||
}
|
60
packages/kit/src/module/install.ts
Normal file
60
packages/kit/src/module/install.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import type { Nuxt } from '../types/nuxt'
|
||||
import type { LegacyNuxtModule, NuxtModule, ModuleMeta, ModuleInstallOptions, ModuleOptions, ModuleSrc } from '../types/module'
|
||||
import { requireModule } from '../utils/cjs'
|
||||
import { nuxtCtx } from '../nuxt'
|
||||
import { defineNuxtModule } from './define'
|
||||
import { ModuleContainer } from './container'
|
||||
|
||||
export async function installModule (nuxt: Nuxt, installOpts: ModuleInstallOptions) {
|
||||
let src: ModuleSrc
|
||||
let options: ModuleOptions = {}
|
||||
const meta: ModuleMeta = {}
|
||||
|
||||
// Extract src, meta and options
|
||||
if (typeof installOpts === 'string') {
|
||||
src = installOpts
|
||||
} else if (Array.isArray(installOpts)) {
|
||||
[src, options] = installOpts
|
||||
} else if (typeof installOpts === 'object') {
|
||||
if (installOpts.src || installOpts.handler) {
|
||||
src = installOpts.src || installOpts.handler
|
||||
options = installOpts.options
|
||||
Object.assign(meta, installOpts.meta)
|
||||
} else {
|
||||
src = installOpts as NuxtModule
|
||||
}
|
||||
} else {
|
||||
src = installOpts
|
||||
}
|
||||
|
||||
// Resolve as legacy handler
|
||||
let handler: LegacyNuxtModule
|
||||
if (typeof src === 'string') {
|
||||
handler = requireModule(src)
|
||||
if (!meta.name) {
|
||||
meta.name = src
|
||||
}
|
||||
} else if (typeof src === 'function') {
|
||||
handler = src
|
||||
} else {
|
||||
handler = defineNuxtModule(src)
|
||||
}
|
||||
|
||||
// Merge meta
|
||||
if (handler.meta) {
|
||||
Object.assign(meta, handler.meta)
|
||||
}
|
||||
|
||||
// Ensure module is required once
|
||||
if (typeof meta.name === 'string') {
|
||||
nuxt.options._requiredModules = nuxt.options._requiredModules || {}
|
||||
if (nuxt.options._requiredModules[meta.name]) {
|
||||
return
|
||||
}
|
||||
nuxt.options._requiredModules[meta.name] = true
|
||||
}
|
||||
|
||||
// Execute in legacy container
|
||||
const container = new ModuleContainer(nuxt)
|
||||
await nuxtCtx.call(nuxt, () => handler.call(container, options))
|
||||
}
|
100
packages/kit/src/module/utils.ts
Normal file
100
packages/kit/src/module/utils.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import path, { basename, parse } from 'path'
|
||||
import fs from 'fs'
|
||||
import hash from 'hash-sum'
|
||||
import consola from 'consola'
|
||||
import { useNuxt } from '../nuxt'
|
||||
import { chainFn } from '../utils/task'
|
||||
import type { TemplateOpts, PluginTemplateOpts } from '../types/module'
|
||||
|
||||
export function addTemplate (tmpl: TemplateOpts | string) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
if (!tmpl) {
|
||||
throw new Error('Invalid tmpl: ' + JSON.stringify(tmpl))
|
||||
}
|
||||
|
||||
// Validate & parse source
|
||||
const src = typeof tmpl === 'string' ? tmpl : tmpl.src
|
||||
const srcPath = parse(src)
|
||||
|
||||
if (typeof src !== 'string' || !fs.existsSync(src)) {
|
||||
throw new Error('tmpl src not found: ' + src)
|
||||
}
|
||||
|
||||
// Mostly for DX, some people prefers `filename` vs `fileName`
|
||||
const fileName = typeof tmpl === 'string' ? '' : tmpl.fileName || tmpl.filename
|
||||
// Generate unique and human readable dst filename if not provided
|
||||
const dst = fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(src)}${srcPath.ext}`
|
||||
// Add to tmpls list
|
||||
const tmplObj = {
|
||||
src,
|
||||
dst,
|
||||
options: typeof tmpl === 'string' ? undefined : tmpl.options
|
||||
}
|
||||
|
||||
nuxt.options.build.templates.push(tmplObj)
|
||||
|
||||
return tmplObj
|
||||
}
|
||||
|
||||
export function addPlugin (tmpl: PluginTemplateOpts) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
const { dst } = addTemplate(tmpl)
|
||||
|
||||
if (!tmpl.mode && typeof tmpl.ssr === 'boolean') {
|
||||
tmpl.mode = tmpl.ssr ? 'server' : 'client'
|
||||
}
|
||||
|
||||
// Add to nuxt plugins
|
||||
nuxt.options.plugins.unshift({
|
||||
src: path.join(nuxt.options.buildDir, dst),
|
||||
mode: tmpl.mode
|
||||
})
|
||||
}
|
||||
|
||||
export function addLayout (tmpl: TemplateOpts, name: string) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
const { dst, src } = addTemplate(tmpl)
|
||||
const layoutName = name || path.parse(src).name
|
||||
const layout = nuxt.options.layouts[layoutName]
|
||||
|
||||
if (layout) {
|
||||
consola.warn(`Duplicate layout registration, "${layoutName}" has been registered as "${layout}"`)
|
||||
}
|
||||
|
||||
// Add to nuxt layouts
|
||||
nuxt.options.layouts[layoutName] = `./${dst}`
|
||||
|
||||
// If error layout, set ErrorPage
|
||||
if (name === 'error') {
|
||||
addErrorLayout(dst)
|
||||
}
|
||||
}
|
||||
|
||||
export function addErrorLayout (dst: string) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
const relativeBuildDir = path.relative(nuxt.options.rootDir, nuxt.options.buildDir)
|
||||
nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
|
||||
}
|
||||
|
||||
export function addServerMiddleware (middleware) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
nuxt.options.serverMiddleware.push(middleware)
|
||||
}
|
||||
|
||||
export function extendBuild (fn) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
// @ts-ignore TODO
|
||||
nuxt.options.build.extend = chainFn(nuxt.options.build.extend, fn)
|
||||
}
|
||||
|
||||
export function extendRoutes (fn) {
|
||||
const nuxt = useNuxt()
|
||||
|
||||
nuxt.options.router.extendRoutes = chainFn(nuxt.options.router.extendRoutes, fn)
|
||||
}
|
10
packages/kit/src/nuxt.ts
Normal file
10
packages/kit/src/nuxt.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { getContext } from 'unctx'
|
||||
import type { Nuxt } from './types/nuxt'
|
||||
import type { NuxtConfig } from './types/config'
|
||||
|
||||
export const nuxtCtx = getContext<Nuxt>('nuxt')
|
||||
export const useNuxt = nuxtCtx.use
|
||||
|
||||
export function defineNuxtConfig (config: NuxtConfig) {
|
||||
return config
|
||||
}
|
15
packages/kit/src/types/config.ts
Normal file
15
packages/kit/src/types/config.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { ConfigSchema } from '../../.gen/config'
|
||||
import { ModuleInstallOptions } from './module'
|
||||
import { NuxtHooks } from './hooks'
|
||||
|
||||
export interface TypedConfigSchema extends ConfigSchema {
|
||||
hooks: NuxtHooks,
|
||||
modules: ModuleInstallOptions[]
|
||||
buildModules: ModuleInstallOptions[]
|
||||
}
|
||||
|
||||
export interface NuxtOptions extends TypedConfigSchema { }
|
||||
|
||||
type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]> | T[P] }
|
||||
|
||||
export interface NuxtConfig extends DeepPartial<TypedConfigSchema> { }
|
13
packages/kit/src/types/hooks.ts
Normal file
13
packages/kit/src/types/hooks.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Nuxt } from './nuxt'
|
||||
|
||||
export type NuxtHook<Arg1 = any> = (arg1: Arg1, ...args: any) => Promise<void> | void
|
||||
|
||||
export interface NuxtHooks {
|
||||
[key: string]: NuxtHook
|
||||
|
||||
'modules:before': NuxtHook<Nuxt>
|
||||
'modules:done': NuxtHook<Nuxt>
|
||||
'ready': NuxtHook<Nuxt>
|
||||
}
|
||||
|
||||
export type NuxtHookName = keyof NuxtHooks
|
51
packages/kit/src/types/module.ts
Normal file
51
packages/kit/src/types/module.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { ModuleContainer } from '../module/container'
|
||||
import { Nuxt } from './nuxt'
|
||||
import { NuxtHooks } from './hooks'
|
||||
|
||||
export interface ModuleMeta {
|
||||
name?: string
|
||||
configKey?: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export type ModuleOptions = Record<string, any>
|
||||
|
||||
export interface LegacyNuxtModule {
|
||||
(this: ModuleContainer, inlineOptions?: ModuleOptions): void | Promise<void>
|
||||
meta?: ModuleMeta
|
||||
}
|
||||
|
||||
export interface NuxtModule<T extends ModuleOptions = any> extends ModuleMeta {
|
||||
defaults?: T
|
||||
setup?: (this: null, resolvedOptions: T, nuxt: Nuxt) => void | Promise<void>
|
||||
hooks?: Partial<NuxtHooks>
|
||||
}
|
||||
|
||||
export type ModuleSrc = string | NuxtModule | LegacyNuxtModule
|
||||
|
||||
export interface ModuleInstallOptionsObj {
|
||||
src: ModuleSrc,
|
||||
meta: ModuleMeta
|
||||
options: ModuleOptions
|
||||
handler: LegacyNuxtModule
|
||||
}
|
||||
|
||||
export type ModuleInstallOptions =
|
||||
ModuleSrc |
|
||||
[ModuleSrc, ModuleOptions?] |
|
||||
Partial<ModuleInstallOptionsObj>
|
||||
|
||||
// -- Templates --
|
||||
|
||||
export interface TemplateOpts {
|
||||
filename?: string
|
||||
fileName?: string
|
||||
options?: Record<string, any>
|
||||
src: string
|
||||
}
|
||||
|
||||
export interface PluginTemplateOpts extends TemplateOpts {
|
||||
/** @deprecated use mode */
|
||||
ssr?: boolean
|
||||
mode?: 'all' | 'server' | 'client'
|
||||
}
|
16
packages/kit/src/types/nuxt.ts
Normal file
16
packages/kit/src/types/nuxt.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NuxtHookName, NuxtHook, NuxtHooks } from './hooks'
|
||||
import { NuxtOptions } from './config'
|
||||
|
||||
export interface Nuxt {
|
||||
options: NuxtOptions
|
||||
|
||||
hooks: {
|
||||
hook(hookName: NuxtHookName, callback: NuxtHook)
|
||||
callHook<T extends string>(hookbname: T, ...args: Parameters<NuxtHooks[T]>)
|
||||
addHooks(hooks: Partial<NuxtHooks>)
|
||||
}
|
||||
hook: Nuxt['hooks']['hook']
|
||||
callHook: Nuxt['hooks']['callHook']
|
||||
|
||||
server?: any
|
||||
}
|
@ -1,18 +1,33 @@
|
||||
import { join } from 'path'
|
||||
import jiti from 'jiti'
|
||||
|
||||
export function isExternalDependency (id: string) {
|
||||
// TODO: use create-require for jest environment
|
||||
const _require = jiti(process.cwd())
|
||||
|
||||
export interface ResolveModuleOptions {
|
||||
paths?: string[]
|
||||
}
|
||||
|
||||
export interface RequireModuleOptions extends ResolveModuleOptions {
|
||||
native?: boolean
|
||||
clearCache?: boolean
|
||||
interopDefault?: boolean
|
||||
}
|
||||
|
||||
export function isNodeModules (id: string) {
|
||||
// TODO: Follow symlinks
|
||||
return /[/\\]node_modules[/\\]/.test(id)
|
||||
}
|
||||
|
||||
export function clearRequireCache (id: string) {
|
||||
if (isExternalDependency(id)) {
|
||||
if (isNodeModules(id)) {
|
||||
return
|
||||
}
|
||||
|
||||
const entry = getRequireCacheItem(id)
|
||||
|
||||
if (!entry) {
|
||||
delete require.cache[id]
|
||||
delete _require.cache[id]
|
||||
return
|
||||
}
|
||||
|
||||
@ -24,11 +39,11 @@ export function clearRequireCache (id: string) {
|
||||
clearRequireCache(child.id)
|
||||
}
|
||||
|
||||
delete require.cache[id]
|
||||
delete _require.cache[id]
|
||||
}
|
||||
|
||||
export function scanRequireTree (id: string, files = new Set<string>()) {
|
||||
if (isExternalDependency(id) || files.has(id)) {
|
||||
if (isNodeModules(id) || files.has(id)) {
|
||||
return files
|
||||
}
|
||||
|
||||
@ -50,18 +65,54 @@ export function scanRequireTree (id: string, files = new Set<string>()) {
|
||||
|
||||
export function getRequireCacheItem (id: string) {
|
||||
try {
|
||||
return require.cache[id]
|
||||
return _require.cache[id]
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
export function tryRequire (id: string) {
|
||||
export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) {
|
||||
return requireModule(join(id, 'package.json'), opts)
|
||||
}
|
||||
|
||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||
return _require.resolve(id, {
|
||||
paths: opts.paths
|
||||
})
|
||||
}
|
||||
|
||||
export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}) {
|
||||
try {
|
||||
return require(id)
|
||||
} catch (e) {
|
||||
return resolveModule(path, opts)
|
||||
} catch (error) {
|
||||
if (error.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getPKG (id: string) {
|
||||
return tryRequire(join(id, 'package.json'))
|
||||
export function requireModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
// Resolve id
|
||||
const resolvedPath = resolveModule(id, opts)
|
||||
|
||||
// Clear require cache if necessary
|
||||
if (opts.clearCache && !isNodeModules(id)) {
|
||||
clearRequireCache(resolvedPath)
|
||||
}
|
||||
|
||||
// Try to require
|
||||
let requiredModule = _require(resolvedPath)
|
||||
|
||||
// Interop default
|
||||
if (opts.interopDefault !== false && requiredModule && requiredModule.default) {
|
||||
requiredModule = requiredModule.default
|
||||
}
|
||||
|
||||
return requiredModule
|
||||
}
|
||||
|
||||
export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
try {
|
||||
return requireModule(id, opts)
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
export const TARGETS = {
|
||||
server: 'server',
|
||||
static: 'static'
|
||||
} as const
|
||||
|
||||
export type Target = keyof typeof TARGETS
|
||||
|
||||
export const MODES = {
|
||||
universal: 'universal',
|
||||
spa: 'spa'
|
||||
} as const
|
||||
|
||||
export type Mode = keyof typeof MODES
|
@ -1,36 +0,0 @@
|
||||
import type { ServerResponse, IncomingMessage } from 'http'
|
||||
|
||||
import { TARGETS } from './constants'
|
||||
|
||||
export const getContext = function getContext (req: IncomingMessage, res: ServerResponse) {
|
||||
return { req, res }
|
||||
}
|
||||
|
||||
type NuxtGlobal = string | ((globalName: string) => string)
|
||||
|
||||
type Globals = 'id' | 'nuxt' | 'context' | 'pluginPrefix' | 'readyCallback' | 'loadedCallback'
|
||||
|
||||
type NuxtGlobals = {
|
||||
[key in Globals]: NuxtGlobal
|
||||
}
|
||||
|
||||
export type DeterminedGlobals = {
|
||||
[key in keyof NuxtGlobals]: string
|
||||
}
|
||||
|
||||
export const determineGlobals = function determineGlobals (globalName: string, globals: NuxtGlobals) {
|
||||
const _globals: Partial<DeterminedGlobals> = {}
|
||||
for (const global in globals) {
|
||||
const currentGlobal = globals[global]
|
||||
if (currentGlobal instanceof Function) {
|
||||
_globals[global] = currentGlobal(globalName)
|
||||
} else {
|
||||
_globals[global] = currentGlobal
|
||||
}
|
||||
}
|
||||
return _globals as DeterminedGlobals
|
||||
}
|
||||
|
||||
export const isFullStatic = function (options) {
|
||||
return !options.dev && !options._legacyGenerate && options.target === TARGETS.static && options.render.ssr
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
export * from './context'
|
||||
export * from './lang'
|
||||
export * from './resolve'
|
||||
export * from './route'
|
||||
export * from './task'
|
||||
export * from './cjs'
|
||||
export * from './constants'
|
@ -1,47 +0,0 @@
|
||||
export const encodeHtml = function encodeHtml (str: string) {
|
||||
return str.replace(/</g, '<').replace(/>/g, '>')
|
||||
}
|
||||
|
||||
export const isString = (obj: unknown): obj is string =>
|
||||
typeof obj === 'string' || obj instanceof String
|
||||
|
||||
export const isNonEmptyString = (obj: unknown): obj is string =>
|
||||
Boolean(obj && isString(obj))
|
||||
|
||||
export const isPureObject = (
|
||||
obj: unknown
|
||||
): obj is Exclude<object, Array<any>> =>
|
||||
!Array.isArray(obj) && typeof obj === 'object'
|
||||
|
||||
export const isUrl = function isUrl (url: string) {
|
||||
return ['http', '//'].some(str => url.startsWith(str))
|
||||
}
|
||||
|
||||
export const urlJoin = function urlJoin (...args: string[]) {
|
||||
return [].slice
|
||||
.call(args)
|
||||
.join('/')
|
||||
.replace(/\/+/g, '/')
|
||||
.replace(':/', '://')
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps value in array if it is not already an array
|
||||
*/
|
||||
export const wrapArray = <T>(value: T | T[]): T[] =>
|
||||
Array.isArray(value) ? value : [value]
|
||||
|
||||
const WHITESPACE_REPLACEMENTS: [RegExp, string][] = [
|
||||
[/[ \t\f\r]+\n/g, '\n'], // strip empty indents
|
||||
[/{\n{2,}/g, '{\n'], // strip start padding from blocks
|
||||
[/\n{2,}([ \t\f\r]*})/g, '\n$1'], // strip end padding from blocks
|
||||
[/\n{3,}/g, '\n\n'], // strip multiple blank lines (1 allowed)
|
||||
[/\n{2,}$/g, '\n'] // strip blank lines EOF (0 allowed)
|
||||
]
|
||||
|
||||
export const stripWhitespace = function stripWhitespace (string: string) {
|
||||
WHITESPACE_REPLACEMENTS.forEach(([regex, newSubstr]) => {
|
||||
string = string.replace(regex, newSubstr)
|
||||
})
|
||||
return string
|
||||
}
|
@ -1,123 +1,72 @@
|
||||
import path from 'path'
|
||||
import consola from 'consola'
|
||||
import escapeRegExp from 'lodash/escapeRegExp'
|
||||
import { existsSync, lstatSync } from 'fs'
|
||||
import { resolve, join } from 'upath'
|
||||
|
||||
export const startsWithAlias = (aliasArray: string[]) => (str: string) =>
|
||||
aliasArray.some(c => str.startsWith(c))
|
||||
|
||||
export const startsWithSrcAlias = startsWithAlias(['@', '~'])
|
||||
|
||||
export const startsWithRootAlias = startsWithAlias(['@@', '~~'])
|
||||
|
||||
export const isWindows = process.platform.startsWith('win')
|
||||
|
||||
export const wp = function wp (p = '') {
|
||||
if (isWindows) {
|
||||
return p.replace(/\\/g, '\\\\')
|
||||
}
|
||||
return p
|
||||
export interface ResolveOptions {
|
||||
base?: string
|
||||
alias?: Record<string, string>
|
||||
extensions?: string[]
|
||||
}
|
||||
|
||||
// Kept for backward compat (modules may use it from template context)
|
||||
export const wChunk = function wChunk (p = '') {
|
||||
return p
|
||||
}
|
||||
|
||||
const reqSep = /\//g
|
||||
const sysSep = escapeRegExp(path.sep)
|
||||
const normalize = (string: string) => string.replace(reqSep, sysSep)
|
||||
|
||||
export const r = function r (...args: string[]) {
|
||||
const lastArg = args[args.length - 1]
|
||||
|
||||
if (startsWithSrcAlias(lastArg)) {
|
||||
return wp(lastArg)
|
||||
function resolvePath (path: string, opts: ResolveOptions = {}) {
|
||||
// Fast return in case of path exists
|
||||
if (existsSync(path)) {
|
||||
return path
|
||||
}
|
||||
|
||||
return wp(path.resolve(...args.map(normalize)))
|
||||
}
|
||||
let resolvedPath: string
|
||||
|
||||
export const relativeTo = function relativeTo (dir: string, ...args: string[]): string {
|
||||
// Keep webpack inline loader intact
|
||||
if (args[0].includes('!')) {
|
||||
const loaders = args.shift()!.split('!')
|
||||
|
||||
return loaders.concat(relativeTo(dir, loaders.pop()!, ...args)).join('!')
|
||||
// Resolve alias
|
||||
if (opts.alias) {
|
||||
resolvedPath = resolveAlias(path, opts.alias)
|
||||
}
|
||||
|
||||
// Resolve path
|
||||
const resolvedPath = r(...args)
|
||||
// Resolve relative to base or cwd
|
||||
resolvedPath = resolve(opts.base || '.', resolvedPath)
|
||||
|
||||
// Check if path is an alias
|
||||
if (startsWithSrcAlias(resolvedPath)) {
|
||||
// Check if resolvedPath is a file
|
||||
let isDirectory = false
|
||||
if (existsSync(resolvedPath)) {
|
||||
isDirectory = lstatSync(resolvedPath).isDirectory()
|
||||
if (!isDirectory) {
|
||||
return resolvedPath
|
||||
}
|
||||
}
|
||||
|
||||
// Check possible extensions
|
||||
for (const ext of opts.extensions) {
|
||||
// resolvedPath.[ext]
|
||||
const resolvedPathwithExt = resolvedPath + ext
|
||||
if (!isDirectory && existsSync(resolvedPathwithExt)) {
|
||||
return resolvedPathwithExt
|
||||
}
|
||||
// resolvedPath/index.[ext]
|
||||
const resolvedPathwithIndex = join(resolvedPath, 'index' + ext)
|
||||
if (isDirectory && existsSync(resolvedPathwithIndex)) {
|
||||
return resolvedPathwithIndex
|
||||
}
|
||||
}
|
||||
|
||||
// If extension check fails and resolvedPath is a valid directory, return it
|
||||
if (isDirectory) {
|
||||
return resolvedPath
|
||||
}
|
||||
|
||||
// Make correct relative path
|
||||
let rp = path.relative(dir, resolvedPath)
|
||||
if (rp[0] !== '.') {
|
||||
rp = '.' + path.sep + rp
|
||||
}
|
||||
|
||||
return wp(rp)
|
||||
// Give up if it is neither a directory
|
||||
throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`)
|
||||
}
|
||||
|
||||
interface AliasOptions {
|
||||
bind?: boolean
|
||||
warn?: boolean
|
||||
}
|
||||
|
||||
export function defineAlias <O extends Record<string, any>> (
|
||||
src: O,
|
||||
target: Record<string, any>,
|
||||
prop: string | string[],
|
||||
opts: AliasOptions = {}
|
||||
) {
|
||||
const { bind = true, warn = false } = opts
|
||||
|
||||
if (Array.isArray(prop)) {
|
||||
for (const p of prop) {
|
||||
defineAlias(src, target, p, opts)
|
||||
export function resolveAlias (path: string, alias: ResolveOptions['alias']) {
|
||||
for (const key in alias) {
|
||||
if (path.startsWith(key)) {
|
||||
path = alias[key] + path.substr(key.length)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let targetVal = target[prop]
|
||||
if (bind && typeof targetVal === 'function') {
|
||||
targetVal = targetVal.bind(target)
|
||||
}
|
||||
|
||||
let warned = false
|
||||
|
||||
Object.defineProperty(src, prop, {
|
||||
get: () => {
|
||||
if (warn && !warned) {
|
||||
warned = true
|
||||
consola.warn({
|
||||
message: `'${prop}' is deprecated'`,
|
||||
// eslint-disable-next-line unicorn/error-message
|
||||
additional: new Error().stack.split('\n').splice(2).join('\n')
|
||||
})
|
||||
}
|
||||
return targetVal
|
||||
}
|
||||
})
|
||||
return path
|
||||
}
|
||||
|
||||
const isIndex = (s: string) => /(.*)\/index\.[^/]+$/.test(s)
|
||||
|
||||
export function isIndexFileAndFolder (pluginFiles: string[]) {
|
||||
// Return early in case the matching file count exceeds 2 (index.js + folder)
|
||||
if (pluginFiles.length !== 2) {
|
||||
return false
|
||||
export function tryResolvePath (path: string, opts: ResolveOptions = {}) {
|
||||
try {
|
||||
return resolvePath(path, opts)
|
||||
} catch (e) {
|
||||
}
|
||||
return pluginFiles.some(isIndex)
|
||||
}
|
||||
|
||||
export const getMainModule = () => {
|
||||
return (
|
||||
require.main ||
|
||||
(module && ((module as any).main as NodeJS.Module)) ||
|
||||
module
|
||||
)
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
import path from 'path'
|
||||
import get from 'lodash/get'
|
||||
import consola from 'consola'
|
||||
|
||||
// Guard dir1 from dir2 which can be indiscriminately removed
|
||||
export const guardDir = function guardDir (options: Record<string, any>, key1: string, key2: string) {
|
||||
const dir1 = get(options, key1, false) as string
|
||||
const dir2 = get(options, key2, false) as string
|
||||
|
||||
if (
|
||||
dir1 &&
|
||||
dir2 &&
|
||||
(
|
||||
dir1 === dir2 ||
|
||||
(
|
||||
dir1.startsWith(dir2) &&
|
||||
!path.basename(dir1).startsWith(path.basename(dir2))
|
||||
)
|
||||
)
|
||||
) {
|
||||
const errorMessage = `options.${key2} cannot be a parent of or same as ${key1}`
|
||||
consola.fatal(errorMessage)
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export const sequence = function sequence<T, R> (
|
||||
export function sequence<T, R> (
|
||||
tasks: T[],
|
||||
fn: (task: T) => R
|
||||
) {
|
||||
@ -8,14 +8,14 @@ export const sequence = function sequence<T, R> (
|
||||
)
|
||||
}
|
||||
|
||||
export const parallel = function parallel<T, R> (
|
||||
export function parallel<T, R> (
|
||||
tasks: T[],
|
||||
fn: (task: T) => R
|
||||
) {
|
||||
return Promise.all(tasks.map(fn))
|
||||
}
|
||||
|
||||
export const chainFn = function chainFn (base, fn) {
|
||||
export function chainFn (base, fn) {
|
||||
if (typeof fn !== 'function') {
|
||||
return base
|
||||
}
|
||||
|
@ -9,13 +9,19 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "jiti ../../scripts/build .",
|
||||
"stub": "yarn build --stub",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"build": {
|
||||
"externals": [
|
||||
"@nuxt/kit"
|
||||
],
|
||||
"entries": {
|
||||
"index": { "format": "cjs" },
|
||||
"compat": { "format": "cjs" },
|
||||
"index": {
|
||||
"format": "cjs"
|
||||
},
|
||||
"compat": {
|
||||
"format": "cjs"
|
||||
},
|
||||
"runtime/": {}
|
||||
},
|
||||
"dependencies": [
|
||||
@ -77,6 +83,7 @@
|
||||
"serve-static": "^1.14.1",
|
||||
"std-env": "^2.3.0",
|
||||
"table": "^6.0.7",
|
||||
"ufo": "^0.6.10",
|
||||
"upath": "^2.0.1",
|
||||
"vue-bundle-renderer": "^0.2.3",
|
||||
"vue-server-renderer": "^2.6.12"
|
||||
|
@ -57,8 +57,7 @@ export default function nuxt2CompatModule () {
|
||||
|
||||
// Resolve middleware
|
||||
nuxt.hook('modules:done', () => {
|
||||
const { middleware, legacyMiddleware } =
|
||||
resolveMiddleware(nuxt.options.serverMiddleware, nuxt.resolver.resolvePath)
|
||||
const { middleware, legacyMiddleware } = resolveMiddleware(nuxt.options.serverMiddleware)
|
||||
if (nuxt.server) {
|
||||
nuxt.server.setLegacyMiddleware(legacyMiddleware)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { resolve } from 'upath'
|
||||
import { resolve, dirname } from 'upath'
|
||||
import defu from 'defu'
|
||||
import type { NuxtOptions } from '@nuxt/types'
|
||||
import type { NuxtOptions } from '@nuxt/kit'
|
||||
import Hookable, { configHooksT } from 'hookable'
|
||||
import type { Preset } from '@nuxt/un'
|
||||
import { tryImport, resolvePath, detectTarget, extendPreset } from './utils'
|
||||
@ -106,7 +106,7 @@ export function getNitroContext (nuxtOptions: NuxtOptions, input: NitroInput): N
|
||||
}
|
||||
},
|
||||
_internal: {
|
||||
runtimeDir: resolve(__dirname, './runtime'),
|
||||
runtimeDir: resolve(dirname(require.resolve('@nuxt/nitro')), 'runtime'),
|
||||
hooks: new Hookable()
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,11 @@ export function externals (opts: NodeExternalsOptions): Plugin {
|
||||
return null
|
||||
}
|
||||
|
||||
// Bundle ts
|
||||
if (id.endsWith('.ts')) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const dir of opts.moduleDirectories) {
|
||||
if (id.startsWith(dir)) {
|
||||
id = id.substr(dir.length + 1)
|
||||
|
@ -2,6 +2,7 @@ import { resolve, join, extname } from 'upath'
|
||||
import { joinURL } from 'ufo'
|
||||
import globby from 'globby'
|
||||
import { watch } from 'chokidar'
|
||||
import { tryResolvePath } from '@nuxt/kit'
|
||||
|
||||
export interface ServerMiddleware {
|
||||
route: string
|
||||
@ -50,7 +51,7 @@ export function scanMiddleware (serverDir: string, onChange?: (results: ServerMi
|
||||
return scan()
|
||||
}
|
||||
|
||||
export function resolveMiddleware (serverMiddleware: any[], resolvePath: (string) => string) {
|
||||
export function resolveMiddleware (serverMiddleware: any[]) {
|
||||
const middleware: ServerMiddleware[] = []
|
||||
const legacyMiddleware: ServerMiddleware[] = []
|
||||
|
||||
@ -65,7 +66,9 @@ export function resolveMiddleware (serverMiddleware: any[], resolvePath: (string
|
||||
delete m.path
|
||||
middleware.push({
|
||||
...m,
|
||||
handle: resolvePath(handle),
|
||||
handle: tryResolvePath(handle, {
|
||||
extensions: ['.ts', '.js']
|
||||
}),
|
||||
route
|
||||
})
|
||||
}
|
||||
|
@ -13,10 +13,12 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "jiti ../../scripts/build .",
|
||||
"stub": "yarn build --stub",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"build": {
|
||||
"externals": [
|
||||
"nuxt3"
|
||||
],
|
||||
"entries": {
|
||||
"index": { "format": "cjs" }
|
||||
}
|
||||
|
@ -15,7 +15,10 @@ async function _main () {
|
||||
|
||||
const { loadNuxt, build } = await import('nuxt3')
|
||||
|
||||
const nuxt = await loadNuxt({ for: isDev ? 'dev' : 'build', rootDir })
|
||||
const nuxt = await loadNuxt({
|
||||
for: isDev ? 'dev' : 'build',
|
||||
rootDir
|
||||
})
|
||||
|
||||
if (isDev) {
|
||||
// https://github.com/nuxt-contrib/listhen
|
||||
|
@ -9,7 +9,6 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "jiti ../../scripts/build .",
|
||||
"stub": "yarn build --stub",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"build": {
|
||||
@ -17,6 +16,7 @@
|
||||
"index": { "format": "cjs" }
|
||||
},
|
||||
"dependencies": [
|
||||
"@nuxt/app",
|
||||
"@vue/compiler-sfc",
|
||||
"postcss",
|
||||
"postcss-loader",
|
||||
@ -38,6 +38,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "0.0.0",
|
||||
"@nuxt/app": "0.0.0",
|
||||
"@nuxt/friendly-errors-webpack-plugin": "^2.5.0",
|
||||
"@nuxt/nitro": "^0.1.11",
|
||||
@ -50,12 +51,9 @@
|
||||
"chokidar": "^3.5.1",
|
||||
"consola": "^2.15.3",
|
||||
"core-js": "^3.9.1",
|
||||
"create-require": "^1.1.1",
|
||||
"css-loader": "^5.2.0",
|
||||
"css-minimizer-webpack-plugin": "^1.3.0",
|
||||
"defu": "^3.2.2",
|
||||
"destr": "^1.1.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"esbuild-loader": "^2.11.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
@ -64,7 +62,6 @@
|
||||
"hash-sum": "^2.0.0",
|
||||
"hookable": "^4.4.1",
|
||||
"ignore": "^5.1.8",
|
||||
"jiti": "^1.6.4",
|
||||
"lodash": "^4.17.21",
|
||||
"memfs": "^3.2.0",
|
||||
"mini-css-extract-plugin": "^1.4.0",
|
||||
@ -72,9 +69,7 @@
|
||||
"postcss": "^8.2.8",
|
||||
"postcss-import-resolver": "^2.0.0",
|
||||
"postcss-loader": "^5.2.0",
|
||||
"rc9": "^1.2.0",
|
||||
"scule": "^0.1.1",
|
||||
"std-env": "3.0.0-alpha",
|
||||
"style-resources-loader": "^1.4.1",
|
||||
"time-fix-plugin": "^2.0.7",
|
||||
"ufo": "^0.6.10",
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { resolve } from 'path'
|
||||
import defu from 'defu'
|
||||
import { tryResolvePath } from '@nuxt/kit'
|
||||
import { Builder } from './builder'
|
||||
import { NuxtRoute, resolvePagesRoutes } from './pages'
|
||||
import { NuxtPlugin, resolvePlugins } from './plugins'
|
||||
|
||||
export interface NuxtApp {
|
||||
main?: string
|
||||
routes: NuxtRoute[]
|
||||
@ -35,10 +37,15 @@ export async function createApp (
|
||||
})
|
||||
|
||||
// Resolve app.main
|
||||
const resolveOptions = {
|
||||
base: nuxt.options.srcDir,
|
||||
alias: nuxt.options.alias,
|
||||
extensions: nuxt.options.extensions
|
||||
}
|
||||
|
||||
if (!app.main) {
|
||||
app.main =
|
||||
nuxt.resolver.tryResolvePath('~/App') ||
|
||||
nuxt.resolver.tryResolvePath('~/app')
|
||||
app.main = tryResolvePath('~/App', resolveOptions) ||
|
||||
tryResolvePath('~/app', resolveOptions)
|
||||
}
|
||||
|
||||
// Resolve pages/
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { join, relative } from 'path'
|
||||
import fsExtra from 'fs-extra'
|
||||
import { debounce } from 'lodash'
|
||||
import { DeterminedGlobals, determineGlobals } from '@nuxt/kit'
|
||||
import { Nuxt } from './nuxt'
|
||||
import { Nuxt } from '@nuxt/kit'
|
||||
|
||||
import {
|
||||
templateData,
|
||||
compileTemplates,
|
||||
@ -15,14 +15,13 @@ import Ignore from './utils/ignore'
|
||||
|
||||
export class Builder {
|
||||
nuxt: Nuxt
|
||||
globals: DeterminedGlobals
|
||||
globals: any
|
||||
ignore: Ignore
|
||||
templates: NuxtTemplate[]
|
||||
app: NuxtApp
|
||||
|
||||
constructor (nuxt) {
|
||||
this.nuxt = nuxt
|
||||
this.globals = determineGlobals(nuxt.options.globalName, nuxt.options.globals)
|
||||
this.ignore = new Ignore({
|
||||
rootDir: nuxt.options.srcDir,
|
||||
ignoreArray: nuxt.options.ignore.concat(
|
||||
@ -53,7 +52,7 @@ async function _build (builder: Builder) {
|
||||
|
||||
await bundle(builder)
|
||||
|
||||
await nuxt.callHook('build:done')
|
||||
await nuxt.callHook('build:done', builder)
|
||||
}
|
||||
|
||||
function watch (builder: Builder) {
|
||||
|
@ -1,2 +1,2 @@
|
||||
export { Nuxt, loadNuxt } from './nuxt'
|
||||
export { build } from './builder'
|
||||
export * from './nuxt'
|
||||
export * from './builder'
|
||||
|
@ -1,235 +0,0 @@
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import hash from 'hash-sum'
|
||||
import consola from 'consola'
|
||||
import { chainFn, sequence } from '@nuxt/kit'
|
||||
|
||||
import Nuxt from './nuxt'
|
||||
|
||||
interface TemplateInput {
|
||||
filename?: string
|
||||
fileName?: string
|
||||
options?: Record<string, any>
|
||||
src: string
|
||||
ssr?: boolean
|
||||
mode?: 'all' | 'server' | 'client'
|
||||
}
|
||||
|
||||
export default class ModuleContainer {
|
||||
nuxt: Nuxt
|
||||
options: Nuxt['options']
|
||||
requiredModules: Record<string, {
|
||||
src: string
|
||||
options: Record<string, any>
|
||||
handler
|
||||
}>
|
||||
|
||||
constructor (nuxt: Nuxt) {
|
||||
this.nuxt = nuxt
|
||||
this.options = nuxt.options
|
||||
this.requiredModules = {}
|
||||
|
||||
// Self bind to allow destructre from container
|
||||
for (const method of Object.getOwnPropertyNames(ModuleContainer.prototype)) {
|
||||
if (typeof this[method] === 'function') {
|
||||
this[method] = this[method].bind(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async ready () {
|
||||
// Call before hook
|
||||
await this.nuxt.callHook('modules:before', this, this.options.modules)
|
||||
|
||||
if (this.options.buildModules && !this.options._start) {
|
||||
// Load every devModule in sequence
|
||||
await sequence(this.options.buildModules, this.addModule)
|
||||
}
|
||||
|
||||
// Load every module in sequence
|
||||
await sequence(this.options.modules, this.addModule)
|
||||
|
||||
// Load ah-hoc modules last
|
||||
await sequence(this.options._modules, this.addModule)
|
||||
|
||||
// Call done hook
|
||||
await this.nuxt.callHook('modules:done', this)
|
||||
}
|
||||
|
||||
addVendor () {
|
||||
consola.warn('addVendor has been deprecated due to webpack4 optimization')
|
||||
}
|
||||
|
||||
addTemplate (template: TemplateInput | string) {
|
||||
if (!template) {
|
||||
throw new Error('Invalid template: ' + JSON.stringify(template))
|
||||
}
|
||||
|
||||
// Validate & parse source
|
||||
const src = typeof template === 'string' ? template : template.src
|
||||
const srcPath = path.parse(src)
|
||||
|
||||
if (typeof src !== 'string' || !fs.existsSync(src)) {
|
||||
throw new Error('Template src not found: ' + src)
|
||||
}
|
||||
|
||||
// Mostly for DX, some people prefers `filename` vs `fileName`
|
||||
const fileName = typeof template === 'string' ? '' : template.fileName || template.filename
|
||||
// Generate unique and human readable dst filename if not provided
|
||||
const dst = fileName || `${path.basename(srcPath.dir)}.${srcPath.name}.${hash(src)}${srcPath.ext}`
|
||||
// Add to templates list
|
||||
const templateObj = {
|
||||
src,
|
||||
dst,
|
||||
options: typeof template === 'string' ? undefined : template.options
|
||||
}
|
||||
|
||||
this.options.build.templates.push(templateObj)
|
||||
|
||||
return templateObj
|
||||
}
|
||||
|
||||
addPlugin (template: TemplateInput) {
|
||||
const { dst } = this.addTemplate(template)
|
||||
|
||||
// Add to nuxt plugins
|
||||
this.options.plugins.unshift({
|
||||
src: path.join(this.options.buildDir, dst),
|
||||
// TODO: remove deprecated option in Nuxt 3
|
||||
ssr: template.ssr,
|
||||
mode: template.mode
|
||||
})
|
||||
}
|
||||
|
||||
addLayout (template: TemplateInput, name: string) {
|
||||
const { dst, src } = this.addTemplate(template)
|
||||
const layoutName = name || path.parse(src).name
|
||||
const layout = this.options.layouts[layoutName]
|
||||
|
||||
if (layout) {
|
||||
consola.warn(`Duplicate layout registration, "${layoutName}" has been registered as "${layout}"`)
|
||||
}
|
||||
|
||||
// Add to nuxt layouts
|
||||
this.options.layouts[layoutName] = `./${dst}`
|
||||
|
||||
// If error layout, set ErrorPage
|
||||
if (name === 'error') {
|
||||
this.addErrorLayout(dst)
|
||||
}
|
||||
}
|
||||
|
||||
addErrorLayout (dst: string) {
|
||||
const relativeBuildDir = path.relative(this.options.rootDir, this.options.buildDir)
|
||||
this.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
|
||||
}
|
||||
|
||||
addServerMiddleware (middleware) {
|
||||
this.options.serverMiddleware.push(middleware)
|
||||
}
|
||||
|
||||
extendBuild (fn) {
|
||||
this.options.build.extend = chainFn(this.options.build.extend, fn)
|
||||
}
|
||||
|
||||
extendRoutes (fn) {
|
||||
this.options.router.extendRoutes = chainFn(
|
||||
this.options.router.extendRoutes,
|
||||
fn
|
||||
)
|
||||
}
|
||||
|
||||
requireModule (moduleOpts) {
|
||||
return this.addModule(moduleOpts)
|
||||
}
|
||||
|
||||
async addModule (moduleOpts) {
|
||||
let src
|
||||
let options: Record<string, any>
|
||||
let handler
|
||||
|
||||
// Type 1: String or Function
|
||||
if (typeof moduleOpts === 'string' || typeof moduleOpts === 'function') {
|
||||
src = moduleOpts
|
||||
} else if (Array.isArray(moduleOpts)) {
|
||||
// Type 2: Babel style array
|
||||
[src, options] = moduleOpts
|
||||
} else if (typeof moduleOpts === 'object') {
|
||||
// Type 3: Pure object
|
||||
({ src, options, handler } = moduleOpts)
|
||||
}
|
||||
|
||||
// Define handler if src is a function
|
||||
if (src instanceof Function) {
|
||||
handler = src
|
||||
}
|
||||
|
||||
// Prevent adding buildModules-listed entries in production
|
||||
if (this.options.buildModules.includes(handler) && this.options._start) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve handler
|
||||
if (!handler && typeof src === 'string') {
|
||||
try {
|
||||
handler = this.nuxt.resolver.requireModule(src, { useESM: true })
|
||||
} catch (error) {
|
||||
if (error.code !== 'MODULE_NOT_FOUND') {
|
||||
throw error
|
||||
}
|
||||
|
||||
// Hint only if entrypoint is not found and src is not local alias or path
|
||||
if (error.message.includes(src) && !/^[~.]|^@\//.test(src)) {
|
||||
let message = 'Module `{name}` not found.'
|
||||
|
||||
if (this.options.buildModules.includes(src)) {
|
||||
message += ' Please ensure `{name}` is in `devDependencies` and installed. HINT: During build step, for npm/yarn, `NODE_ENV=production` or `--production` should NOT be used.'.replace('{name}', src)
|
||||
} else if (this.options.modules.includes(src)) {
|
||||
message += ' Please ensure `{name}` is in `dependencies` and installed.'
|
||||
}
|
||||
|
||||
message = message.replace(/{name}/g, src)
|
||||
|
||||
consola.warn(message)
|
||||
}
|
||||
|
||||
if (this.options._cli) {
|
||||
throw error
|
||||
} else {
|
||||
// TODO: Remove in next major version
|
||||
consola.warn('Silently ignoring module as programatic usage detected.')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate handler
|
||||
if (typeof handler !== 'function') {
|
||||
throw new TypeError('Module should export a function: ' + src)
|
||||
}
|
||||
|
||||
// Ensure module is required once
|
||||
if ('meta' in handler && typeof src === 'string') {
|
||||
const metaKey = handler.meta && handler.meta.name
|
||||
const key = metaKey || src
|
||||
if (typeof key === 'string') {
|
||||
if (this.requiredModules[key]) {
|
||||
if (!metaKey) {
|
||||
// TODO: Skip with nuxt3
|
||||
consola.warn('Modules should be only specified once:', key)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
this.requiredModules[key] = { src, options, handler }
|
||||
}
|
||||
}
|
||||
|
||||
// Default module options to empty object
|
||||
if (options === undefined) {
|
||||
options = {}
|
||||
}
|
||||
const result = await handler.call(this, options)
|
||||
return result
|
||||
}
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
// eslint-disable-next-line import/named
|
||||
import { wpfs, getNitroContext, createDevServer, resolveMiddleware, build, prepare, generate } from '@nuxt/nitro'
|
||||
import type { Nuxt } from './index'
|
||||
import type { Nuxt } from '@nuxt/kit'
|
||||
|
||||
export function initNitro (nuxt: Nuxt) {
|
||||
// Create contexts
|
||||
const nitroContext = getNitroContext(nuxt.options, nuxt.options.nitro || {})
|
||||
const nitroContext = getNitroContext(nuxt.options, (nuxt.options as any).nitro || {})
|
||||
const nitroDevContext = getNitroContext(nuxt.options, { preset: 'dev' })
|
||||
|
||||
nuxt.server = createDevServer(nitroDevContext)
|
||||
|
||||
// Connect hooks
|
||||
nuxt.addHooks(nitroContext.nuxtHooks)
|
||||
nuxt.hooks.addHooks(nitroContext.nuxtHooks)
|
||||
nuxt.hook('close', () => nitroContext._internal.hooks.callHook('close'))
|
||||
|
||||
nuxt.addHooks(nitroDevContext.nuxtHooks)
|
||||
nuxt.hooks.addHooks(nitroDevContext.nuxtHooks)
|
||||
nuxt.hook('close', () => nitroDevContext._internal.hooks.callHook('close'))
|
||||
|
||||
// Expose process.env.NITRO_PRESET
|
||||
@ -21,8 +20,7 @@ export function initNitro (nuxt: Nuxt) {
|
||||
|
||||
// Resolve middleware
|
||||
nuxt.hook('modules:done', () => {
|
||||
const { middleware, legacyMiddleware } =
|
||||
resolveMiddleware(nuxt.options.serverMiddleware, nuxt.resolver.resolvePath)
|
||||
const { middleware, legacyMiddleware } = resolveMiddleware(nuxt.options.serverMiddleware)
|
||||
nuxt.server.setLegacyMiddleware(legacyMiddleware)
|
||||
nitroContext.middleware.push(...middleware)
|
||||
nitroDevContext.middleware.push(...middleware)
|
||||
@ -39,7 +37,7 @@ export function initNitro (nuxt: Nuxt) {
|
||||
}
|
||||
})
|
||||
|
||||
// nude dev
|
||||
// nuxt dev
|
||||
if (nuxt.options.dev) {
|
||||
nitroDevContext._internal.hooks.hook('nitro:compiled', () => { nuxt.server.watch() })
|
||||
nuxt.hook('build:compile', ({ compiler }) => { compiler.outputFileSystem = wpfs })
|
||||
|
@ -1,107 +1,64 @@
|
||||
import type { IncomingHttpHeaders } from 'http'
|
||||
|
||||
import { dirname } from 'path'
|
||||
import isPlainObject from 'lodash/isPlainObject'
|
||||
import consola from 'consola'
|
||||
import Hookable from 'hookable'
|
||||
import { LoadNuxtOptions, loadNuxtConfig } from '@nuxt/kit'
|
||||
import { version } from '../package.json'
|
||||
|
||||
import ModuleContainer from './module'
|
||||
import Resolver from './resolver'
|
||||
import { loadNuxtConfig, LoadNuxtConfigOptions, Nuxt, NuxtOptions, installModule } from '@nuxt/kit'
|
||||
import { initNitro } from './nitro'
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
__NUXT_DEV__: boolean
|
||||
}
|
||||
export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
const hooks = new Hookable()
|
||||
|
||||
return {
|
||||
options,
|
||||
hooks,
|
||||
callHook: hooks.callHook,
|
||||
hook: hooks.hook
|
||||
}
|
||||
}
|
||||
|
||||
export class Nuxt extends Hookable {
|
||||
_ready?: Promise<this>
|
||||
_initCalled?: boolean
|
||||
async function initNuxt (nuxt: Nuxt) {
|
||||
// Register user hooks
|
||||
nuxt.hooks.addHooks(nuxt.options.hooks)
|
||||
|
||||
error?: Error & { statusCode?: number, headers?: IncomingHttpHeaders }
|
||||
options: any
|
||||
resolver: Resolver
|
||||
moduleContainer: ModuleContainer
|
||||
server?: any
|
||||
renderer?: any
|
||||
render?: any['app']
|
||||
showReady?: () => void
|
||||
// Init nitro
|
||||
await initNitro(nuxt)
|
||||
|
||||
constructor (options) {
|
||||
super(consola)
|
||||
// Init user modules
|
||||
await nuxt.callHook('modules:before', nuxt)
|
||||
const modulesToInstall = [
|
||||
...nuxt.options.buildModules,
|
||||
...nuxt.options.modules,
|
||||
...nuxt.options._modules
|
||||
]
|
||||
|
||||
this.options = options
|
||||
|
||||
// Create instance of core components
|
||||
this.resolver = new Resolver(this)
|
||||
this.moduleContainer = new ModuleContainer(this)
|
||||
|
||||
// Call ready
|
||||
if (this.options._ready !== false) {
|
||||
this.ready().catch((err) => {
|
||||
consola.fatal(err)
|
||||
})
|
||||
}
|
||||
for (const m of modulesToInstall) {
|
||||
await installModule(nuxt, m)
|
||||
}
|
||||
|
||||
static get version () {
|
||||
return `v${version}` + (global.__NUXT_DEV__ ? '-development' : '')
|
||||
}
|
||||
await nuxt.callHook('modules:done', nuxt)
|
||||
|
||||
ready () {
|
||||
if (!this._ready) {
|
||||
this._ready = this._init()
|
||||
}
|
||||
return this._ready
|
||||
}
|
||||
|
||||
async _init () {
|
||||
if (this._initCalled) {
|
||||
return this
|
||||
}
|
||||
this._initCalled = true
|
||||
|
||||
// Add hooks
|
||||
if (this.options.hooks instanceof Function) {
|
||||
this.options.hooks(this.hook)
|
||||
} else if (isPlainObject(this.options.hooks)) {
|
||||
this.addHooks(this.options.hooks)
|
||||
}
|
||||
|
||||
// Await for server
|
||||
await initNitro(this)
|
||||
|
||||
// Await for modules
|
||||
await this.moduleContainer.ready()
|
||||
|
||||
// Call ready hook
|
||||
await this.callHook('ready', this)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
async close (callback?: () => any | Promise<any>) {
|
||||
await this.callHook('close', this)
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
await callback()
|
||||
}
|
||||
}
|
||||
await nuxt.callHook('ready', nuxt)
|
||||
}
|
||||
|
||||
export async function loadNuxt (opts: LoadNuxtOptions) {
|
||||
const options = await loadNuxtConfig(opts)
|
||||
export interface LoadNuxtOptions extends LoadNuxtConfigOptions {
|
||||
for?: 'dev' | 'build'
|
||||
}
|
||||
|
||||
export async function loadNuxt (loadOpts: LoadNuxtOptions = {}): Promise<Nuxt> {
|
||||
const options = loadNuxtConfig({
|
||||
config: {
|
||||
dev: loadOpts.for === 'dev',
|
||||
...loadOpts.config
|
||||
},
|
||||
...loadOpts
|
||||
})
|
||||
|
||||
// Temp
|
||||
// @ts-ignore
|
||||
options.appDir = dirname(require.resolve('@nuxt/app'))
|
||||
options._majorVersion = 3
|
||||
|
||||
const nuxt = new Nuxt(options)
|
||||
await nuxt.ready()
|
||||
const nuxt = createNuxt(options)
|
||||
|
||||
await initNuxt(nuxt)
|
||||
|
||||
return nuxt
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ interface SegmentToken {
|
||||
|
||||
export async function resolvePagesRoutes (builder: Builder, app: NuxtApp) {
|
||||
const pagesDir = resolve(app.dir, app.pages!.dir)
|
||||
const pagesPattern = `${app.pages!.dir}/**/*.{${app.extensions.join(',')}}`
|
||||
const pagesPattern = `${app.pages!.dir}/**/*{${app.extensions.join(',')}}`
|
||||
const files = await resolveFiles(builder, pagesPattern, app.dir)
|
||||
|
||||
// Sort to make sure parent are listed first
|
||||
|
@ -1,186 +0,0 @@
|
||||
import { resolve, join } from 'path'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
import jiti from 'jiti'
|
||||
import {
|
||||
startsWithRootAlias,
|
||||
startsWithSrcAlias,
|
||||
isExternalDependency,
|
||||
clearRequireCache
|
||||
} from '@nuxt/kit'
|
||||
import { Nuxt } from './nuxt'
|
||||
|
||||
interface ResolvePathOptions {
|
||||
isAlias?: boolean
|
||||
isModule?: boolean
|
||||
isStyle?: boolean
|
||||
}
|
||||
|
||||
interface RequireModuleOptions {
|
||||
useESM?: boolean
|
||||
isAlias?: boolean
|
||||
interopDefault?: any
|
||||
}
|
||||
|
||||
export default class Resolver {
|
||||
_require: NodeJS.Require
|
||||
_resolve: NodeJS.RequireResolve
|
||||
nuxt: Nuxt
|
||||
options: Nuxt['options']
|
||||
|
||||
constructor (nuxt: Nuxt) {
|
||||
this.nuxt = nuxt
|
||||
this.options = this.nuxt.options
|
||||
|
||||
// Binds
|
||||
this.resolvePath = this.resolvePath.bind(this)
|
||||
this.resolveAlias = this.resolveAlias.bind(this)
|
||||
this.resolveModule = this.resolveModule.bind(this)
|
||||
this.requireModule = this.requireModule.bind(this)
|
||||
|
||||
this._require = jiti(__filename)
|
||||
this._resolve = this._require.resolve
|
||||
}
|
||||
|
||||
resolveModule (path: string) {
|
||||
try {
|
||||
return this._resolve(path, {
|
||||
paths: this.options.modulesDir
|
||||
})
|
||||
} catch (error) {
|
||||
if (error.code !== 'MODULE_NOT_FOUND') {
|
||||
// TODO: remove after https://github.com/facebook/jest/pull/8487 released
|
||||
if (process.env.NODE_ENV === 'test' && error.message.startsWith('Cannot resolve module')) {
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolveAlias (path: string) {
|
||||
if (startsWithRootAlias(path)) {
|
||||
return join(this.options.rootDir, path.substr(2))
|
||||
}
|
||||
|
||||
if (startsWithSrcAlias(path)) {
|
||||
return join(this.options.srcDir, path.substr(1))
|
||||
}
|
||||
|
||||
return resolve(this.options.srcDir, path)
|
||||
}
|
||||
|
||||
resolvePath (path: string, { isAlias, isModule, isStyle }: ResolvePathOptions = {}) {
|
||||
// Fast return in case of path exists
|
||||
if (fs.existsSync(path)) {
|
||||
return path
|
||||
}
|
||||
|
||||
let resolvedPath: string
|
||||
|
||||
// Try to resolve it as a regular module
|
||||
if (isModule !== false) {
|
||||
resolvedPath = this.resolveModule(path)
|
||||
}
|
||||
|
||||
// Try to resolve alias
|
||||
if (!resolvedPath && isAlias !== false) {
|
||||
resolvedPath = this.resolveAlias(path)
|
||||
}
|
||||
|
||||
// Use path for resolvedPath
|
||||
if (!resolvedPath) {
|
||||
resolvedPath = path
|
||||
}
|
||||
|
||||
let isDirectory: boolean
|
||||
|
||||
// Check if resolvedPath exits and is not a directory
|
||||
if (fs.existsSync(resolvedPath)) {
|
||||
isDirectory = fs.lstatSync(resolvedPath).isDirectory()
|
||||
|
||||
if (!isDirectory) {
|
||||
return resolvedPath
|
||||
}
|
||||
}
|
||||
|
||||
const extensions = isStyle ? this.options.styleExtensions : this.options.extensions
|
||||
|
||||
// Check if any resolvedPath.[ext] or resolvedPath/index.[ext] exists
|
||||
for (const ext of extensions) {
|
||||
if (!isDirectory && fs.existsSync(resolvedPath + '.' + ext)) {
|
||||
return resolvedPath + '.' + ext
|
||||
}
|
||||
|
||||
const resolvedPathwithIndex = join(resolvedPath, 'index.' + ext)
|
||||
if (isDirectory && fs.existsSync(resolvedPathwithIndex)) {
|
||||
return resolvedPathwithIndex
|
||||
}
|
||||
}
|
||||
|
||||
// If there's no index.[ext] we just return the directory path
|
||||
if (isDirectory) {
|
||||
return resolvedPath
|
||||
}
|
||||
|
||||
// Give up
|
||||
throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`)
|
||||
}
|
||||
|
||||
tryResolvePath (path: string, options?: ResolvePathOptions) {
|
||||
try {
|
||||
return this.resolvePath(path, options)
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
requireModule <T> (path: string, { useESM, isAlias, interopDefault }: RequireModuleOptions = {}): T {
|
||||
let resolvedPath = path
|
||||
let requiredModule: any
|
||||
|
||||
let lastError: any
|
||||
|
||||
// Try to resolve path
|
||||
try {
|
||||
resolvedPath = this.resolvePath(path, { isAlias })
|
||||
} catch (e) {
|
||||
lastError = e
|
||||
}
|
||||
|
||||
const isExternal = isExternalDependency(resolvedPath)
|
||||
|
||||
// in dev mode make sure to clear the require cache so after
|
||||
// a dev server restart any changed file is reloaded
|
||||
if (this.options.dev && !isExternal) {
|
||||
clearRequireCache(resolvedPath)
|
||||
}
|
||||
|
||||
// By default use esm only for js,mjs files outside of node_modules
|
||||
if (useESM === undefined) {
|
||||
useESM = !isExternal && /.(js|mjs)$/.test(resolvedPath)
|
||||
}
|
||||
|
||||
// Try to require
|
||||
try {
|
||||
if (useESM) {
|
||||
requiredModule = this._require(resolvedPath)
|
||||
} else {
|
||||
requiredModule = require(resolvedPath)
|
||||
}
|
||||
} catch (e) {
|
||||
lastError = e
|
||||
}
|
||||
|
||||
// Interop default
|
||||
if (interopDefault !== false && requiredModule && requiredModule.default) {
|
||||
requiredModule = requiredModule.default
|
||||
}
|
||||
|
||||
// Throw error if failed to require
|
||||
if (requiredModule === undefined && lastError) {
|
||||
throw lastError
|
||||
}
|
||||
|
||||
return requiredModule
|
||||
}
|
||||
}
|
@ -19,10 +19,16 @@ export function templateData (builder) {
|
||||
}
|
||||
}
|
||||
|
||||
async function compileTemplate ({ src, path, data }: NuxtTemplate, destDir: string) {
|
||||
const srcContents = await fsExtra.readFile(src, 'utf-8')
|
||||
const compiledSrc = lodashTemplate(srcContents, {})(data)
|
||||
const dest = join(destDir, path)
|
||||
async function compileTemplate (tmpl: NuxtTemplate, destDir: string) {
|
||||
const srcContents = await fsExtra.readFile(tmpl.src, 'utf-8')
|
||||
let compiledSrc
|
||||
try {
|
||||
compiledSrc = lodashTemplate(srcContents, {})(tmpl.data)
|
||||
} catch (err) {
|
||||
console.error('Error compiling template: ', tmpl)
|
||||
throw err
|
||||
}
|
||||
const dest = join(destDir, tmpl.path)
|
||||
// consola.log('Compile template', dest)
|
||||
await fsExtra.mkdirp(dirname(dest))
|
||||
await fsExtra.writeFile(dest, compiledSrc)
|
||||
|
@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import consola from 'consola'
|
||||
@ -5,10 +6,9 @@ import defaults from 'lodash/defaults'
|
||||
import merge from 'lodash/merge'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import createResolver from 'postcss-import-resolver'
|
||||
import { Nuxt, tryRequireModule } from '@nuxt/kit'
|
||||
|
||||
import { isPureObject } from '@nuxt/kit'
|
||||
import type { Nuxt } from '../../../core'
|
||||
import type { NormalizedConfiguration } from '../../../config'
|
||||
const isPureObject = obj => obj !== null && !Array.isArray(obj) && typeof obj === 'object'
|
||||
|
||||
export const orderPresets = {
|
||||
cssnanoLast (names) {
|
||||
@ -30,17 +30,18 @@ export const orderPresets = {
|
||||
}
|
||||
}
|
||||
|
||||
let _postcssConfigFileWarningShown
|
||||
function postcssConfigFileWarning () {
|
||||
if (postcssConfigFileWarning.executed) {
|
||||
if (_postcssConfigFileWarningShown) {
|
||||
return
|
||||
}
|
||||
consola.warn('Please use `build.postcss` in your nuxt.config.js instead of an external config file. Support for such files will be removed in Nuxt 3 as they remove all defaults set by Nuxt and can cause severe problems with features like alias resolving inside your CSS.')
|
||||
postcssConfigFileWarning.executed = true
|
||||
_postcssConfigFileWarningShown = true
|
||||
}
|
||||
|
||||
export default class PostcssConfig {
|
||||
nuxt: Nuxt
|
||||
options: NormalizedConfiguration
|
||||
options: Nuxt['options']
|
||||
|
||||
constructor (nuxt) {
|
||||
this.nuxt = nuxt
|
||||
@ -150,7 +151,7 @@ export default class PostcssConfig {
|
||||
// Map postcss plugins into instances on object mode once
|
||||
config.plugins = this.sortPlugins(config)
|
||||
.map((p) => {
|
||||
const plugin = this.nuxt.resolver.requireModule(p)
|
||||
const plugin = tryRequireModule(p)
|
||||
const opts = plugins[p]
|
||||
if (opts === false) {
|
||||
return false // Disabled
|
||||
|
@ -1,3 +1,5 @@
|
||||
export default {
|
||||
import { defineNuxtConfig } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
vite: true
|
||||
}
|
||||
})
|
||||
|
172
scripts/build.ts
172
scripts/build.ts
@ -1,7 +1,7 @@
|
||||
import { promisify } from 'util'
|
||||
import { resolve, relative, dirname } from 'path'
|
||||
import Module from 'module'
|
||||
import { writeFile, mkdir } from 'fs/promises'
|
||||
import { writeFile, mkdir, unlink, symlink } from 'fs/promises'
|
||||
import chalk from 'chalk'
|
||||
import consola from 'consola'
|
||||
import rimraf from 'rimraf'
|
||||
@ -12,12 +12,16 @@ import alias from '@rollup/plugin-alias'
|
||||
import esbuild from 'rollup-plugin-esbuild'
|
||||
import { mkdist } from 'mkdist'
|
||||
import prettyBytes from 'pretty-bytes'
|
||||
import execa from 'execa'
|
||||
import dts from 'rollup-plugin-dts'
|
||||
|
||||
interface BuildEntry {
|
||||
name: string
|
||||
input: string
|
||||
output: string
|
||||
bundle: boolean
|
||||
srcDir: string
|
||||
distDir: string
|
||||
format: 'esm' | 'cjs'
|
||||
}
|
||||
|
||||
@ -51,7 +55,14 @@ async function main () {
|
||||
ctx.externals.push(...buildOptions.externals)
|
||||
}
|
||||
|
||||
await promisify(rimraf)(resolve(ctx.rootDir, 'dist'))
|
||||
const distDir = resolve(ctx.rootDir, 'dist')
|
||||
await unlink(distDir).catch(() => {})
|
||||
await promisify(rimraf)(distDir)
|
||||
|
||||
if (buildOptions.prebuild) {
|
||||
const [cmd, ...args] = buildOptions.prebuild.split(' ')
|
||||
await execa(cmd, args)
|
||||
}
|
||||
|
||||
if (args.includes('--stub')) {
|
||||
const stubbed: string[] = []
|
||||
@ -65,40 +76,50 @@ async function main () {
|
||||
const esStub = `export * from '${input}'`
|
||||
await writeFile(output, entry.format === 'cjs' ? cjsStub : esStub)
|
||||
await writeFile(output.replace('.js', '.d.ts'), esStub)
|
||||
} else {
|
||||
const outDir = resolve(ctx.rootDir, entry.output)
|
||||
const srcDir = resolve(ctx.rootDir, entry.input)
|
||||
await unlink(outDir).catch(() => { })
|
||||
await symlink(srcDir, outDir)
|
||||
}
|
||||
}
|
||||
consola.success(`Stub done: ${stubbed.join(', ')}`)
|
||||
return
|
||||
}
|
||||
|
||||
consola.info(chalk.cyan(`Builduing ${pkg.name}`))
|
||||
if (process.env.DEBUG) {
|
||||
consola.info(`${chalk.cyan(`Builduing ${pkg.name}`)}
|
||||
|
||||
${chalk.bold('Root dir:')} ${ctx.rootDir}
|
||||
${chalk.bold('Entries:')}
|
||||
${ctx.entries.map(entry => ' ' + dumpObject(entry)).join('\n')}
|
||||
consola.info(`
|
||||
${chalk.bold('Root dir:')} ${ctx.rootDir}
|
||||
${chalk.bold('Entries:')}
|
||||
${ctx.entries.map(entry => ' ' + dumpObject(entry)).join('\n')}
|
||||
`)
|
||||
}
|
||||
|
||||
const rollupOptions = getRollupOptions(ctx)
|
||||
const buildResult = await rollup(rollupOptions)
|
||||
const outputOptions = rollupOptions.output as OutputOptions
|
||||
const { output } = await buildResult.write(outputOptions)
|
||||
|
||||
const usedImports = new Set<string>()
|
||||
const buildEntries: { path: string, bytes?: number, exports?: string[], chunks?: string[] }[] = []
|
||||
const usedImports = new Set<string>()
|
||||
if (rollupOptions) {
|
||||
const buildResult = await rollup(rollupOptions)
|
||||
const outputOptions = rollupOptions.output as OutputOptions
|
||||
const { output } = await buildResult.write(outputOptions)
|
||||
|
||||
for (const entry of output.filter(e => e.type === 'chunk') as OutputChunk[]) {
|
||||
for (const id of entry.imports) {
|
||||
usedImports.add(id)
|
||||
}
|
||||
if (entry.isEntry) {
|
||||
buildEntries.push({
|
||||
path: entry.fileName,
|
||||
bytes: entry.code.length * 4,
|
||||
exports: entry.exports
|
||||
})
|
||||
for (const entry of output.filter(e => e.type === 'chunk') as OutputChunk[]) {
|
||||
for (const id of entry.imports) {
|
||||
usedImports.add(id)
|
||||
}
|
||||
if (entry.isEntry) {
|
||||
buildEntries.push({
|
||||
path: relative(ctx.rootDir, resolve(outputOptions.dir, entry.fileName)),
|
||||
bytes: entry.code.length * 4,
|
||||
exports: entry.exports
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Types
|
||||
rollupOptions.plugins.push(dts())
|
||||
const typesBuild = await rollup(rollupOptions)
|
||||
await typesBuild.write(outputOptions)
|
||||
}
|
||||
|
||||
for (const entry of ctx.entries.filter(e => !e.bundle)) {
|
||||
@ -109,50 +130,51 @@ ${ctx.entries.map(entry => ' ' + dumpObject(entry)).join('\n')}
|
||||
format: entry.format
|
||||
})
|
||||
buildEntries.push({
|
||||
path: entry.output,
|
||||
bytes: 0,
|
||||
chunks: writtenFiles.map(p => relative(resolve(ctx.rootDir, entry.output), p))
|
||||
path: relative(ctx.rootDir, entry.output),
|
||||
chunks: [`${writtenFiles.length} files`]
|
||||
})
|
||||
}
|
||||
|
||||
consola.success(chalk.green('Build succeed'))
|
||||
|
||||
if (process.env.DEBUG) {
|
||||
consola.log(`
|
||||
${buildEntries.map(entry => `${chalk.bold(entry.path)}
|
||||
size: ${chalk.cyan(entry.bytes ? prettyBytes(entry.bytes) : '-')}
|
||||
exports: ${chalk.gray(entry.exports ? entry.exports.join(', ') : '-')}
|
||||
chunks: ${chalk.gray(entry.chunks ? entry.chunks.join(', ') : '-')}`
|
||||
).join('\n')}`)
|
||||
consola.success(chalk.green('Build succeed for ' + pkg.name))
|
||||
for (const entry of buildEntries) {
|
||||
consola.log(` ${chalk.bold(entry.path)} (` + [
|
||||
entry.bytes && `size: ${chalk.cyan(prettyBytes(entry.bytes))}`,
|
||||
entry.exports && `exports: ${chalk.gray(entry.exports.join(', '))}`,
|
||||
entry.chunks && `chunks: ${chalk.gray(entry.chunks.join(', '))}`
|
||||
].filter(Boolean).join(', ') + ')')
|
||||
}
|
||||
|
||||
const usedDependencies = new Set<string>()
|
||||
const unusedDependencies = new Set<string>(Object.keys(pkg.dependencies || {}))
|
||||
const implicitDependnecies = new Set<string>()
|
||||
for (const id of usedImports) {
|
||||
unusedDependencies.delete(id)
|
||||
usedDependencies.add(id)
|
||||
}
|
||||
if (Array.isArray(buildOptions.dependencies)) {
|
||||
for (const id of buildOptions.dependencies) {
|
||||
if (rollupOptions) {
|
||||
const usedDependencies = new Set<string>()
|
||||
const unusedDependencies = new Set<string>(Object.keys(pkg.dependencies || {}))
|
||||
const implicitDependnecies = new Set<string>()
|
||||
for (const id of usedImports) {
|
||||
unusedDependencies.delete(id)
|
||||
usedDependencies.add(id)
|
||||
}
|
||||
if (Array.isArray(buildOptions.dependencies)) {
|
||||
for (const id of buildOptions.dependencies) {
|
||||
unusedDependencies.delete(id)
|
||||
}
|
||||
}
|
||||
for (const id of usedDependencies) {
|
||||
if (
|
||||
!ctx.externals.includes(id) &&
|
||||
!id.startsWith('chunks/') &&
|
||||
!ctx.externals.includes(id.split('/')[0]) // lodash/get
|
||||
) {
|
||||
implicitDependnecies.add(id)
|
||||
}
|
||||
}
|
||||
if (unusedDependencies.size) {
|
||||
consola.warn('Potential unused dependencies found:', Array.from(unusedDependencies).map(id => chalk.cyan(id)).join(', '))
|
||||
}
|
||||
if (implicitDependnecies.size) {
|
||||
consola.warn('Potential implicit dependencies found:', Array.from(implicitDependnecies).map(id => chalk.cyan(id)).join(', '))
|
||||
}
|
||||
}
|
||||
for (const id of usedDependencies) {
|
||||
if (
|
||||
!ctx.externals.includes(id) &&
|
||||
!id.startsWith('chunks/') &&
|
||||
!ctx.externals.includes(id.split('/')[0]) // lodash/get
|
||||
) {
|
||||
implicitDependnecies.add(id)
|
||||
}
|
||||
}
|
||||
if (unusedDependencies.size) {
|
||||
consola.warn('Potential unused dependencies found:', Array.from(unusedDependencies).map(id => chalk.cyan(id)).join(', '))
|
||||
}
|
||||
if (implicitDependnecies.size) {
|
||||
consola.warn('Potential implicit dependencies found:', Array.from(implicitDependnecies).map(id => chalk.cyan(id)).join(', '))
|
||||
}
|
||||
|
||||
consola.log('')
|
||||
}
|
||||
|
||||
function resolveEntry (input: string | [string, Partial<BuildEntry>] | Partial<BuildEntry>): BuildEntry {
|
||||
@ -163,9 +185,9 @@ function resolveEntry (input: string | [string, Partial<BuildEntry>] | Partial<B
|
||||
if (Array.isArray(input)) {
|
||||
entry = { name: input[0], ...input[1] }
|
||||
}
|
||||
entry.input = entry.input ?? `src/${entry.name}`
|
||||
entry.output = entry.output ?? `dist/${entry.name}`
|
||||
entry.bundle = entry.bundle ?? !entry.input.endsWith('/')
|
||||
entry.input = entry.input ?? resolve(entry.srcDir || 'src', './' + entry.name)
|
||||
entry.output = entry.output ?? resolve(entry.distDir || 'dist', './' + entry.name)
|
||||
entry.bundle = entry.bundle ?? !(entry.input.endsWith('/') || entry.name.endsWith('/'))
|
||||
entry.format = entry.format ?? 'esm'
|
||||
return entry as BuildEntry
|
||||
}
|
||||
@ -174,13 +196,18 @@ function dumpObject (obj) {
|
||||
return '{ ' + Object.keys(obj).map(key => `${key}: ${JSON.stringify(obj[key])}`).join(', ') + ' }'
|
||||
}
|
||||
|
||||
function getRollupOptions (ctx: BuildContext): RollupOptions {
|
||||
function getRollupOptions (ctx: BuildContext): RollupOptions | null {
|
||||
const extensions = ['.ts', '.mjs', '.js', '.json']
|
||||
|
||||
const r = (...path) => resolve(ctx.rootDir, ...path)
|
||||
|
||||
const entries = ctx.entries.filter(e => e.bundle)
|
||||
if (!entries.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <RollupOptions>{
|
||||
input: ctx.entries.filter(e => e.bundle).map(e => e.input),
|
||||
input: entries.map(e => e.input),
|
||||
|
||||
output: {
|
||||
dir: r('dist'),
|
||||
@ -194,7 +221,17 @@ function getRollupOptions (ctx: BuildContext): RollupOptions {
|
||||
if (id[0] === '.' || id[0] === '/' || id.includes('src/')) {
|
||||
return false
|
||||
}
|
||||
return !!ctx.externals.find(ext => id.includes(ext))
|
||||
const isExplicitExternal = !!ctx.externals.find(ext => id.includes(ext))
|
||||
if (!isExplicitExternal) {
|
||||
consola.warn(`Inlining external ${id}`)
|
||||
}
|
||||
return isExplicitExternal
|
||||
},
|
||||
|
||||
onwarn (warning, rollupWarn) {
|
||||
if (!['CIRCULAR_DEPENDENCY'].includes(warning.code)) {
|
||||
rollupWarn(warning)
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [
|
||||
@ -222,4 +259,7 @@ function getRollupOptions (ctx: BuildContext): RollupOptions {
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(consola.error)
|
||||
main().catch((err) => {
|
||||
consola.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
77
yarn.lock
77
yarn.lock
@ -2196,6 +2196,17 @@
|
||||
"@vue/babel-plugin-transform-vue-jsx" "^1.2.1"
|
||||
camelcase "^5.0.0"
|
||||
|
||||
"@vue/compiler-core@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.10.tgz#ced92120c6b9bab7b6c44dfe5e3e5cf2ea422531"
|
||||
integrity sha512-rayD+aODgX9CWgWv0cAI+whPLyMmtkWfNGsZpdpsaIloh8mY2hX8+SvE1Nn3755YhGWJ/7oaDEcNpOctGwZbsA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.12.0"
|
||||
"@babel/types" "^7.12.0"
|
||||
"@vue/shared" "3.0.10"
|
||||
estree-walker "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-core@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.9.tgz#ec7efa676889aee006fc43739ee4a67a952ac623"
|
||||
@ -2207,6 +2218,14 @@
|
||||
estree-walker "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-dom@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.10.tgz#59d3597498e7d4b0b92f3886a823f99d5b08f1fe"
|
||||
integrity sha512-SzN1li9xAxtqkZimR1AFU2t1N0vzsAJxR/5764xoS0xedwhUU9s8s+Tks2FNMLsXiqdkP2Qd4zAM+9EwTbZmRw==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.0.10"
|
||||
"@vue/shared" "3.0.10"
|
||||
|
||||
"@vue/compiler-dom@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.9.tgz#1fd554097d9ab36eca73bc6d0d9607fecf94e71c"
|
||||
@ -2245,6 +2264,13 @@
|
||||
"@vue/compiler-dom" "3.0.9"
|
||||
"@vue/shared" "3.0.9"
|
||||
|
||||
"@vue/reactivity@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.10.tgz#012830733291e60827f3b228d425ad53b83484ce"
|
||||
integrity sha512-0GOSqlIv/a5wy4r6fAcdaglQ8v2sLYMRUpu49yK8Z2vHccK85Ym3R9C9K3vo6dfBRGbbCVvoKxYtQw49LvE8Ug==
|
||||
dependencies:
|
||||
"@vue/shared" "3.0.10"
|
||||
|
||||
"@vue/reactivity@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.9.tgz#875f241b8c10262560b190ccdeff2d0ab7053e11"
|
||||
@ -2252,6 +2278,14 @@
|
||||
dependencies:
|
||||
"@vue/shared" "3.0.9"
|
||||
|
||||
"@vue/runtime-core@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.10.tgz#cb8730c0ec86ea5c1cfa701facc0a97bf59b15a2"
|
||||
integrity sha512-qKhCOwHGff5YEdyClO1gf9Q9xgaPPz/qJ2GyzNZkPb00WcXJ3l+yTgHZWaSywRLs9GD1y9Ff3C0MIowzj95NHA==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.0.10"
|
||||
"@vue/shared" "3.0.10"
|
||||
|
||||
"@vue/runtime-core@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.9.tgz#9665f149468355a524a304cb8f260147a4d294e6"
|
||||
@ -2260,6 +2294,15 @@
|
||||
"@vue/reactivity" "3.0.9"
|
||||
"@vue/shared" "3.0.9"
|
||||
|
||||
"@vue/runtime-dom@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.10.tgz#80c6ee28caeabf74f31357d2c64d177945bd8a5f"
|
||||
integrity sha512-8yRAALc/884UlYWY7hJImecvow1Cngbl2B6n0ThYTms08FVQ3W9tdW0MEvR3JVit06JyQLS1Qvwdn1PwNPPDqg==
|
||||
dependencies:
|
||||
"@vue/runtime-core" "3.0.10"
|
||||
"@vue/shared" "3.0.10"
|
||||
csstype "^2.6.8"
|
||||
|
||||
"@vue/runtime-dom@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.9.tgz#16a1d001dc746a9f346ee7fb9de90d52ad097b61"
|
||||
@ -2277,6 +2320,11 @@
|
||||
"@vue/compiler-ssr" "3.0.9"
|
||||
"@vue/shared" "3.0.9"
|
||||
|
||||
"@vue/shared@3.0.10":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.10.tgz#5476d5615d01bf339c65c2e804f5909bbc27844a"
|
||||
integrity sha512-p8GJ+bGpEGiEHICwcCH/EtJnkZQllrOfm1J2J+Ep0ydMte25bPnArgrY/h2Tn1LKqqR3LXyQlOSYY6gJgiW2LQ==
|
||||
|
||||
"@vue/shared@3.0.9":
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.9.tgz#09882d745ded52b07e4481d036659d733edd2a9a"
|
||||
@ -7544,10 +7592,10 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
mkdist@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/mkdist/-/mkdist-0.1.2.tgz#7365d975005976a7ac22540c0e76f8b21b33cdb0"
|
||||
integrity sha512-NELp7Nnz8pKek6pvIz4snM1j+D8ni9Gm5UhKApuK9pgrbd/Q3KveVg2HtEWy73AKuG1wXnK9O3cjfKD5OgG9Ww==
|
||||
mkdist@^0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/mkdist/-/mkdist-0.1.3.tgz#46787c2493493d8eff1770700da23d5c4fc3d844"
|
||||
integrity sha512-WQ0l+v0ICvxvsmgi2MtePzeyis5kMDRUMnibUDsc1NdVSo+lsoiIYbLrvIBgKJGJ2ITMaLDtCAHiFjF3U7h29A==
|
||||
dependencies:
|
||||
defu "^3.2.2"
|
||||
esbuild "^0.8.56"
|
||||
@ -9970,13 +10018,6 @@ static-extend@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
std-env@3.0.0-alpha:
|
||||
version "3.0.0-alpha"
|
||||
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.0.0-alpha.tgz#f161964da20a8af6a11bdbccfd39a99b5d7728d1"
|
||||
integrity sha512-WWaDtGMLaG1AqB8n792lM8zfR38xVw8iFIFGBvQRV4L+4kps54gvluqKcOq2Do2FwXNoKKjUJHRL1xgnz2pN3A==
|
||||
dependencies:
|
||||
ci-info "^2.0.0"
|
||||
|
||||
std-env@^2.2.1, std-env@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.3.0.tgz#66d4a4a4d5224242ed8e43f5d65cfa9095216eee"
|
||||
@ -10634,6 +10675,11 @@ unbox-primitive@^1.0.0:
|
||||
has-symbols "^1.0.0"
|
||||
which-boxed-primitive "^1.0.1"
|
||||
|
||||
unctx@^0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/unctx/-/unctx-0.0.3.tgz#e06f67d5bebe2babe5a57c1dc13d77255e3458c0"
|
||||
integrity sha512-x+NCoXiYn93laQNnoJGZx2UZj7vv8ViFKadUCDx9S4QoPIkGRCYT0OLUDEMlg/B+Q6bnqdSkPLmiy/kjNIwVyQ==
|
||||
|
||||
union-value@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
||||
@ -10904,6 +10950,15 @@ vue-template-compiler@^2.6.12:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.1.0"
|
||||
|
||||
vue@^3.0.10:
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.10.tgz#b5d2801c6ac0e756c850ad7a8f9a78cbccbad02a"
|
||||
integrity sha512-6arZ722uqIArSNUU94aqx0Pq0IMHFqYZuJ+U+q9HGdZZu11VFpyFP/L/hakijGFKp56Jr0yxJdWbDiJGWPxwww==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.0.10"
|
||||
"@vue/runtime-dom" "3.0.10"
|
||||
"@vue/shared" "3.0.10"
|
||||
|
||||
vue@^3.0.9:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.9.tgz#c68ffc0e4aa2b0f1905124a9037b6e352de469ad"
|
||||
|
Loading…
Reference in New Issue
Block a user