mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 00:23:53 +00:00
refactor: enable strict type checking everywhere (#6943)
This commit is contained in:
parent
56c7b6168c
commit
9db2229f70
@ -20,7 +20,7 @@
|
|||||||
"pathe": "^0.3.5",
|
"pathe": "^0.3.5",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"scule": "^0.3.2",
|
"scule": "^0.3.2",
|
||||||
"untyped": "^0.4.5",
|
"untyped": "^0.4.7",
|
||||||
"vue-mq": "^1.0.1",
|
"vue-mq": "^1.0.1",
|
||||||
"vue-plausible": "^1.3.2"
|
"vue-plausible": "^1.3.2"
|
||||||
},
|
},
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"unctx": "^2.0.1",
|
"unctx": "^2.0.1",
|
||||||
"unimport": "^0.6.7",
|
"unimport": "^0.6.7",
|
||||||
"untyped": "^0.4.5"
|
"untyped": "^0.4.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.template": "^4",
|
"@types/lodash.template": "^4",
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"noImplicitAny": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"./src/**/*.ts",
|
|
||||||
"./test/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
@ -21,6 +21,7 @@
|
|||||||
"@nuxt/kit": "3.0.0-rc.8",
|
"@nuxt/kit": "3.0.0-rc.8",
|
||||||
"@nuxt/schema": "3.0.0-rc.8",
|
"@nuxt/schema": "3.0.0-rc.8",
|
||||||
"@types/clear": "^0",
|
"@types/clear": "^0",
|
||||||
|
"@types/flat": "^5.0.2",
|
||||||
"@types/mri": "^1.1.1",
|
"@types/mri": "^1.1.1",
|
||||||
"@types/semver": "^7",
|
"@types/semver": "^7",
|
||||||
"c12": "^0.2.9",
|
"c12": "^0.2.9",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { AddressInfo } from 'node:net'
|
import type { AddressInfo } from 'node:net'
|
||||||
|
import { RequestListener } from 'node:http'
|
||||||
import { resolve, relative, normalize } from 'pathe'
|
import { resolve, relative, normalize } from 'pathe'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
import { debounce } from 'perfect-debounce'
|
import { debounce } from 'perfect-debounce'
|
||||||
@ -24,15 +25,15 @@ export default defineNuxtCommand({
|
|||||||
overrideEnv('development')
|
overrideEnv('development')
|
||||||
|
|
||||||
const { listen } = await import('listhen')
|
const { listen } = await import('listhen')
|
||||||
let currentHandler
|
let currentHandler: RequestListener | undefined
|
||||||
let loadingMessage = 'Nuxt is starting...'
|
let loadingMessage = 'Nuxt is starting...'
|
||||||
const loadingHandler = async (_req, res) => {
|
const loadingHandler: RequestListener = async (_req, res) => {
|
||||||
const { loading: loadingTemplate } = await importModule('@nuxt/ui-templates')
|
const { loading: loadingTemplate } = await importModule('@nuxt/ui-templates')
|
||||||
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
||||||
res.statusCode = 503 // Service Unavailable
|
res.statusCode = 503 // Service Unavailable
|
||||||
res.end(loadingTemplate({ loading: loadingMessage }))
|
res.end(loadingTemplate({ loading: loadingMessage }))
|
||||||
}
|
}
|
||||||
const serverHandler = (req, res) => {
|
const serverHandler: RequestListener = (req, res) => {
|
||||||
return currentHandler ? currentHandler(req, res) : loadingHandler(req, res)
|
return currentHandler ? currentHandler(req, res) : loadingHandler(req, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ export default defineNuxtCommand({
|
|||||||
const load = async (isRestart: boolean, reason?: string) => {
|
const load = async (isRestart: boolean, reason?: string) => {
|
||||||
try {
|
try {
|
||||||
loadingMessage = `${reason ? reason + '. ' : ''}${isRestart ? 'Restarting' : 'Starting'} nuxt...`
|
loadingMessage = `${reason ? reason + '. ' : ''}${isRestart ? 'Restarting' : 'Starting'} nuxt...`
|
||||||
currentHandler = null
|
currentHandler = undefined
|
||||||
if (isRestart) {
|
if (isRestart) {
|
||||||
consola.info(loadingMessage)
|
consola.info(loadingMessage)
|
||||||
}
|
}
|
||||||
@ -103,7 +104,7 @@ export default defineNuxtCommand({
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
consola.error(`Cannot ${isRestart ? 'restart' : 'start'} nuxt: `, err)
|
consola.error(`Cannot ${isRestart ? 'restart' : 'start'} nuxt: `, err)
|
||||||
currentHandler = null
|
currentHandler = undefined
|
||||||
loadingMessage = 'Error while loading nuxt. Please check console and fix errors.'
|
loadingMessage = 'Error while loading nuxt. Please check console and fix errors.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Argv } from 'mri'
|
import type { Argv } from 'mri'
|
||||||
|
|
||||||
const _rDefault = r => r.default || r
|
const _rDefault = (r: any) => r.default || r
|
||||||
|
|
||||||
export const commands = {
|
export const commands = {
|
||||||
dev: () => import('./dev').then(_rDefault),
|
dev: () => import('./dev').then(_rDefault),
|
||||||
|
@ -6,6 +6,7 @@ import jiti from 'jiti'
|
|||||||
import destr from 'destr'
|
import destr from 'destr'
|
||||||
import { splitByCase } from 'scule'
|
import { splitByCase } from 'scule'
|
||||||
import clipboardy from 'clipboardy'
|
import clipboardy from 'clipboardy'
|
||||||
|
import { NuxtModule } from '@nuxt/schema'
|
||||||
import { getPackageManager, getPackageManagerVersion } from '../utils/packageManagers'
|
import { getPackageManager, getPackageManagerVersion } from '../utils/packageManagers'
|
||||||
import { findup } from '../utils/fs'
|
import { findup } from '../utils/fs'
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
@ -27,13 +28,13 @@ export default defineNuxtCommand({
|
|||||||
const { dependencies = {}, devDependencies = {} } = findPackage(rootDir)
|
const { dependencies = {}, devDependencies = {} } = findPackage(rootDir)
|
||||||
|
|
||||||
// Utils to query a dependency version
|
// Utils to query a dependency version
|
||||||
const getDepVersion = name => getPkg(name, rootDir)?.version || dependencies[name] || devDependencies[name]
|
const getDepVersion = (name: string) => getPkg(name, rootDir)?.version || dependencies[name] || devDependencies[name]
|
||||||
|
|
||||||
const listModules = (arr = []) => arr
|
const listModules = (arr = []) => arr
|
||||||
.map(normalizeConfigModule)
|
.map(m => normalizeConfigModule(m, rootDir))
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map((name) => {
|
.map((name) => {
|
||||||
const npmName = name.split('/').splice(0, 2).join('/') // @foo/bar/baz => @foo/bar
|
const npmName = name!.split('/').splice(0, 2).join('/') // @foo/bar/baz => @foo/bar
|
||||||
const v = getDepVersion(npmName)
|
const v = getDepVersion(npmName)
|
||||||
return '`' + (v ? `${name}@${v}` : name) + '`'
|
return '`' + (v ? `${name}@${v}` : name) + '`'
|
||||||
})
|
})
|
||||||
@ -54,6 +55,7 @@ export default defineNuxtCommand({
|
|||||||
if (packageManager) {
|
if (packageManager) {
|
||||||
packageManager += '@' + getPackageManagerVersion(packageManager)
|
packageManager += '@' + getPackageManagerVersion(packageManager)
|
||||||
} else {
|
} else {
|
||||||
|
// @ts-expect-error
|
||||||
packageManager = 'unknown'
|
packageManager = 'unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,14 +97,14 @@ export default defineNuxtCommand({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function normalizeConfigModule (module, rootDir) {
|
function normalizeConfigModule (module: NuxtModule | string | null | undefined, rootDir: string): string | null {
|
||||||
if (!module) {
|
if (!module) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (typeof module === 'string') {
|
if (typeof module === 'string') {
|
||||||
return module
|
return module
|
||||||
.split(rootDir).pop() // Strip rootDir
|
.split(rootDir).pop()! // Strip rootDir
|
||||||
.split('node_modules').pop() // Strip node_modules
|
.split('node_modules').pop()! // Strip node_modules
|
||||||
.replace(/^\//, '')
|
.replace(/^\//, '')
|
||||||
}
|
}
|
||||||
if (typeof module === 'function') {
|
if (typeof module === 'function') {
|
||||||
@ -111,9 +113,10 @@ function normalizeConfigModule (module, rootDir) {
|
|||||||
if (Array.isArray(module)) {
|
if (Array.isArray(module)) {
|
||||||
return normalizeConfigModule(module[0], rootDir)
|
return normalizeConfigModule(module[0], rootDir)
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNuxtConfig (rootDir) {
|
function getNuxtConfig (rootDir: string) {
|
||||||
try {
|
try {
|
||||||
return jiti(rootDir, { interopDefault: true, esmResolve: true })('./nuxt.config')
|
return jiti(rootDir, { interopDefault: true, esmResolve: true })('./nuxt.config')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -122,7 +125,7 @@ function getNuxtConfig (rootDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPkg (name, rootDir) {
|
function getPkg (name: string, rootDir: string) {
|
||||||
// Assume it is in {rootDir}/node_modules/${name}/package.json
|
// Assume it is in {rootDir}/node_modules/${name}/package.json
|
||||||
let pkgPath = resolve(rootDir, 'node_modules', name, 'package.json')
|
let pkgPath = resolve(rootDir, 'node_modules', name, 'package.json')
|
||||||
|
|
||||||
@ -135,7 +138,7 @@ function getPkg (name, rootDir) {
|
|||||||
return readJSONSync(pkgPath)
|
return readJSONSync(pkgPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
function findPackage (rootDir) {
|
function findPackage (rootDir: string) {
|
||||||
return findup(rootDir, (dir) => {
|
return findup(rootDir, (dir) => {
|
||||||
const p = resolve(dir, 'package.json')
|
const p = resolve(dir, 'package.json')
|
||||||
if (existsSync(p)) {
|
if (existsSync(p)) {
|
||||||
@ -144,7 +147,7 @@ function findPackage (rootDir) {
|
|||||||
}) || {}
|
}) || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readJSONSync (filePath) {
|
function readJSONSync (filePath: string) {
|
||||||
try {
|
try {
|
||||||
return destr(readFileSync(filePath, 'utf-8'))
|
return destr(readFileSync(filePath, 'utf-8'))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { existsSync, readdirSync } from 'node:fs'
|
import { existsSync, readdirSync } from 'node:fs'
|
||||||
|
// @ts-expect-error missing types
|
||||||
import createTiged from 'tiged'
|
import createTiged from 'tiged'
|
||||||
import { relative, resolve } from 'pathe'
|
import { relative, resolve } from 'pathe'
|
||||||
import superb from 'superb'
|
import superb from 'superb'
|
||||||
import consola from 'consola'
|
import consola from 'consola'
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
||||||
const rpath = p => relative(process.cwd(), p)
|
const rpath = (p: string) => relative(process.cwd(), p)
|
||||||
|
|
||||||
const resolveTemplate = (template) => {
|
const resolveTemplate = (template: string | boolean) => {
|
||||||
if (typeof template === 'boolean') {
|
if (typeof template === 'boolean') {
|
||||||
consola.error('Please specify a template!')
|
consola.error('Please specify a template!')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
@ -39,12 +40,12 @@ export default defineNuxtCommand({
|
|||||||
consola.error(`Directory ${dstDir} is not empty. Please pick another name or remove it first. Aborting.`)
|
consola.error(`Directory ${dstDir} is not empty. Please pick another name or remove it first. Aborting.`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
const formatArgs = msg => msg.replace('options.', '--')
|
const formatArgs = (msg: string) => msg.replace('options.', '--')
|
||||||
tiged.on('warn', event => consola.warn(formatArgs(event.message)))
|
tiged.on('warn', (event: any) => consola.warn(formatArgs(event.message)))
|
||||||
tiged.on('info', event => consola.info(formatArgs(event.message)))
|
tiged.on('info', (event: any) => consola.info(formatArgs(event.message)))
|
||||||
try {
|
try {
|
||||||
await tiged.clone(dstDir)
|
await tiged.clone(dstDir)
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
if (e.toString().includes('could not find commit hash')) {
|
if (e.toString().includes('could not find commit hash')) {
|
||||||
consola.error(`Failed to clone template from \`${src}\`. Please check the repo is valid and that you have installed \`git\` correctly.`)
|
consola.error(`Failed to clone template from \`${src}\`. Please check the repo is valid and that you have installed \`git\` correctly.`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
@ -3,14 +3,14 @@ import { pathToFileURL } from 'node:url'
|
|||||||
import { normalize, dirname } from 'pathe'
|
import { normalize, dirname } from 'pathe'
|
||||||
|
|
||||||
export function getModulePaths (paths?: string | string[]): string[] {
|
export function getModulePaths (paths?: string | string[]): string[] {
|
||||||
return [].concat(
|
return [
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PREPATHS__,
|
global.__NUXT_PREPATHS__,
|
||||||
...(Array.isArray(paths) ? paths : [paths]),
|
...(paths ? [] : Array.isArray(paths) ? paths : [paths]),
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PATHS__
|
global.__NUXT_PATHS__
|
||||||
).filter(Boolean)
|
].filter(Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
const _require = createRequire(process.cwd())
|
const _require = createRequire(process.cwd())
|
||||||
|
@ -2,19 +2,19 @@ import flatten from 'flat'
|
|||||||
import { detailedDiff } from 'deep-object-diff'
|
import { detailedDiff } from 'deep-object-diff'
|
||||||
import { green, red, blue, cyan } from 'colorette'
|
import { green, red, blue, cyan } from 'colorette'
|
||||||
|
|
||||||
function normalizeDiff (diffObj, type, ignore) {
|
function normalizeDiff (diffObj: any, type: 'added' | 'deleted' | 'updated', ignore: string[]) {
|
||||||
return Object.entries(flatten(diffObj))
|
return Object.entries(flatten(diffObj) as Record<string, any>)
|
||||||
.map(([key, value]) => ({ key, value, type }))
|
.map(([key, value]) => ({ key, value, type }))
|
||||||
.filter(item => !ignore.includes(item.key) && typeof item.value !== 'function')
|
.filter(item => !ignore.includes(item.key) && typeof item.value !== 'function')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function diff (a, b, ignore) {
|
export function diff (a: any, b: any, ignore: string[]) {
|
||||||
const _diff: any = detailedDiff(a, b)
|
const _diff: any = detailedDiff(a, b)
|
||||||
return [].concat(
|
return [
|
||||||
normalizeDiff(_diff.added, 'added', ignore),
|
...normalizeDiff(_diff.added, 'added', ignore),
|
||||||
normalizeDiff(_diff.deleted, 'deleted', ignore),
|
...normalizeDiff(_diff.deleted, 'deleted', ignore),
|
||||||
normalizeDiff(_diff.updated, 'updated', ignore)
|
...normalizeDiff(_diff.updated, 'updated', ignore)
|
||||||
)
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
@ -23,9 +23,9 @@ const typeMap = {
|
|||||||
updated: blue('updated')
|
updated: blue('updated')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function printDiff (diff) {
|
export function printDiff (diff: any) {
|
||||||
for (const item of diff) {
|
for (const item of diff) {
|
||||||
console.log(' ', typeMap[item.type] || item.type, cyan(item.key), item.value ? `~> ${cyan(item.value)}` : '')
|
console.log(' ', typeMap[item.type as keyof typeof typeMap] || item.type, cyan(item.key), item.value ? `~> ${cyan(item.value)}` : '')
|
||||||
}
|
}
|
||||||
console.log()
|
console.log()
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
import { cyan, magenta } from 'colorette'
|
import { cyan, magenta } from 'colorette'
|
||||||
export function showHelp (meta?) {
|
import { NuxtCommandMeta } from '../commands'
|
||||||
|
|
||||||
|
export function showHelp (meta?: Partial<NuxtCommandMeta>) {
|
||||||
const sections: string[] = []
|
const sections: string[] = []
|
||||||
|
|
||||||
if (meta.usage) {
|
if (meta) {
|
||||||
sections.push(magenta('> ') + 'Usage: ' + cyan(meta.usage))
|
if (meta.usage) {
|
||||||
}
|
sections.push(magenta('> ') + 'Usage: ' + cyan(meta.usage))
|
||||||
|
}
|
||||||
|
|
||||||
if (meta.description) {
|
if (meta.description) {
|
||||||
sections.push(magenta('⋮ ') + meta.description)
|
sections.push(magenta('⋮ ') + meta.description)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sections.push(`Use ${cyan('npx nuxi [command] --help')} to see help for each command`)
|
sections.push(`Use ${cyan('npx nuxi [command] --help')} to see help for each command`)
|
||||||
|
@ -3,7 +3,7 @@ import { importModule } from './cjs'
|
|||||||
export const loadKit = async (rootDir: string): Promise<typeof import('@nuxt/kit')> => {
|
export const loadKit = async (rootDir: string): Promise<typeof import('@nuxt/kit')> => {
|
||||||
try {
|
try {
|
||||||
return await importModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit')
|
return await importModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit')
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
if (e.toString().includes("Cannot find module '@nuxt/kit'")) {
|
if (e.toString().includes("Cannot find module '@nuxt/kit'")) {
|
||||||
throw new Error('nuxi requires `@nuxt/kit` to be installed in your project. Try installing `nuxt3` or `@nuxt/bridge` first.')
|
throw new Error('nuxi requires `@nuxt/kit` to be installed in your project. Try installing `nuxt3` or `@nuxt/bridge` first.')
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import type { Nuxt } from '@nuxt/schema'
|
|||||||
import { rmRecursive } from './fs'
|
import { rmRecursive } from './fs'
|
||||||
|
|
||||||
export interface NuxtProjectManifest {
|
export interface NuxtProjectManifest {
|
||||||
_hash: string
|
_hash: string | null
|
||||||
project: {
|
project: {
|
||||||
rootDir: string
|
rootDir: string
|
||||||
},
|
},
|
||||||
|
@ -9,14 +9,17 @@ export const packageManagerLocks = {
|
|||||||
pnpm: 'pnpm-lock.yaml'
|
pnpm: 'pnpm-lock.yaml'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PackageManager = keyof typeof packageManagerLocks
|
||||||
|
|
||||||
export function getPackageManager (rootDir: string) {
|
export function getPackageManager (rootDir: string) {
|
||||||
return findup(rootDir, (dir) => {
|
return findup(rootDir, (dir) => {
|
||||||
for (const name in packageManagerLocks) {
|
for (const name in packageManagerLocks) {
|
||||||
if (existsSync(resolve(dir, packageManagerLocks[name]))) {
|
const path = packageManagerLocks[name as PackageManager]
|
||||||
|
if (path && existsSync(resolve(dir, path))) {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}) as PackageManager | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPackageManagerVersion (name: string) {
|
export function getPackageManagerVersion (name: string) {
|
||||||
|
@ -31,7 +31,7 @@ export const writeTypes = async (nuxt: Nuxt) => {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const aliases = {
|
const aliases: Record<string, string> = {
|
||||||
...nuxt.options.alias,
|
...nuxt.options.alias,
|
||||||
'#build': nuxt.options.buildDir
|
'#build': nuxt.options.buildDir
|
||||||
}
|
}
|
||||||
@ -48,6 +48,7 @@ export const writeTypes = async (nuxt: Nuxt) => {
|
|||||||
: aliases[alias]
|
: aliases[alias]
|
||||||
|
|
||||||
const stats = await fsp.stat(resolve(nuxt.options.rootDir, relativePath)).catch(() => null /* file does not exist */)
|
const stats = await fsp.stat(resolve(nuxt.options.rootDir, relativePath)).catch(() => null /* file does not exist */)
|
||||||
|
tsConfig.compilerOptions = tsConfig.compilerOptions || {}
|
||||||
if (stats?.isDirectory()) {
|
if (stats?.isDirectory()) {
|
||||||
tsConfig.compilerOptions.paths[alias] = [relativePath]
|
tsConfig.compilerOptions.paths[alias] = [relativePath]
|
||||||
tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`]
|
tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`]
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
"unenv": "^0.6.1",
|
"unenv": "^0.6.1",
|
||||||
"unimport": "^0.6.7",
|
"unimport": "^0.6.7",
|
||||||
"unplugin": "^0.9.2",
|
"unplugin": "^0.9.2",
|
||||||
"untyped": "^0.4.5",
|
"untyped": "^0.4.7",
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
"vue-bundle-renderer": "^0.4.2",
|
"vue-bundle-renderer": "^0.4.2",
|
||||||
"vue-devtools-stub": "^0.1.0",
|
"vue-devtools-stub": "^0.1.0",
|
||||||
|
@ -144,7 +144,7 @@ export function useAsyncData<
|
|||||||
result = options.transform(result)
|
result = options.transform(result)
|
||||||
}
|
}
|
||||||
if (options.pick) {
|
if (options.pick) {
|
||||||
result = pick(result, options.pick) as DataT
|
result = pick(result as any, options.pick) as DataT
|
||||||
}
|
}
|
||||||
asyncData.data.value = result
|
asyncData.data.value = result
|
||||||
asyncData.error.value = null
|
asyncData.error.value = null
|
||||||
|
@ -231,7 +231,7 @@ export function normalizePlugins (_plugins: Plugin[]) {
|
|||||||
return plugins as Plugin[]
|
return plugins as Plugin[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineNuxtPlugin<T> (plugin: Plugin<T>) {
|
export function defineNuxtPlugin<T extends Record<string, any>> (plugin: Plugin<T>) {
|
||||||
plugin[NuxtPluginIndicator] = true
|
plugin[NuxtPluginIndicator] = true
|
||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"noImplicitAny": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"./src/**/*.ts",
|
|
||||||
"./test/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
@ -41,6 +41,7 @@ export default defineBuildConfig({
|
|||||||
'ignore',
|
'ignore',
|
||||||
// Implicit
|
// Implicit
|
||||||
'@vue/compiler-core',
|
'@vue/compiler-core',
|
||||||
'@vue/shared'
|
'@vue/shared',
|
||||||
|
'untyped'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"@types/lodash.template": "^4",
|
"@types/lodash.template": "^4",
|
||||||
"@types/semver": "^7",
|
"@types/semver": "^7",
|
||||||
"unbuild": "latest",
|
"unbuild": "latest",
|
||||||
|
"untyped": "^0.4.7",
|
||||||
"vite": "~3.0.9"
|
"vite": "~3.0.9"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Configure Nuxt component auto-registration.
|
* Configure Nuxt component auto-registration.
|
||||||
*
|
*
|
||||||
@ -57,4 +59,4 @@ export default {
|
|||||||
* @version 3
|
* @version 3
|
||||||
*/
|
*/
|
||||||
telemetry: undefined
|
telemetry: undefined
|
||||||
}
|
})
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import { resolve, join } from 'pathe'
|
import { resolve, join } from 'pathe'
|
||||||
import { existsSync, readdirSync } from 'node:fs'
|
import { existsSync, readdirSync } from 'node:fs'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
import { MetaObject } from '../types/meta'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Vue.js config
|
* Vue.js config
|
||||||
* @version 2
|
* @version 2
|
||||||
@ -17,8 +20,12 @@ export default {
|
|||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
config: {
|
config: {
|
||||||
silent: { $resolve: (val, get) => val ?? !get('dev') },
|
silent: {
|
||||||
performance: { $resolve: (val, get) => val ?? get('dev') },
|
$resolve: (val, get) => val ?? !get('dev')
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
$resolve: (val, get) => val ?? get('dev')
|
||||||
|
},
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Options for the Vue compiler that will be passed at build time.
|
* Options for the Vue compiler that will be passed at build time.
|
||||||
@ -105,7 +112,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
head: {
|
head: {
|
||||||
$resolve: (val, get) => {
|
$resolve: (val, get) => {
|
||||||
const resolved = defu(val, get('meta'), {
|
const resolved: Required<MetaObject> = defu(val, get('meta'), {
|
||||||
meta: [],
|
meta: [],
|
||||||
link: [],
|
link: [],
|
||||||
style: [],
|
style: [],
|
||||||
@ -306,7 +313,7 @@ export default {
|
|||||||
* @version 3
|
* @version 3
|
||||||
*/
|
*/
|
||||||
css: {
|
css: {
|
||||||
$resolve: val => (val ?? []).map(c => c.src || c)
|
$resolve: val => (val ?? []).map((c: any) => c.src || c)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -460,4 +467,4 @@ export default {
|
|||||||
/** Set to false to disable the `<ClientOnly>` component (see [docs](https://github.com/egoist/vue-client-only)) */
|
/** Set to false to disable the `<ClientOnly>` component (see [docs](https://github.com/egoist/vue-client-only)) */
|
||||||
componentClientOnly: true
|
componentClientOnly: true
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -4,9 +4,12 @@ import createRequire from 'create-require'
|
|||||||
import { pascalCase } from 'scule'
|
import { pascalCase } from 'scule'
|
||||||
import jiti from 'jiti'
|
import jiti from 'jiti'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
|
|
||||||
import { RuntimeConfig } from '../types/config'
|
import { RuntimeConfig } from '../types/config'
|
||||||
|
|
||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Extend nested configurations from multiple local or remote sources.
|
* Extend nested configurations from multiple local or remote sources.
|
||||||
*
|
*
|
||||||
@ -152,12 +155,13 @@ export default {
|
|||||||
createRequire: {
|
createRequire: {
|
||||||
$resolve: (val: any) => {
|
$resolve: (val: any) => {
|
||||||
val = process.env.NUXT_CREATE_REQUIRE || val ||
|
val = process.env.NUXT_CREATE_REQUIRE || val ||
|
||||||
|
// @ts-expect-error global type
|
||||||
(typeof globalThis.jest !== 'undefined' ? 'native' : 'jiti')
|
(typeof globalThis.jest !== 'undefined' ? 'native' : 'jiti')
|
||||||
if (val === 'jiti') {
|
if (val === 'jiti') {
|
||||||
return p => jiti(typeof p === 'string' ? p : p.filename, { esmResolve: true })
|
return (p: string | { filename: string }) => jiti(typeof p === 'string' ? p : p.filename, { esmResolve: true })
|
||||||
}
|
}
|
||||||
if (val === 'native') {
|
if (val === 'native') {
|
||||||
return p => createRequire(typeof p === 'string' ? p : p.filename)
|
return (p: string | { filename: string }) => createRequire(typeof p === 'string' ? p : p.filename)
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
@ -312,17 +316,17 @@ export default {
|
|||||||
*/
|
*/
|
||||||
globals: {
|
globals: {
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
id: globalName => `__${globalName}`,
|
id: (globalName: string) => `__${globalName}`,
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
nuxt: globalName => `$${globalName}`,
|
nuxt: (globalName: string) => `$${globalName}`,
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
context: globalName => `__${globalName.toUpperCase()}__`,
|
context: (globalName: string) => `__${globalName.toUpperCase()}__`,
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
pluginPrefix: globalName => globalName,
|
pluginPrefix: (globalName: string) => globalName,
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
readyCallback: globalName => `on${pascalCase(globalName)}Ready`,
|
readyCallback: (globalName: string) => `on${pascalCase(globalName)}Ready`,
|
||||||
/** @type {(globalName: string) => string} */
|
/** @type {(globalName: string) => string} */
|
||||||
loadedCallback: globalName => `_on${pascalCase(globalName)}Loaded`
|
loadedCallback: (globalName: string) => `_on${pascalCase(globalName)}Loaded`
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,10 +431,10 @@ export default {
|
|||||||
*/
|
*/
|
||||||
modulesDir: {
|
modulesDir: {
|
||||||
$default: ['node_modules'],
|
$default: ['node_modules'],
|
||||||
$resolve: (val, get) => [].concat(
|
$resolve: (val, get) => [
|
||||||
val.map(dir => resolve(get('rootDir'), dir)),
|
...val.map((dir: string) => resolve(get('rootDir'), dir)),
|
||||||
resolve(process.cwd(), 'node_modules')
|
resolve(process.cwd(), 'node_modules')
|
||||||
)
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -759,4 +763,4 @@ export default {
|
|||||||
* @version 3
|
* @version 3
|
||||||
*/
|
*/
|
||||||
appConfig: {},
|
appConfig: {},
|
||||||
}
|
})
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/** @private */
|
/** @private */
|
||||||
_majorVersion: 2,
|
_majorVersion: 2,
|
||||||
/** @private */
|
/** @private */
|
||||||
@ -21,4 +23,4 @@ export default {
|
|||||||
_nuxtConfigFiles: [],
|
_nuxtConfigFiles: [],
|
||||||
/** @private */
|
/** @private */
|
||||||
appDir: ''
|
appDir: ''
|
||||||
}
|
})
|
||||||
|
@ -2,8 +2,9 @@ import defu from 'defu'
|
|||||||
import { join } from 'pathe'
|
import { join } from 'pathe'
|
||||||
import { isCI, isTest } from 'std-env'
|
import { isCI, isTest } from 'std-env'
|
||||||
import { normalizeURL, withTrailingSlash } from 'ufo'
|
import { normalizeURL, withTrailingSlash } from 'ufo'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* The builder to use for bundling the Vue part of your application.
|
* The builder to use for bundling the Vue part of your application.
|
||||||
*
|
*
|
||||||
@ -15,7 +16,7 @@ export default {
|
|||||||
if (typeof val === 'object') {
|
if (typeof val === 'object') {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
const map = {
|
const map: Record<string, string> = {
|
||||||
vite: '@nuxt/vite-builder',
|
vite: '@nuxt/vite-builder',
|
||||||
webpack: '@nuxt/webpack-builder',
|
webpack: '@nuxt/webpack-builder',
|
||||||
}
|
}
|
||||||
@ -225,15 +226,16 @@ export default {
|
|||||||
* chunk: ({ isDev }) => (isDev ? '[name].js' : '[id].[contenthash].js')
|
* chunk: ({ isDev }) => (isDev ? '[name].js' : '[id].[contenthash].js')
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
|
* @type {Record<string, ((arg: any) => string)>}
|
||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
filenames: {
|
filenames: {
|
||||||
app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
|
app: ({ isDev, isModern }: any) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
|
||||||
chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
|
chunk: ({ isDev, isModern }: any) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`,
|
||||||
css: ({ isDev }) => isDev ? '[name].css' : 'css/[contenthash:7].css',
|
css: ({ isDev }: any) => isDev ? '[name].css' : 'css/[contenthash:7].css',
|
||||||
img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]',
|
img: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]',
|
||||||
font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
|
font: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
|
||||||
video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
|
video: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,7 +362,9 @@ export default {
|
|||||||
optimization: {
|
optimization: {
|
||||||
runtimeChunk: 'single',
|
runtimeChunk: 'single',
|
||||||
/** Set minimize to false to disable all minimizers. (It is disabled in development by default) */
|
/** Set minimize to false to disable all minimizers. (It is disabled in development by default) */
|
||||||
minimize: { $resolve: (val, get) => val ?? !get('dev') },
|
minimize: {
|
||||||
|
$resolve: (val, get) => val ?? !get('dev')
|
||||||
|
},
|
||||||
/** You can set minimizer to a customized array of plugins. */
|
/** You can set minimizer to a customized array of plugins. */
|
||||||
minimizer: undefined,
|
minimizer: undefined,
|
||||||
splitChunks: {
|
splitChunks: {
|
||||||
@ -639,4 +643,4 @@ export default {
|
|||||||
*/
|
*/
|
||||||
followSymlinks: false
|
followSymlinks: false
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Add a message to the CLI banner by adding a string to this array.
|
* Add a message to the CLI banner by adding a string to this array.
|
||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
@ -11,4 +13,4 @@ export default {
|
|||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
bannerColor: 'green'
|
bannerColor: 'green'
|
||||||
}
|
})
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/** @version 3 */
|
/** @version 3 */
|
||||||
experimental: {
|
experimental: {
|
||||||
/**
|
/**
|
||||||
* Set to true to generate an async entry point for the Vue bundle (for module federation support).
|
* Set to true to generate an async entry point for the Vue bundle (for module federation support).
|
||||||
*/
|
*/
|
||||||
asyncEntry: {
|
asyncEntry: {
|
||||||
$resolve: (val, get) => val ?? false
|
$resolve: (val) => val ?? false
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,4 +53,4 @@ export default {
|
|||||||
*/
|
*/
|
||||||
viteServerDynamicImports: true
|
viteServerDynamicImports: true
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { joinURL } from 'ufo'
|
import { joinURL } from 'ufo'
|
||||||
|
import { SchemaDefinition } from 'untyped'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
export default {
|
export default <SchemaDefinition> {
|
||||||
/**
|
/**
|
||||||
* Directory name that holds all the assets and generated pages for a `static` build.
|
* Directory name that holds all the assets and generated pages for a `static` build.
|
||||||
*/
|
*/
|
||||||
@ -160,10 +161,16 @@ export default {
|
|||||||
* The full path to the directory underneath `/_nuxt/` where static assets
|
* The full path to the directory underneath `/_nuxt/` where static assets
|
||||||
* (payload, state and manifest files) will live.
|
* (payload, state and manifest files) will live.
|
||||||
*/
|
*/
|
||||||
base: { $resolve: (val, get) => val || joinURL(get('app').buildAssetsDir, get('generate.dir')) },
|
base: {
|
||||||
/** The full path to the versioned directory where static assets for the current buidl are located. */
|
$resolve: (val, get) => val || joinURL(get('app').buildAssetsDir, get('generate.dir'))
|
||||||
versionBase: { $resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version')) },
|
},
|
||||||
|
/** The full path to the versioned directory where static assets for the current build are located. */
|
||||||
|
versionBase: {
|
||||||
|
$resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version'))
|
||||||
|
},
|
||||||
/** A unique string to uniquely identify payload versions (defaults to the current timestamp). */
|
/** A unique string to uniquely identify payload versions (defaults to the current timestamp). */
|
||||||
version: { $resolve: val => val || (String(Math.round(Date.now() / 1000))) }
|
version: {
|
||||||
|
$resolve: val => val || (String(Math.round(Date.now() / 1000)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import { SchemaDefinition } from 'untyped'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
export default {
|
export default <SchemaDefinition> {
|
||||||
/** The text that displays on the Nuxt loading indicator when `ssr: false`. */
|
/** The text that displays on the Nuxt loading indicator when `ssr: false`. */
|
||||||
loading: 'Loading...',
|
loading: 'Loading...',
|
||||||
/** The 404 text on the default Nuxt error page. */
|
/** The 404 text on the default Nuxt error page. */
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Configuration for Nitro.
|
* Configuration for Nitro.
|
||||||
*
|
*
|
||||||
@ -31,4 +33,4 @@ export default {
|
|||||||
* @version 3
|
* @version 3
|
||||||
*/
|
*/
|
||||||
devServerHandlers: []
|
devServerHandlers: []
|
||||||
}
|
})
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import createResolver from 'postcss-import-resolver'
|
import createResolver from 'postcss-import-resolver'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
export default defineUntypedSchema({
|
||||||
/** @version 3 */
|
/** @version 3 */
|
||||||
postcss: {
|
postcss: {
|
||||||
/** Path to postcss config file. */
|
/** Path to postcss config file. */
|
||||||
@ -51,4 +52,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import { SchemaDefinition } from 'untyped'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
export default {
|
export default <SchemaDefinition>{
|
||||||
/**
|
/**
|
||||||
* Use this option to customize the Vue SSR bundle renderer.
|
* Use this option to customize the Vue SSR bundle renderer.
|
||||||
* This option is skipped if `ssr: false`.
|
* This option is skipped if `ssr: false`.
|
||||||
@ -10,9 +12,11 @@ export default {
|
|||||||
*/
|
*/
|
||||||
bundleRenderer: {
|
bundleRenderer: {
|
||||||
shouldPrefetch: () => false,
|
shouldPrefetch: () => false,
|
||||||
shouldPreload: (_fileWithoutQuery, asType) => ['script', 'style'].includes(asType),
|
shouldPreload: (_fileWithoutQuery: string, asType: string) => ['script', 'style'].includes(asType),
|
||||||
/** enabled by default for development */
|
/** enabled by default for development */
|
||||||
runInNewContext: { $resolve: (val, get) => val ?? get('dev') }
|
runInNewContext: {
|
||||||
|
$resolve: (val, get) => val ?? get('dev')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +45,9 @@ export default {
|
|||||||
*
|
*
|
||||||
* Set to `collapsed` to collapse the logs, or `false` to disable.
|
* Set to `collapsed` to collapse the logs, or `false` to disable.
|
||||||
*/
|
*/
|
||||||
ssrLog: { $resolve: (val, get) => get('dev') ? Boolean(val) : false },
|
ssrLog: {
|
||||||
|
$resolve: (val, get) => get('dev') ? Boolean(val) : false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for HTTP2 push headers.
|
* Configuration for HTTP2 push headers.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { normalizeURL, withTrailingSlash } from 'ufo'
|
import { normalizeURL, withTrailingSlash } from 'ufo'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Additional options passed to `vue-router`.
|
* Additional options passed to `vue-router`.
|
||||||
*
|
*
|
||||||
@ -168,4 +169,4 @@ export default {
|
|||||||
* @version 2
|
* @version 2
|
||||||
*/
|
*/
|
||||||
trailingSlash: undefined
|
trailingSlash: undefined
|
||||||
}
|
})
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import { SchemaDefinition } from 'untyped'
|
||||||
|
|
||||||
/** @version 2 */
|
/** @version 2 */
|
||||||
export default {
|
export default <SchemaDefinition>{
|
||||||
/**
|
/**
|
||||||
* Whether to enable HTTPS.
|
* Whether to enable HTTPS.
|
||||||
*
|
*
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export default {
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Configuration for Nuxt's TypeScript integration.
|
* Configuration for Nuxt's TypeScript integration.
|
||||||
*
|
*
|
||||||
@ -35,4 +37,4 @@ export default {
|
|||||||
*/
|
*/
|
||||||
shim: true
|
shim: true
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { withoutLeadingSlash } from 'ufo'
|
import { withoutLeadingSlash } from 'ufo'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
export default defineUntypedSchema({
|
||||||
/**
|
/**
|
||||||
* Configuration that will be passed directly to Vite.
|
* Configuration that will be passed directly to Vite.
|
||||||
*
|
*
|
||||||
@ -45,7 +46,7 @@ export default {
|
|||||||
exclude: {
|
exclude: {
|
||||||
$resolve: (val, get) => [
|
$resolve: (val, get) => [
|
||||||
...val || [],
|
...val || [],
|
||||||
...get('build.transpile').filter((i) => typeof i === 'string'),
|
...get('build.transpile').filter((i: string) => typeof i === 'string'),
|
||||||
'vue-demi'
|
'vue-demi'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -77,4 +78,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { join } from 'pathe'
|
import { join } from 'pathe'
|
||||||
|
import { defineUntypedSchema } from 'untyped'
|
||||||
|
|
||||||
export default {
|
export default defineUntypedSchema({
|
||||||
/** @version 3 */
|
/** @version 3 */
|
||||||
webpack: {
|
webpack: {
|
||||||
/**
|
/**
|
||||||
@ -122,12 +123,12 @@ export default {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
filenames: {
|
filenames: {
|
||||||
app: ({ isDev }) => isDev ? `[name].js` : `[contenthash:7].js`,
|
app: ({ isDev }: { isDev: boolean }) => isDev ? `[name].js` : `[contenthash:7].js`,
|
||||||
chunk: ({ isDev }) => isDev ? `[name].js` : `[contenthash:7].js`,
|
chunk: ({ isDev }: { isDev: boolean }) => isDev ? `[name].js` : `[contenthash:7].js`,
|
||||||
css: ({ isDev }) => isDev ? '[name].css' : 'css/[contenthash:7].css',
|
css: ({ isDev }: { isDev: boolean }) => isDev ? '[name].css' : 'css/[contenthash:7].css',
|
||||||
img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]',
|
img: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]',
|
||||||
font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
|
font: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]',
|
||||||
video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
|
video: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]'
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -297,4 +298,4 @@ export default {
|
|||||||
*/
|
*/
|
||||||
warningIgnoreFilters: [],
|
warningIgnoreFilters: [],
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
@ -71,10 +71,10 @@ export interface ModuleContainer {
|
|||||||
addServerMiddleware(arg1: any): void
|
addServerMiddleware(arg1: any): void
|
||||||
|
|
||||||
/** Allows extending webpack build config by chaining `options.build.extend` function. */
|
/** Allows extending webpack build config by chaining `options.build.extend` function. */
|
||||||
extendBuild(fn): void
|
extendBuild(fn: Function): void
|
||||||
|
|
||||||
/** Allows extending routes by chaining `options.router.extendRoutes` function. */
|
/** Allows extending routes by chaining `options.router.extendRoutes` function. */
|
||||||
extendRoutes(fn): void
|
extendRoutes(fn: Function): void
|
||||||
|
|
||||||
/** Registers a module. */
|
/** Registers a module. */
|
||||||
requireModule(installOptions: any, opts: any): Promise<void>
|
requireModule(installOptions: any, opts: any): Promise<void>
|
||||||
|
@ -31,7 +31,7 @@ export async function getBrowser (): Promise<Browser> {
|
|||||||
if (!ctx.browser) {
|
if (!ctx.browser) {
|
||||||
await createBrowser()
|
await createBrowser()
|
||||||
}
|
}
|
||||||
return ctx.browser
|
return ctx.browser!
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createPage (path?: string, options?: BrowserContextOptions) {
|
export async function createPage (path?: string, options?: BrowserContextOptions) {
|
||||||
|
@ -2,7 +2,7 @@ import { resolve } from 'node:path'
|
|||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import type { TestContext, TestOptions, TestRunner } from './types'
|
import type { TestContext, TestOptions, TestRunner } from './types'
|
||||||
|
|
||||||
let currentContext: TestContext
|
let currentContext: TestContext | undefined
|
||||||
|
|
||||||
export function createTestContext (options: Partial<TestOptions>): TestContext {
|
export function createTestContext (options: Partial<TestOptions>): TestContext {
|
||||||
const _options: Partial<TestOptions> = defu(options, {
|
const _options: Partial<TestOptions> = defu(options, {
|
||||||
@ -18,7 +18,7 @@ export function createTestContext (options: Partial<TestOptions>): TestContext {
|
|||||||
// TODO: auto detect based on process.env
|
// TODO: auto detect based on process.env
|
||||||
runner: <TestRunner>'vitest',
|
runner: <TestRunner>'vitest',
|
||||||
browserOptions: {
|
browserOptions: {
|
||||||
type: 'chromium'
|
type: 'chromium' as const
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -32,7 +32,9 @@ export function useTestContext (): TestContext {
|
|||||||
return currentContext
|
return currentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTestContext (context: TestContext): TestContext {
|
export function setTestContext (context: TestContext): TestContext
|
||||||
|
export function setTestContext (context?: TestContext): TestContext | undefined
|
||||||
|
export function setTestContext (context?: TestContext): TestContext | undefined {
|
||||||
currentContext = context
|
currentContext = context
|
||||||
return currentContext
|
return currentContext
|
||||||
}
|
}
|
||||||
|
@ -64,5 +64,5 @@ export async function loadFixture () {
|
|||||||
|
|
||||||
export async function buildFixture () {
|
export async function buildFixture () {
|
||||||
const ctx = useTestContext()
|
const ctx = useTestContext()
|
||||||
await kit.buildNuxt(ctx.nuxt)
|
await kit.buildNuxt(ctx.nuxt!)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ export async function runTests (opts: RunTestOptions) {
|
|||||||
process.env.NUXT_TEST_DEV = 'true'
|
process.env.NUXT_TEST_DEV = 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore missing types
|
||||||
const { startVitest } = await import('vitest/dist/node.mjs')
|
const { startVitest } = await import('vitest/dist/node.mjs')
|
||||||
const succeeded = await startVitest(
|
const succeeded = await startVitest(
|
||||||
[] /* argv */,
|
[] /* argv */,
|
||||||
|
@ -16,7 +16,7 @@ export async function startServer () {
|
|||||||
if (ctx.options.dev) {
|
if (ctx.options.dev) {
|
||||||
const nuxiCLI = await kit.resolvePath('nuxi/cli')
|
const nuxiCLI = await kit.resolvePath('nuxi/cli')
|
||||||
ctx.serverProcess = execa(nuxiCLI, ['dev'], {
|
ctx.serverProcess = execa(nuxiCLI, ['dev'], {
|
||||||
cwd: ctx.nuxt.options.rootDir,
|
cwd: ctx.nuxt!.options.rootDir,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
@ -37,7 +37,7 @@ export async function startServer () {
|
|||||||
throw new Error('Timeout waiting for dev server!')
|
throw new Error('Timeout waiting for dev server!')
|
||||||
} else {
|
} else {
|
||||||
ctx.serverProcess = execa('node', [
|
ctx.serverProcess = execa('node', [
|
||||||
resolve(ctx.nuxt.options.nitro.output.dir, 'server/index.mjs')
|
resolve(ctx.nuxt!.options.nitro.output!.dir!, 'server/index.mjs')
|
||||||
], {
|
], {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: {
|
env: {
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"noImplicitAny": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"./src/**/*.ts",
|
|
||||||
"./test/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
@ -58,6 +58,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/schema": "3.0.0-rc.8",
|
"@nuxt/schema": "3.0.0-rc.8",
|
||||||
|
"@types/lodash-es": "^4.17.6",
|
||||||
"@types/pify": "^5.0.1",
|
"@types/pify": "^5.0.1",
|
||||||
"@types/webpack-bundle-analyzer": "^4.4.2",
|
"@types/webpack-bundle-analyzer": "^4.4.2",
|
||||||
"@types/webpack-dev-middleware": "^5.0.2",
|
"@types/webpack-dev-middleware": "^5.0.2",
|
||||||
|
@ -68,6 +68,7 @@ function clientHMR (ctx: WebpackConfigContext) {
|
|||||||
`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`
|
`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config.plugins = config.plugins || []
|
||||||
config.plugins.push(new webpack.HotModuleReplacementPlugin())
|
config.plugins.push(new webpack.HotModuleReplacementPlugin())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ export function server (ctx: WebpackConfigContext) {
|
|||||||
function serverPreset (ctx: WebpackConfigContext) {
|
function serverPreset (ctx: WebpackConfigContext) {
|
||||||
const { config } = ctx
|
const { config } = ctx
|
||||||
|
|
||||||
config.output.filename = 'server.mjs'
|
config.output!.filename = 'server.mjs'
|
||||||
config.devtool = 'cheap-module-source-map'
|
config.devtool = 'cheap-module-source-map'
|
||||||
|
|
||||||
config.optimization = {
|
config.optimization = {
|
||||||
@ -53,8 +53,11 @@ function serverStandalone (ctx: WebpackConfigContext) {
|
|||||||
|
|
||||||
if (!Array.isArray(ctx.config.externals)) { return }
|
if (!Array.isArray(ctx.config.externals)) { return }
|
||||||
ctx.config.externals.push(({ request }, cb) => {
|
ctx.config.externals.push(({ request }, cb) => {
|
||||||
|
if (!request) {
|
||||||
|
return cb(undefined, false)
|
||||||
|
}
|
||||||
if (external.includes(request)) {
|
if (external.includes(request)) {
|
||||||
return cb(null, true)
|
return cb(undefined, true)
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
request[0] === '.' ||
|
request[0] === '.' ||
|
||||||
@ -63,16 +66,18 @@ function serverStandalone (ctx: WebpackConfigContext) {
|
|||||||
assetPattern.test(request)
|
assetPattern.test(request)
|
||||||
) {
|
) {
|
||||||
// console.log('Inline', request)
|
// console.log('Inline', request)
|
||||||
return cb(null, false)
|
return cb(undefined, false)
|
||||||
}
|
}
|
||||||
// console.log('Ext', request)
|
// console.log('Ext', request)
|
||||||
return cb(null, true)
|
return cb(undefined, true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function serverPlugins (ctx: WebpackConfigContext) {
|
function serverPlugins (ctx: WebpackConfigContext) {
|
||||||
const { config, options } = ctx
|
const { config, options } = ctx
|
||||||
|
|
||||||
|
config.plugins = config.plugins || []
|
||||||
|
|
||||||
// Server polyfills
|
// Server polyfills
|
||||||
if (options.webpack.serverURLPolyfill) {
|
if (options.webpack.serverURLPolyfill) {
|
||||||
config.plugins.push(new webpack.ProvidePlugin({
|
config.plugins.push(new webpack.ProvidePlugin({
|
||||||
@ -83,6 +88,6 @@ function serverPlugins (ctx: WebpackConfigContext) {
|
|||||||
|
|
||||||
// Add type-checking
|
// Add type-checking
|
||||||
if (ctx.nuxt.options.typescript.typeCheck === true || (ctx.nuxt.options.typescript.typeCheck === 'build' && !ctx.nuxt.options.dev)) {
|
if (ctx.nuxt.options.typescript.typeCheck === true || (ctx.nuxt.options.typescript.typeCheck === 'build' && !ctx.nuxt.options.dev)) {
|
||||||
ctx.config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger }))
|
config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ export const DynamicBasePlugin = createUnplugin((options: DynamicBasePluginOptio
|
|||||||
s.append(`${options.globalPublicPath} = buildAssetsURL();\n`)
|
s.append(`${options.globalPublicPath} = buildAssetsURL();\n`)
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
|
map: options.sourcemap
|
||||||
|
? s.generateMap({ source: id, includeContent: true })
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { uniq } from 'lodash-es'
|
|||||||
import fse from 'fs-extra'
|
import fse from 'fs-extra'
|
||||||
|
|
||||||
import type { Nuxt } from '@nuxt/schema'
|
import type { Nuxt } from '@nuxt/schema'
|
||||||
|
import type { Compilation, Compiler } from 'webpack'
|
||||||
import { isJS, isCSS, isHotUpdate } from './util'
|
import { isJS, isCSS, isHotUpdate } from './util'
|
||||||
|
|
||||||
interface PluginOptions {
|
interface PluginOptions {
|
||||||
@ -26,17 +27,17 @@ export default class VueSSRClientPlugin {
|
|||||||
}, options)
|
}, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
apply (compiler) {
|
apply (compiler: Compiler) {
|
||||||
compiler.hooks.afterEmit.tap('VueSSRClientPlugin', async (compilation: any) => {
|
compiler.hooks.afterEmit.tap('VueSSRClientPlugin', async (compilation: Compilation) => {
|
||||||
const stats = compilation.getStats().toJson()
|
const stats = compilation.getStats().toJson()
|
||||||
|
|
||||||
const allFiles = uniq(stats.assets
|
const allFiles = uniq(stats.assets!
|
||||||
.map(a => a.name))
|
.map(a => a.name))
|
||||||
.filter(file => !isHotUpdate(file))
|
.filter(file => !isHotUpdate(file))
|
||||||
|
|
||||||
const initialFiles = uniq(Object.keys(stats.entrypoints)
|
const initialFiles = uniq(Object.keys(stats.entrypoints!)
|
||||||
.map(name => stats.entrypoints[name].assets)
|
.map(name => stats.entrypoints![name].assets!)
|
||||||
.reduce((files, entryAssets) => files.concat(entryAssets.map(entryAsset => entryAsset.name)), [])
|
.reduce((files, entryAssets) => files.concat(entryAssets.map(entryAsset => entryAsset.name)), [] as string[])
|
||||||
.filter(file => isJS(file) || isCSS(file)))
|
.filter(file => isJS(file) || isCSS(file)))
|
||||||
.filter(file => !isHotUpdate(file))
|
.filter(file => !isHotUpdate(file))
|
||||||
|
|
||||||
@ -45,11 +46,11 @@ export default class VueSSRClientPlugin {
|
|||||||
.filter(file => !initialFiles.includes(file))
|
.filter(file => !initialFiles.includes(file))
|
||||||
.filter(file => !isHotUpdate(file))
|
.filter(file => !isHotUpdate(file))
|
||||||
|
|
||||||
const assetsMapping = {}
|
const assetsMapping: Record<string, string[]> = {}
|
||||||
stats.assets
|
stats.assets!
|
||||||
.filter(({ name }) => isJS(name))
|
.filter(({ name }) => isJS(name))
|
||||||
.filter(({ name }) => !isHotUpdate(name))
|
.filter(({ name }) => !isHotUpdate(name))
|
||||||
.forEach(({ name, chunkNames }) => {
|
.forEach(({ name, chunkNames = [] }) => {
|
||||||
const componentHash = hash(chunkNames.join('|'))
|
const componentHash = hash(chunkNames.join('|'))
|
||||||
if (!assetsMapping[componentHash]) {
|
if (!assetsMapping[componentHash]) {
|
||||||
assetsMapping[componentHash] = []
|
assetsMapping[componentHash] = []
|
||||||
@ -62,29 +63,29 @@ export default class VueSSRClientPlugin {
|
|||||||
all: allFiles,
|
all: allFiles,
|
||||||
initial: initialFiles,
|
initial: initialFiles,
|
||||||
async: asyncFiles,
|
async: asyncFiles,
|
||||||
modules: { /* [identifier: string]: Array<index: number> */ },
|
modules: { /* [identifier: string]: Array<index: number> */ } as Record<string, number[]>,
|
||||||
assetsMapping
|
assetsMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
const { entrypoints, namedChunkGroups } = stats
|
const { entrypoints = {}, namedChunkGroups = {} } = stats
|
||||||
const assetModules = stats.modules.filter(m => m.assets.length)
|
const assetModules = stats.modules!.filter(m => m.assets!.length)
|
||||||
const fileToIndex = file => webpackManifest.all.indexOf(file)
|
const fileToIndex = (file: string) => webpackManifest.all.indexOf(file)
|
||||||
stats.modules.forEach((m) => {
|
stats.modules!.forEach((m) => {
|
||||||
// Ignore modules duplicated in multiple chunks
|
// Ignore modules duplicated in multiple chunks
|
||||||
if (m.chunks.length === 1) {
|
if (m.chunks!.length === 1) {
|
||||||
const [cid] = m.chunks
|
const [cid] = m.chunks!
|
||||||
const chunk = stats.chunks.find(c => c.id === cid)
|
const chunk = stats.chunks!.find(c => c.id === cid)
|
||||||
if (!chunk || !chunk.files) {
|
if (!chunk || !chunk.files) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const id = m.identifier.replace(/\s\w+$/, '') // remove appended hash
|
const id = m.identifier!.replace(/\s\w+$/, '') // remove appended hash
|
||||||
const filesSet = new Set(chunk.files.map(fileToIndex).filter(i => i !== -1))
|
const filesSet = new Set(chunk.files.map(fileToIndex).filter(i => i !== -1))
|
||||||
|
|
||||||
for (const chunkName of chunk.names) {
|
for (const chunkName of chunk.names!) {
|
||||||
if (!entrypoints[chunkName]) {
|
if (!entrypoints[chunkName]) {
|
||||||
const chunkGroup = namedChunkGroups[chunkName]
|
const chunkGroup = namedChunkGroups[chunkName]
|
||||||
if (chunkGroup) {
|
if (chunkGroup) {
|
||||||
for (const asset of chunkGroup.assets) {
|
for (const asset of chunkGroup.assets!) {
|
||||||
filesSet.add(fileToIndex(asset.name))
|
filesSet.add(fileToIndex(asset.name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +99,7 @@ export default class VueSSRClientPlugin {
|
|||||||
// Include ConcatenatedModule for not losing module-component mapping
|
// Include ConcatenatedModule for not losing module-component mapping
|
||||||
if (Array.isArray(m.modules)) {
|
if (Array.isArray(m.modules)) {
|
||||||
for (const concatenatedModule of m.modules) {
|
for (const concatenatedModule of m.modules) {
|
||||||
const id = hash(concatenatedModule.identifier.replace(/\s\w+$/, ''))
|
const id = hash(concatenatedModule.identifier!.replace(/\s\w+$/, ''))
|
||||||
if (!webpackManifest.modules[id]) {
|
if (!webpackManifest.modules[id]) {
|
||||||
webpackManifest.modules[id] = files
|
webpackManifest.modules[id] = files
|
||||||
}
|
}
|
||||||
@ -107,14 +108,14 @@ export default class VueSSRClientPlugin {
|
|||||||
|
|
||||||
// Find all asset modules associated with the same chunk
|
// Find all asset modules associated with the same chunk
|
||||||
assetModules.forEach((m) => {
|
assetModules.forEach((m) => {
|
||||||
if (m.chunks.includes(cid)) {
|
if (m.chunks!.includes(cid)) {
|
||||||
files.push.apply(files, m.assets.map(fileToIndex))
|
files.push.apply(files, (m.assets as string[]).map(fileToIndex))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const manifest = normalizeWebpackManifest(webpackManifest)
|
const manifest = normalizeWebpackManifest(webpackManifest as any)
|
||||||
await this.options.nuxt.callHook('build:manifest', manifest)
|
await this.options.nuxt.callHook('build:manifest', manifest)
|
||||||
|
|
||||||
const src = JSON.stringify(manifest, null, 2)
|
const src = JSON.stringify(manifest, null, 2)
|
||||||
|
@ -1,35 +1,36 @@
|
|||||||
|
import webpack, { Compilation, Compiler } from 'webpack'
|
||||||
import webpack from 'webpack'
|
|
||||||
import { validate, isJS, extractQueryPartJS } from './util'
|
import { validate, isJS, extractQueryPartJS } from './util'
|
||||||
|
|
||||||
export default class VueSSRServerPlugin {
|
export interface VueSSRServerPluginOptions {
|
||||||
options: {
|
filename: string
|
||||||
filename?: string
|
}
|
||||||
}
|
|
||||||
|
|
||||||
constructor (options = {}) {
|
export default class VueSSRServerPlugin {
|
||||||
|
options: VueSSRServerPluginOptions
|
||||||
|
|
||||||
|
constructor (options: Partial<VueSSRServerPluginOptions> = {}) {
|
||||||
this.options = Object.assign({
|
this.options = Object.assign({
|
||||||
filename: null
|
filename: null
|
||||||
}, options)
|
}, options) as VueSSRServerPluginOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
apply (compiler) {
|
apply (compiler: Compiler) {
|
||||||
validate(compiler)
|
validate(compiler)
|
||||||
compiler.hooks.make.tap('VueSSRServerPlugin', (compilation: any) => {
|
compiler.hooks.make.tap('VueSSRServerPlugin', (compilation: Compilation) => {
|
||||||
compilation.hooks.processAssets.tapAsync({
|
compilation.hooks.processAssets.tapAsync({
|
||||||
name: 'VueSSRServerPlugin',
|
name: 'VueSSRServerPlugin',
|
||||||
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
|
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
|
||||||
}, (assets, cb) => {
|
}, (assets: any, cb: any) => {
|
||||||
const stats = compilation.getStats().toJson()
|
const stats = compilation.getStats().toJson()
|
||||||
const [entryName] = Object.keys(stats.entrypoints)
|
const [entryName] = Object.keys(stats.entrypoints!)
|
||||||
const entryInfo = stats.entrypoints[entryName]
|
const entryInfo = stats.entrypoints![entryName]
|
||||||
|
|
||||||
if (!entryInfo) {
|
if (!entryInfo) {
|
||||||
// #5553
|
// #5553
|
||||||
return cb()
|
return cb()
|
||||||
}
|
}
|
||||||
|
|
||||||
const entryAssets = entryInfo.assets.filter(asset => isJS(asset.name))
|
const entryAssets = entryInfo.assets!.filter((asset: { name:string }) => isJS(asset.name))
|
||||||
|
|
||||||
if (entryAssets.length > 1) {
|
if (entryAssets.length > 1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -47,11 +48,11 @@ export default class VueSSRServerPlugin {
|
|||||||
|
|
||||||
const bundle = {
|
const bundle = {
|
||||||
entry: entry.name,
|
entry: entry.name,
|
||||||
files: {},
|
files: {} as Record<string, string>,
|
||||||
maps: {}
|
maps: {} as Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.assets.forEach((asset) => {
|
stats.assets!.forEach((asset: any) => {
|
||||||
if (isJS(asset.name)) {
|
if (isJS(asset.name)) {
|
||||||
const queryPart = extractQueryPartJS(asset.name)
|
const queryPart = extractQueryPartJS(asset.name)
|
||||||
if (queryPart !== undefined) {
|
if (queryPart !== undefined) {
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { logger } from '@nuxt/kit'
|
import { logger } from '@nuxt/kit'
|
||||||
|
import type { Compiler } from 'webpack'
|
||||||
|
|
||||||
export const validate = (compiler) => {
|
export const validate = (compiler: Compiler) => {
|
||||||
if (compiler.options.target !== 'node') {
|
if (compiler.options.target !== 'node') {
|
||||||
logger.warn('webpack config `target` should be "node".')
|
logger.warn('webpack config `target` should be "node".')
|
||||||
}
|
}
|
||||||
@ -20,10 +21,10 @@ export const validate = (compiler) => {
|
|||||||
|
|
||||||
const isJSRegExp = /\.[cm]?js(\?[^.]+)?$/
|
const isJSRegExp = /\.[cm]?js(\?[^.]+)?$/
|
||||||
|
|
||||||
export const isJS = file => isJSRegExp.test(file)
|
export const isJS = (file: string) => isJSRegExp.test(file)
|
||||||
|
|
||||||
export const extractQueryPartJS = file => isJSRegExp.exec(file)[1]
|
export const extractQueryPartJS = (file: string) => isJSRegExp.exec(file)?.[1]
|
||||||
|
|
||||||
export const isCSS = file => /\.css(\?[^.]+)?$/.test(file)
|
export const isCSS = (file: string) => /\.css(\?[^.]+)?$/.test(file)
|
||||||
|
|
||||||
export const isHotUpdate = file => file.includes('hot-update')
|
export const isHotUpdate = (file: string) => file.includes('hot-update')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { fileName, WebpackConfigContext } from '../utils/config'
|
import { fileName, WebpackConfigContext } from '../utils/config'
|
||||||
|
|
||||||
export function assets (ctx: WebpackConfigContext) {
|
export function assets (ctx: WebpackConfigContext) {
|
||||||
ctx.config.module.rules.push(
|
ctx.config.module!.rules!.push(
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|svg|webp)$/i,
|
test: /\.(png|jpe?g|gif|svg|webp)$/i,
|
||||||
use: [{
|
use: [{
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { resolve, normalize } from 'pathe'
|
import { resolve, normalize } from 'pathe'
|
||||||
|
// @ts-expect-error missing types
|
||||||
import TimeFixPlugin from 'time-fix-plugin'
|
import TimeFixPlugin from 'time-fix-plugin'
|
||||||
import WebpackBar from 'webpackbar'
|
import WebpackBar from 'webpackbar'
|
||||||
import webpack from 'webpack'
|
import webpack from 'webpack'
|
||||||
import { logger } from '@nuxt/kit'
|
import { logger } from '@nuxt/kit'
|
||||||
|
// @ts-expect-error missing types
|
||||||
import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin'
|
import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin'
|
||||||
import escapeRegExp from 'escape-string-regexp'
|
import escapeRegExp from 'escape-string-regexp'
|
||||||
import { joinURL } from 'ufo'
|
import { joinURL } from 'ufo'
|
||||||
@ -44,6 +46,8 @@ function baseConfig (ctx: WebpackConfigContext) {
|
|||||||
function basePlugins (ctx: WebpackConfigContext) {
|
function basePlugins (ctx: WebpackConfigContext) {
|
||||||
const { config, options, nuxt } = ctx
|
const { config, options, nuxt } = ctx
|
||||||
|
|
||||||
|
config.plugins = config.plugins || []
|
||||||
|
|
||||||
// Add timefix-plugin before other plugins
|
// Add timefix-plugin before other plugins
|
||||||
if (options.dev) {
|
if (options.dev) {
|
||||||
config.plugins.push(new TimeFixPlugin())
|
config.plugins.push(new TimeFixPlugin())
|
||||||
@ -63,7 +67,7 @@ function basePlugins (ctx: WebpackConfigContext) {
|
|||||||
ctx.isServer ||
|
ctx.isServer ||
|
||||||
(ctx.isDev && !options.build.quiet && options.webpack.friendlyErrors)
|
(ctx.isDev && !options.build.quiet && options.webpack.friendlyErrors)
|
||||||
) {
|
) {
|
||||||
ctx.config.plugins.push(
|
config.plugins.push(
|
||||||
new FriendlyErrorsWebpackPlugin({
|
new FriendlyErrorsWebpackPlugin({
|
||||||
clearConsole: false,
|
clearConsole: false,
|
||||||
reporter: 'consola',
|
reporter: 'consola',
|
||||||
@ -81,16 +85,17 @@ function basePlugins (ctx: WebpackConfigContext) {
|
|||||||
}
|
}
|
||||||
config.plugins.push(new WebpackBar({
|
config.plugins.push(new WebpackBar({
|
||||||
name: ctx.name,
|
name: ctx.name,
|
||||||
color: colors[ctx.name],
|
color: colors[ctx.name as keyof typeof colors],
|
||||||
reporters: ['stats'],
|
reporters: ['stats'],
|
||||||
stats: !ctx.isDev,
|
stats: !ctx.isDev,
|
||||||
reporter: {
|
reporter: {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
change: (_, { shortPath }) => {
|
change: (_, { shortPath }) => {
|
||||||
if (!ctx.isServer) {
|
if (!ctx.isServer) {
|
||||||
nuxt.callHook('bundler:change', shortPath)
|
nuxt.callHook('bundler:change', shortPath)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// @ts-ignore
|
||||||
done: ({ state }) => {
|
done: ({ state }) => {
|
||||||
if (state.hasErrors) {
|
if (state.hasErrors) {
|
||||||
nuxt.callHook('bundler:error')
|
nuxt.callHook('bundler:error')
|
||||||
@ -101,6 +106,7 @@ function basePlugins (ctx: WebpackConfigContext) {
|
|||||||
allDone: () => {
|
allDone: () => {
|
||||||
nuxt.callHook('bundler:done')
|
nuxt.callHook('bundler:done')
|
||||||
},
|
},
|
||||||
|
// @ts-ignore
|
||||||
progress ({ statesArray }) {
|
progress ({ statesArray }) {
|
||||||
nuxt.callHook('bundler:progress', statesArray)
|
nuxt.callHook('bundler:progress', statesArray)
|
||||||
}
|
}
|
||||||
@ -220,7 +226,7 @@ function getWarningIgnoreFilter (ctx: WebpackConfigContext): WarningFilter {
|
|||||||
function getEnv (ctx: WebpackConfigContext) {
|
function getEnv (ctx: WebpackConfigContext) {
|
||||||
const { options } = ctx
|
const { options } = ctx
|
||||||
|
|
||||||
const _env = {
|
const _env: Record<string, string | boolean> = {
|
||||||
'process.env.NODE_ENV': JSON.stringify(ctx.config.mode),
|
'process.env.NODE_ENV': JSON.stringify(ctx.config.mode),
|
||||||
'process.mode': JSON.stringify(ctx.config.mode),
|
'process.mode': JSON.stringify(ctx.config.mode),
|
||||||
'process.dev': options.dev,
|
'process.dev': options.dev,
|
||||||
@ -239,7 +245,7 @@ function getEnv (ctx: WebpackConfigContext) {
|
|||||||
|
|
||||||
Object.entries(options.env).forEach(([key, value]) => {
|
Object.entries(options.env).forEach(([key, value]) => {
|
||||||
const isNative = ['boolean', 'number'].includes(typeof value)
|
const isNative = ['boolean', 'number'].includes(typeof value)
|
||||||
_env['process.env.' + key] = isNative ? value : JSON.stringify(value)
|
_env['process.env.' + key] = isNative ? value as string : JSON.stringify(value)
|
||||||
})
|
})
|
||||||
|
|
||||||
return _env
|
return _env
|
||||||
|
@ -10,9 +10,9 @@ export function esbuild (ctx: WebpackConfigContext) {
|
|||||||
const target = ctx.isServer ? 'es2019' : 'chrome85'
|
const target = ctx.isServer ? 'es2019' : 'chrome85'
|
||||||
|
|
||||||
// https://github.com/nuxt/framework/issues/2372
|
// https://github.com/nuxt/framework/issues/2372
|
||||||
config.optimization.minimizer.push(new (esbuildLoader as unknown as typeof import('esbuild-loader')).ESBuildMinifyPlugin())
|
config.optimization!.minimizer!.push(new (esbuildLoader as unknown as typeof import('esbuild-loader')).ESBuildMinifyPlugin())
|
||||||
|
|
||||||
config.module.rules.push(
|
config.module!.rules!.push(
|
||||||
{
|
{
|
||||||
test: /\.m?[jt]s$/i,
|
test: /\.m?[jt]s$/i,
|
||||||
loader: 'esbuild-loader',
|
loader: 'esbuild-loader',
|
||||||
|
@ -6,7 +6,7 @@ export function node (ctx: WebpackConfigContext) {
|
|||||||
config.target = 'node'
|
config.target = 'node'
|
||||||
config.node = false
|
config.node = false
|
||||||
|
|
||||||
config.experiments.outputModule = true
|
config.experiments!.outputModule = true
|
||||||
|
|
||||||
config.output = {
|
config.output = {
|
||||||
...config.output,
|
...config.output,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { WebpackConfigContext } from '../utils/config'
|
import { WebpackConfigContext } from '../utils/config'
|
||||||
|
|
||||||
export function pug (ctx: WebpackConfigContext) {
|
export function pug (ctx: WebpackConfigContext) {
|
||||||
ctx.config.module.rules.push({
|
ctx.config.module!.rules!.push({
|
||||||
test: /\.pug$/i,
|
test: /\.pug$/i,
|
||||||
oneOf: [
|
oneOf: [
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,8 @@ export function style (ctx: WebpackConfigContext) {
|
|||||||
function minimizer (ctx: WebpackConfigContext) {
|
function minimizer (ctx: WebpackConfigContext) {
|
||||||
const { options, config } = ctx
|
const { options, config } = ctx
|
||||||
|
|
||||||
if (options.webpack.optimizeCSS && Array.isArray(config.optimization.minimizer)) {
|
if (options.webpack.optimizeCSS && Array.isArray(config.optimization!.minimizer)) {
|
||||||
config.optimization.minimizer.push(new CssMinimizerPlugin({
|
config.optimization!.minimizer.push(new CssMinimizerPlugin({
|
||||||
...options.webpack.optimizeCSS
|
...options.webpack.optimizeCSS
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ function extractCSS (ctx: WebpackConfigContext) {
|
|||||||
|
|
||||||
// CSS extraction
|
// CSS extraction
|
||||||
if (options.webpack.extractCSS) {
|
if (options.webpack.extractCSS) {
|
||||||
config.plugins.push(new MiniCssExtractPlugin({
|
config.plugins!.push(new MiniCssExtractPlugin({
|
||||||
filename: fileName(ctx, 'css'),
|
filename: fileName(ctx, 'css'),
|
||||||
chunkFilename: fileName(ctx, 'css'),
|
chunkFilename: fileName(ctx, 'css'),
|
||||||
...options.webpack.extractCSS === true ? {} : options.webpack.extractCSS
|
...options.webpack.extractCSS === true ? {} : options.webpack.extractCSS
|
||||||
@ -38,28 +38,28 @@ function loaders (ctx: WebpackConfigContext) {
|
|||||||
const { config, options } = ctx
|
const { config, options } = ctx
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
config.module.rules.push(createdStyleRule('css', /\.css$/i, null, ctx))
|
config.module!.rules!.push(createdStyleRule('css', /\.css$/i, null, ctx))
|
||||||
|
|
||||||
// Postcss
|
// Postcss
|
||||||
config.module.rules.push(createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx))
|
config.module!.rules!.push(createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx))
|
||||||
|
|
||||||
// Less
|
// Less
|
||||||
const lessLoader = { loader: 'less-loader', options: options.webpack.loaders.less }
|
const lessLoader = { loader: 'less-loader', options: options.webpack.loaders.less }
|
||||||
config.module.rules.push(createdStyleRule('less', /\.less$/i, lessLoader, ctx))
|
config.module!.rules!.push(createdStyleRule('less', /\.less$/i, lessLoader, ctx))
|
||||||
|
|
||||||
// Sass (TODO: optional dependency)
|
// Sass (TODO: optional dependency)
|
||||||
const sassLoader = { loader: 'sass-loader', options: options.webpack.loaders.sass }
|
const sassLoader = { loader: 'sass-loader', options: options.webpack.loaders.sass }
|
||||||
config.module.rules.push(createdStyleRule('sass', /\.sass$/i, sassLoader, ctx))
|
config.module!.rules!.push(createdStyleRule('sass', /\.sass$/i, sassLoader, ctx))
|
||||||
|
|
||||||
const scssLoader = { loader: 'sass-loader', options: options.webpack.loaders.scss }
|
const scssLoader = { loader: 'sass-loader', options: options.webpack.loaders.scss }
|
||||||
config.module.rules.push(createdStyleRule('scss', /\.scss$/i, scssLoader, ctx))
|
config.module!.rules!.push(createdStyleRule('scss', /\.scss$/i, scssLoader, ctx))
|
||||||
|
|
||||||
// Stylus
|
// Stylus
|
||||||
const stylusLoader = { loader: 'stylus-loader', options: options.webpack.loaders.stylus }
|
const stylusLoader = { loader: 'stylus-loader', options: options.webpack.loaders.stylus }
|
||||||
config.module.rules.push(createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx))
|
config.module!.rules!.push(createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
function createdStyleRule (lang: string, test: RegExp, processorLoader, ctx: WebpackConfigContext) {
|
function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx: WebpackConfigContext) {
|
||||||
const { options } = ctx
|
const { options } = ctx
|
||||||
|
|
||||||
const styleLoaders = [
|
const styleLoaders = [
|
||||||
@ -90,7 +90,7 @@ function createdStyleRule (lang: string, test: RegExp, processorLoader, ctx: Web
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions) {
|
function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions: any) {
|
||||||
const { options } = ctx
|
const { options } = ctx
|
||||||
|
|
||||||
const cssLoader = { loader: 'css-loader', options: cssLoaderOptions }
|
const cssLoader = { loader: 'css-loader', options: cssLoaderOptions }
|
||||||
|
@ -11,7 +11,7 @@ export function vue (ctx: WebpackConfigContext) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
config.plugins.push(new (VueLoaderPlugin.default || VueLoaderPlugin)())
|
config.plugins.push(new (VueLoaderPlugin.default || VueLoaderPlugin)())
|
||||||
|
|
||||||
config.module.rules.push({
|
config.module!.rules!.push({
|
||||||
test: /\.vue$/i,
|
test: /\.vue$/i,
|
||||||
loader: 'vue-loader',
|
loader: 'vue-loader',
|
||||||
options: {
|
options: {
|
||||||
@ -21,12 +21,12 @@ export function vue (ctx: WebpackConfigContext) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (ctx.isClient) {
|
if (ctx.isClient) {
|
||||||
config.plugins.push(new VueSSRClientPlugin({
|
config.plugins!.push(new VueSSRClientPlugin({
|
||||||
filename: resolve(options.buildDir, 'dist/server', `${ctx.name}.manifest.json`),
|
filename: resolve(options.buildDir, 'dist/server', `${ctx.name}.manifest.json`),
|
||||||
nuxt: ctx.nuxt
|
nuxt: ctx.nuxt
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
config.plugins.push(new VueSSRServerPlugin({
|
config.plugins!.push(new VueSSRServerPlugin({
|
||||||
filename: `${ctx.name}.manifest.json`
|
filename: `${ctx.name}.manifest.json`
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export function vue (ctx: WebpackConfigContext) {
|
|||||||
// Feature flags
|
// Feature flags
|
||||||
// https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
|
// https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
|
||||||
// TODO: Provide options to toggle
|
// TODO: Provide options to toggle
|
||||||
config.plugins.push(new webpack.DefinePlugin({
|
config.plugins!.push(new webpack.DefinePlugin({
|
||||||
__VUE_OPTIONS_API__: 'true',
|
__VUE_OPTIONS_API__: 'true',
|
||||||
__VUE_PROD_DEVTOOLS__: 'false'
|
__VUE_PROD_DEVTOOLS__: 'false'
|
||||||
}))
|
}))
|
||||||
|
@ -19,7 +19,7 @@ export function createWebpackConfigContext (nuxt: Nuxt) {
|
|||||||
isServer: false,
|
isServer: false,
|
||||||
isClient: false,
|
isClient: false,
|
||||||
|
|
||||||
alias: {} as Configuration['resolve']['alias'],
|
alias: {} as { [index: string]: string | false | string[] },
|
||||||
transpile: [] as RegExp[]
|
transpile: [] as RegExp[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ export function applyPresets (ctx: WebpackConfigContext, presets: WebpackConfigP
|
|||||||
export function fileName (ctx: WebpackConfigContext, key: string) {
|
export function fileName (ctx: WebpackConfigContext, key: string) {
|
||||||
const { options } = ctx
|
const { options } = ctx
|
||||||
|
|
||||||
let fileName = options.webpack.filenames[key]
|
let fileName = options.webpack.filenames[key as keyof typeof options.webpack.filenames] as ((ctx: WebpackConfigContext) => string) | string
|
||||||
|
|
||||||
if (typeof fileName === 'function') {
|
if (typeof fileName === 'function') {
|
||||||
fileName = fileName(ctx)
|
fileName = fileName(ctx)
|
||||||
@ -61,7 +61,7 @@ export function getWebpackConfig (ctx: WebpackConfigContext): Configuration {
|
|||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
const builder = {}
|
const builder = {}
|
||||||
const loaders = []
|
const loaders: any[] = []
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { extend } = options.build
|
const { extend } = options.build
|
||||||
|
@ -9,7 +9,7 @@ export function createMFS () {
|
|||||||
const fs = createFsFromVolume(new Volume())
|
const fs = createFsFromVolume(new Volume())
|
||||||
|
|
||||||
// Clone to extend
|
// Clone to extend
|
||||||
const _fs: Partial<IFs> & { join?(...paths: string[]): string } = { ...fs }
|
const _fs: IFs & { join?(...paths: string[]): string } = { ...fs } as any
|
||||||
|
|
||||||
// fs.join method is (still) expected by webpack-dev-middleware
|
// fs.join method is (still) expected by webpack-dev-middleware
|
||||||
// There might be differences with https://github.com/webpack/memory-fs/blob/master/lib/join.js
|
// There might be differences with https://github.com/webpack/memory-fs/blob/master/lib/join.js
|
||||||
|
@ -35,20 +35,20 @@ export const getPostcssConfig = (nuxt: Nuxt) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortPlugins ({ plugins, order }) {
|
function sortPlugins ({ plugins, order }: any) {
|
||||||
const names = Object.keys(plugins)
|
const names = Object.keys(plugins)
|
||||||
if (typeof order === 'string') {
|
if (typeof order === 'string') {
|
||||||
order = orderPresets[order]
|
order = orderPresets[order as keyof typeof orderPresets]
|
||||||
}
|
}
|
||||||
return typeof order === 'function' ? order(names, orderPresets) : (order || names)
|
return typeof order === 'function' ? order(names, orderPresets) : (order || names)
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPlugins (config) {
|
function loadPlugins (config: any) {
|
||||||
if (!isPureObject(config.plugins)) { return }
|
if (!isPureObject(config.plugins)) { return }
|
||||||
|
|
||||||
// Map postcss plugins into instances on object mode once
|
// Map postcss plugins into instances on object mode once
|
||||||
const cjs = createCommonJS(import.meta.url)
|
const cjs = createCommonJS(import.meta.url)
|
||||||
config.plugins = sortPlugins(config).map((pluginName) => {
|
config.plugins = sortPlugins(config).map((pluginName: string) => {
|
||||||
const pluginFn = requireModule(pluginName, { paths: [cjs.__dirname] })
|
const pluginFn = requireModule(pluginName, { paths: [cjs.__dirname] })
|
||||||
const pluginOptions = config.plugins[pluginName]
|
const pluginOptions = config.plugins[pluginName]
|
||||||
if (!pluginOptions || typeof pluginFn !== 'function') { return null }
|
if (!pluginOptions || typeof pluginFn !== 'function') { return null }
|
||||||
@ -81,9 +81,11 @@ export const getPostcssConfig = (nuxt: Nuxt) => {
|
|||||||
loadPlugins(postcssOptions)
|
loadPlugins(postcssOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
delete nuxt.options.webpack.postcss.order
|
delete nuxt.options.webpack.postcss.order
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// @ts-expect-error
|
||||||
sourceMap: nuxt.options.webpack.cssSourceMap,
|
sourceMap: nuxt.options.webpack.cssSourceMap,
|
||||||
...nuxt.options.webpack.postcss,
|
...nuxt.options.webpack.postcss,
|
||||||
postcssOptions
|
postcssOptions
|
||||||
|
@ -21,6 +21,6 @@ export function registerVirtualModules () {
|
|||||||
|
|
||||||
nuxt.hook('webpack:config', configs => configs.forEach((config) => {
|
nuxt.hook('webpack:config', configs => configs.forEach((config) => {
|
||||||
// Support virtual modules (input)
|
// Support virtual modules (input)
|
||||||
config.plugins.push(virtualModules)
|
config.plugins!.push(virtualModules)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { IncomingMessage, ServerResponse } from 'node:http'
|
import type { IncomingMessage, ServerResponse } from 'node:http'
|
||||||
import pify from 'pify'
|
import pify from 'pify'
|
||||||
import webpack from 'webpack'
|
import webpack from 'webpack'
|
||||||
import webpackDevMiddleware, { API } from 'webpack-dev-middleware'
|
import webpackDevMiddleware, { API, OutputFileSystem } from 'webpack-dev-middleware'
|
||||||
import webpackHotMiddleware from 'webpack-hot-middleware'
|
import webpackHotMiddleware from 'webpack-hot-middleware'
|
||||||
import type { Compiler, Watching } from 'webpack'
|
import type { Compiler, Watching } from 'webpack'
|
||||||
|
|
||||||
@ -34,10 +34,10 @@ export async function bundle (nuxt: Nuxt) {
|
|||||||
|
|
||||||
// Configure compilers
|
// Configure compilers
|
||||||
const compilers = webpackConfigs.map((config) => {
|
const compilers = webpackConfigs.map((config) => {
|
||||||
config.plugins.push(DynamicBasePlugin.webpack({
|
config.plugins!.push(DynamicBasePlugin.webpack({
|
||||||
sourcemap: nuxt.options.sourcemap
|
sourcemap: nuxt.options.sourcemap
|
||||||
}))
|
}))
|
||||||
config.plugins.push(composableKeysPlugin.webpack({
|
config.plugins!.push(composableKeysPlugin.webpack({
|
||||||
sourcemap: nuxt.options.sourcemap,
|
sourcemap: nuxt.options.sourcemap,
|
||||||
rootDir: nuxt.options.rootDir
|
rootDir: nuxt.options.rootDir
|
||||||
}))
|
}))
|
||||||
@ -47,7 +47,7 @@ export async function bundle (nuxt: Nuxt) {
|
|||||||
|
|
||||||
// In dev, write files in memory FS
|
// In dev, write files in memory FS
|
||||||
if (nuxt.options.dev) {
|
if (nuxt.options.dev) {
|
||||||
compiler.outputFileSystem = mfs
|
compiler.outputFileSystem = mfs as unknown as OutputFileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiler
|
return compiler
|
||||||
@ -88,7 +88,7 @@ async function createDevMiddleware (compiler: Compiler) {
|
|||||||
const hotMiddleware = pify(webpackHotMiddleware(compiler, {
|
const hotMiddleware = pify(webpackHotMiddleware(compiler, {
|
||||||
log: false,
|
log: false,
|
||||||
heartbeat: 10000,
|
heartbeat: 10000,
|
||||||
path: joinURL(nuxt.options.app.baseURL, '__webpack_hmr', compiler.options.name),
|
path: joinURL(nuxt.options.app.baseURL, '__webpack_hmr', compiler.options.name!),
|
||||||
...hotMiddlewareOptions
|
...hotMiddlewareOptions
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -96,9 +96,9 @@ async function createDevMiddleware (compiler: Compiler) {
|
|||||||
await nuxt.callHook('webpack:hotMiddleware', hotMiddleware)
|
await nuxt.callHook('webpack:hotMiddleware', hotMiddleware)
|
||||||
|
|
||||||
// Register devMiddleware on server
|
// Register devMiddleware on server
|
||||||
await nuxt.callHook('server:devMiddleware', async (req, res, next) => {
|
await nuxt.callHook('server:devMiddleware', async (req: IncomingMessage, res: ServerResponse, next: (error?: any) => void) => {
|
||||||
for (const mw of [devMiddleware, hotMiddleware]) {
|
for (const mw of [devMiddleware, hotMiddleware]) {
|
||||||
await mw?.(req, res)
|
await mw?.(req, res, next)
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
@ -111,11 +111,11 @@ async function compile (compiler: Compiler) {
|
|||||||
|
|
||||||
const { name } = compiler.options
|
const { name } = compiler.options
|
||||||
|
|
||||||
await nuxt.callHook('build:compile', { name, compiler })
|
await nuxt.callHook('build:compile', { name: name!, compiler })
|
||||||
|
|
||||||
// Load renderer resources after build
|
// Load renderer resources after build
|
||||||
compiler.hooks.done.tap('load-resources', async (stats) => {
|
compiler.hooks.done.tap('load-resources', async (stats) => {
|
||||||
await nuxt.callHook('build:compiled', { name, compiler, stats })
|
await nuxt.callHook('build:compiled', { name: name!, compiler, stats })
|
||||||
// Reload renderer
|
// Reload renderer
|
||||||
await nuxt.callHook('build:resources', compiler.outputFileSystem)
|
await nuxt.callHook('build:resources', compiler.outputFileSystem)
|
||||||
})
|
})
|
||||||
@ -152,7 +152,7 @@ async function compile (compiler: Compiler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Production Build ---
|
// --- Production Build ---
|
||||||
const stats = await new Promise<webpack.Stats>((resolve, reject) => compiler.run((err, stats) => err ? reject(err) : resolve(stats)))
|
const stats = await new Promise<webpack.Stats>((resolve, reject) => compiler.run((err, stats) => err ? reject(err) : resolve(stats!)))
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
if (stats.hasErrors()) {
|
||||||
// non-quiet mode: errors will be printed by webpack itself
|
// non-quiet mode: errors will be printed by webpack itself
|
||||||
|
@ -3,16 +3,22 @@ import { execSync } from 'node:child_process'
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { globby } from 'globby'
|
import { globby } from 'globby'
|
||||||
|
|
||||||
|
interface Dep {
|
||||||
|
name: string,
|
||||||
|
range: string,
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
async function loadPackage (dir: string) {
|
async function loadPackage (dir: string) {
|
||||||
const pkgPath = resolve(dir, 'package.json')
|
const pkgPath = resolve(dir, 'package.json')
|
||||||
const data = JSON.parse(await fsp.readFile(pkgPath, 'utf-8').catch(() => '{}'))
|
const data = JSON.parse(await fsp.readFile(pkgPath, 'utf-8').catch(() => '{}'))
|
||||||
const save = () => fsp.writeFile(pkgPath, JSON.stringify(data, null, 2) + '\n')
|
const save = () => fsp.writeFile(pkgPath, JSON.stringify(data, null, 2) + '\n')
|
||||||
|
|
||||||
const updateDeps = (reviver: Function) => {
|
const updateDeps = (reviver: (dep: Dep) => Dep | void) => {
|
||||||
for (const type of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {
|
for (const type of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {
|
||||||
if (!data[type]) { continue }
|
if (!data[type]) { continue }
|
||||||
for (const e of Object.entries(data[type])) {
|
for (const e of Object.entries(data[type])) {
|
||||||
const dep = { name: e[0], range: e[1], type }
|
const dep: Dep = { name: e[0], range: e[1] as string, type }
|
||||||
delete data[type][dep.name]
|
delete data[type][dep.name]
|
||||||
const updated = reviver(dep) || dep
|
const updated = reviver(dep) || dep
|
||||||
data[updated.type] = data[updated.type] || {}
|
data[updated.type] = data[updated.type] || {}
|
||||||
|
@ -350,7 +350,7 @@ describe('extends support', () => {
|
|||||||
describe('app', () => {
|
describe('app', () => {
|
||||||
it('extends foo/app/router.options & bar/app/router.options', async () => {
|
it('extends foo/app/router.options & bar/app/router.options', async () => {
|
||||||
const html: string = await $fetch('/')
|
const html: string = await $fetch('/')
|
||||||
const routerLinkClasses = html.match(/href="\/" class="([^"]*)"/)[1].split(' ')
|
const routerLinkClasses = html.match(/href="\/" class="([^"]*)"/)?.[1].split(' ')
|
||||||
expect(routerLinkClasses).toContain('foo-active-class')
|
expect(routerLinkClasses).toContain('foo-active-class')
|
||||||
expect(routerLinkClasses).toContain('bar-exact-active-class')
|
expect(routerLinkClasses).toContain('bar-exact-active-class')
|
||||||
})
|
})
|
||||||
@ -404,7 +404,7 @@ describe('dynamic paths', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it('should work with no overrides', async () => {
|
it('should work with no overrides', async () => {
|
||||||
const html = await $fetch('/assets')
|
const html: string = await $fetch('/assets')
|
||||||
for (const match of html.matchAll(/(href|src)="(.*?)"/g)) {
|
for (const match of html.matchAll(/(href|src)="(.*?)"/g)) {
|
||||||
const url = match[2]
|
const url = match[2]
|
||||||
expect(url.startsWith('/_nuxt/') || url === '/public.svg').toBeTruthy()
|
expect(url.startsWith('/_nuxt/') || url === '/public.svg').toBeTruthy()
|
||||||
@ -417,11 +417,11 @@ describe('dynamic paths', () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const html = await $fetch('/assets')
|
const html: string = await $fetch('/assets')
|
||||||
const urls = Array.from(html.matchAll(/(href|src)="(.*?)"/g)).map(m => m[2])
|
const urls = Array.from(html.matchAll(/(href|src)="(.*?)"/g)).map(m => m[2])
|
||||||
const cssURL = urls.find(u => /_nuxt\/assets.*\.css$/.test(u))
|
const cssURL = urls.find(u => /_nuxt\/assets.*\.css$/.test(u))
|
||||||
expect(cssURL).toBeDefined()
|
expect(cssURL).toBeDefined()
|
||||||
const css = await $fetch(cssURL)
|
const css: string = await $fetch(cssURL!)
|
||||||
const imageUrls = Array.from(css.matchAll(/url\(([^)]*)\)/g)).map(m => m[1].replace(/[-.][\w]{8}\./g, '.'))
|
const imageUrls = Array.from(css.matchAll(/url\(([^)]*)\)/g)).map(m => m[1].replace(/[-.][\w]{8}\./g, '.'))
|
||||||
expect(imageUrls).toMatchInlineSnapshot(`
|
expect(imageUrls).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
|
@ -4,13 +4,13 @@ import { expect } from 'vitest'
|
|||||||
export async function renderPage (path = '/') {
|
export async function renderPage (path = '/') {
|
||||||
const ctx = useTestContext()
|
const ctx = useTestContext()
|
||||||
if (!ctx.options.browser) {
|
if (!ctx.options.browser) {
|
||||||
return
|
throw new Error('`renderPage` require `options.browser` to be set')
|
||||||
}
|
}
|
||||||
|
|
||||||
const browser = await getBrowser()
|
const browser = await getBrowser()
|
||||||
const page = await browser.newPage({})
|
const page = await browser.newPage({})
|
||||||
const pageErrors = []
|
const pageErrors: Error[] = []
|
||||||
const consoleLogs = []
|
const consoleLogs: { type:string, text:string }[] = []
|
||||||
|
|
||||||
page.on('console', (message) => {
|
page.on('console', (message) => {
|
||||||
consoleLogs.push({
|
consoleLogs.push({
|
||||||
@ -39,7 +39,7 @@ export async function expectNoClientErrors (path: string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const { pageErrors, consoleLogs } = await renderPage(path)
|
const { pageErrors, consoleLogs } = (await renderPage(path))!
|
||||||
|
|
||||||
const consoleLogErrors = consoleLogs.filter(i => i.type === 'error')
|
const consoleLogErrors = consoleLogs.filter(i => i.type === 'error')
|
||||||
const consoleLogWarnings = consoleLogs.filter(i => i.type === 'warning')
|
const consoleLogWarnings = consoleLogs.filter(i => i.type === 'warning')
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"strict": false,
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
@ -33,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"**/*/dist/*",
|
"**/dist/**",
|
||||||
"**/.nuxt/**",
|
"**/.nuxt/**",
|
||||||
"**/nuxt.d.ts",
|
"**/nuxt.d.ts",
|
||||||
"**/examples/**",
|
"**/examples/**",
|
||||||
|
37
yarn.lock
37
yarn.lock
@ -327,7 +327,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/standalone@npm:^7.18.11":
|
"@babel/standalone@npm:^7.18.11, @babel/standalone@npm:^7.18.13":
|
||||||
version: 7.18.13
|
version: 7.18.13
|
||||||
resolution: "@babel/standalone@npm:7.18.13"
|
resolution: "@babel/standalone@npm:7.18.13"
|
||||||
checksum: da010b1ef0d53f7888d01b3ef93aac9a17af5711979e7bc048b80bf08ae6dfa6b637bf92fee0c5753b4ff1bc3639a5b82925f9234d4e2150fc6d4d5c2ccc1f89
|
checksum: da010b1ef0d53f7888d01b3ef93aac9a17af5711979e7bc048b80bf08ae6dfa6b637bf92fee0c5753b4ff1bc3639a5b82925f9234d4e2150fc6d4d5c2ccc1f89
|
||||||
@ -1661,7 +1661,7 @@ __metadata:
|
|||||||
unbuild: latest
|
unbuild: latest
|
||||||
unctx: ^2.0.1
|
unctx: ^2.0.1
|
||||||
unimport: ^0.6.7
|
unimport: ^0.6.7
|
||||||
untyped: ^0.4.5
|
untyped: ^0.4.7
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -1688,6 +1688,7 @@ __metadata:
|
|||||||
ufo: ^0.8.5
|
ufo: ^0.8.5
|
||||||
unbuild: latest
|
unbuild: latest
|
||||||
unimport: ^0.6.7
|
unimport: ^0.6.7
|
||||||
|
untyped: ^0.4.7
|
||||||
vite: ~3.0.9
|
vite: ~3.0.9
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@ -1825,6 +1826,7 @@ __metadata:
|
|||||||
"@nuxt/friendly-errors-webpack-plugin": ^2.5.2
|
"@nuxt/friendly-errors-webpack-plugin": ^2.5.2
|
||||||
"@nuxt/kit": 3.0.0-rc.8
|
"@nuxt/kit": 3.0.0-rc.8
|
||||||
"@nuxt/schema": 3.0.0-rc.8
|
"@nuxt/schema": 3.0.0-rc.8
|
||||||
|
"@types/lodash-es": ^4.17.6
|
||||||
"@types/pify": ^5.0.1
|
"@types/pify": ^5.0.1
|
||||||
"@types/webpack-bundle-analyzer": ^4.4.2
|
"@types/webpack-bundle-analyzer": ^4.4.2
|
||||||
"@types/webpack-dev-middleware": ^5.0.2
|
"@types/webpack-dev-middleware": ^5.0.2
|
||||||
@ -2280,6 +2282,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/flat@npm:^5.0.2":
|
||||||
|
version: 5.0.2
|
||||||
|
resolution: "@types/flat@npm:5.0.2"
|
||||||
|
checksum: e21d51d872e788bdb381887c2880f717ba4377beb4055078136127134858efd15044655610f1fce4832d9a103ded468a25335203fc53f36db08edd5ab5a8b3db
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/fs-extra@npm:^9.0.13":
|
"@types/fs-extra@npm:^9.0.13":
|
||||||
version: 9.0.13
|
version: 9.0.13
|
||||||
resolution: "@types/fs-extra@npm:9.0.13"
|
resolution: "@types/fs-extra@npm:9.0.13"
|
||||||
@ -2331,6 +2340,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/lodash-es@npm:^4.17.6":
|
||||||
|
version: 4.17.6
|
||||||
|
resolution: "@types/lodash-es@npm:4.17.6"
|
||||||
|
dependencies:
|
||||||
|
"@types/lodash": "*"
|
||||||
|
checksum: 9bd239dd525086e278821949ce12fbdd4f100a060fed9323fc7ad5661113e1641f28a7ebab617230ed3474680d8f4de705c1928b48252bb684be6ec9eed715db
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/lodash.template@npm:^4":
|
"@types/lodash.template@npm:^4":
|
||||||
version: 4.5.1
|
version: 4.5.1
|
||||||
resolution: "@types/lodash.template@npm:4.5.1"
|
resolution: "@types/lodash.template@npm:4.5.1"
|
||||||
@ -9860,6 +9878,7 @@ __metadata:
|
|||||||
"@nuxt/kit": 3.0.0-rc.8
|
"@nuxt/kit": 3.0.0-rc.8
|
||||||
"@nuxt/schema": 3.0.0-rc.8
|
"@nuxt/schema": 3.0.0-rc.8
|
||||||
"@types/clear": ^0
|
"@types/clear": ^0
|
||||||
|
"@types/flat": ^5.0.2
|
||||||
"@types/mri": ^1.1.1
|
"@types/mri": ^1.1.1
|
||||||
"@types/semver": ^7
|
"@types/semver": ^7
|
||||||
c12: ^0.2.9
|
c12: ^0.2.9
|
||||||
@ -9976,7 +9995,7 @@ __metadata:
|
|||||||
unenv: ^0.6.1
|
unenv: ^0.6.1
|
||||||
unimport: ^0.6.7
|
unimport: ^0.6.7
|
||||||
unplugin: ^0.9.2
|
unplugin: ^0.9.2
|
||||||
untyped: ^0.4.5
|
untyped: ^0.4.7
|
||||||
vue: ^3.2.37
|
vue: ^3.2.37
|
||||||
vue-bundle-renderer: ^0.4.2
|
vue-bundle-renderer: ^0.4.2
|
||||||
vue-devtools-stub: ^0.1.0
|
vue-devtools-stub: ^0.1.0
|
||||||
@ -13190,6 +13209,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"untyped@npm:^0.4.7":
|
||||||
|
version: 0.4.7
|
||||||
|
resolution: "untyped@npm:0.4.7"
|
||||||
|
dependencies:
|
||||||
|
"@babel/core": ^7.18.13
|
||||||
|
"@babel/standalone": ^7.18.13
|
||||||
|
"@babel/types": ^7.18.13
|
||||||
|
scule: ^0.3.2
|
||||||
|
checksum: d5b189b19e114c4d60e122da9234c68a93d71b312a64bd8303e3aaa96f7a677befa8519ce003dec8cb587ed3e5503046131532196257ed10e647bc741532b1bc
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"upath@npm:^2.0.1":
|
"upath@npm:^2.0.1":
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
resolution: "upath@npm:2.0.1"
|
resolution: "upath@npm:2.0.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user