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