feat(kit,nuxt,vite,webpack): reimplement cjs utils using `jiti` (#29073)

This commit is contained in:
Daniel Roe 2024-09-19 16:35:02 +01:00 committed by GitHub
parent 3dbcdd0036
commit c5a8eaae36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 185 additions and 315 deletions

View File

@ -1,7 +0,0 @@
/* eslint-disable no-var */
declare global {
var __NUXT_PREPATHS__: string[] | string | undefined
var __NUXT_PATHS__: string[] | string | undefined
}
export {}

View File

@ -32,14 +32,6 @@ export { addTemplate, addTypeTemplate, normalizeTemplate, updateTemplates, write
export { logger, useLogger } from './logger'
// Internal Utils
// TODO
export {
resolveModule,
requireModule,
importModule,
tryImportModule,
tryRequireModule,
} from './internal/cjs'
export type { ResolveModuleOptions, RequireModuleOptions } from './internal/cjs'
export { tryResolveModule } from './internal/esm'
export { resolveModule, tryResolveModule, importModule, tryImportModule, requireModule, tryRequireModule } from './internal/esm'
export type { ImportModuleOptions, ResolveModuleOptions } from './internal/esm'
export * from './internal/template'

View File

@ -1,121 +0,0 @@
import { pathToFileURL } from 'node:url'
import { normalize } from 'pathe'
import { interopDefault } from 'mlly'
import { createJiti } from 'jiti'
// TODO: use create-require for jest environment
const jiti = createJiti(process.cwd(), { interopDefault: true })
/** @deprecated Do not use CJS utils */
export interface ResolveModuleOptions {
paths?: string | string[]
}
/** @deprecated Do not use CJS utils */
export interface RequireModuleOptions extends ResolveModuleOptions {
// TODO: use create-require for jest environment
// native?: boolean
/** Clear the require cache (force fresh require) but only if not within `node_modules` */
clearCache?: boolean
/** Automatically de-default the result of requiring the module. */
interopDefault?: boolean
}
/** @deprecated Do not use CJS utils */
function isNodeModules (id: string) {
// TODO: Follow symlinks
return /[/\\]node_modules[/\\]/.test(id)
}
/** @deprecated Do not use CJS utils */
function clearRequireCache (id: string) {
if (isNodeModules(id)) {
return
}
const entry = getRequireCacheItem(id)
if (!entry) {
delete jiti.cache[id]
return
}
if (entry.parent) {
entry.parent.children = entry.parent.children.filter(e => e.id !== id)
}
for (const child of entry.children) {
clearRequireCache(child.id)
}
delete jiti.cache[id]
}
/** @deprecated Do not use CJS utils */
function getRequireCacheItem (id: string) {
try {
return jiti.cache[id]
} catch {
// ignore issues accessing require.cache
}
}
export function getNodeModulesPaths (paths?: string[] | string) {
return ([] as Array<string | undefined>).concat(
global.__NUXT_PREPATHS__,
paths || [],
process.cwd(),
global.__NUXT_PATHS__,
).filter(Boolean) as string[]
}
/** @deprecated Do not use CJS utils */
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
return normalize(jiti.resolve(id, {
paths: getNodeModulesPaths(opts.paths),
}))
}
/** @deprecated Do not use CJS utils */
export function requireModule (id: string, opts: RequireModuleOptions = {}) {
// Resolve id
const resolvedPath = resolveModule(id, opts)
// Clear require cache if necessary
if (opts.clearCache && !isNodeModules(id)) {
clearRequireCache(resolvedPath)
}
// Try to require
const requiredModule = jiti(resolvedPath)
return requiredModule
}
/** @deprecated Do not use CJS utils */
export function importModule (id: string, opts: RequireModuleOptions = {}) {
const resolvedPath = resolveModule(id, opts)
if (opts.interopDefault !== false) {
return import(pathToFileURL(resolvedPath).href).then(interopDefault)
}
return import(pathToFileURL(resolvedPath).href)
}
/** @deprecated Do not use CJS utils */
export function tryImportModule (id: string, opts: RequireModuleOptions = {}) {
try {
return importModule(id, opts).catch(() => undefined)
} catch {
// intentionally empty as this is a `try-` function
}
}
/** @deprecated Do not use CJS utils */
export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) {
try {
return requireModule(id, opts)
} catch {
// intentionally empty as this is a `try-` function
}
}

View File

@ -1,5 +1,10 @@
import { pathToFileURL } from 'node:url'
import { interopDefault, resolvePath } from 'mlly'
import { interopDefault, resolvePath, resolvePathSync } from 'mlly'
import { createJiti } from 'jiti'
export interface ResolveModuleOptions {
paths?: string | string[]
}
/**
* Resolve a module from a given root path using an algorithm patterned on
@ -15,14 +20,52 @@ export async function tryResolveModule (id: string, url: string | string[] = imp
}
}
export async function importModule (id: string, url: string | string[] = import.meta.url) {
const resolvedPath = await resolvePath(id, { url })
return import(pathToFileURL(resolvedPath).href).then(interopDefault)
export function resolveModule (id: string, options?: ResolveModuleOptions) {
return resolvePathSync(id, { url: options?.paths ?? [import.meta.url] })
}
export function tryImportModule (id: string, url = import.meta.url) {
export interface ImportModuleOptions extends ResolveModuleOptions {
/** Automatically de-default the result of requiring the module. */
interopDefault?: boolean
}
export async function importModule<T = unknown> (id: string, opts?: ImportModuleOptions) {
const resolvedPath = await resolveModule(id, opts)
return import(pathToFileURL(resolvedPath).href).then(r => opts?.interopDefault !== false ? interopDefault(r) : r) as Promise<T>
}
export function tryImportModule<T = unknown> (id: string, opts?: ImportModuleOptions) {
try {
return importModule(id, url).catch(() => undefined)
return importModule<T>(id, opts).catch(() => undefined)
} catch {
// intentionally empty as this is a `try-` function
}
}
const warnings = new Set<string>()
/**
* @deprecated Please use `importModule` instead.
*/
export function requireModule<T = unknown> (id: string, opts?: ImportModuleOptions) {
if (!warnings.has(id)) {
// TODO: add more information on stack trace
console.warn('[@nuxt/kit] `requireModule` is deprecated. Please use `importModule` instead.')
warnings.add(id)
}
const resolvedPath = resolveModule(id, opts)
const jiti = createJiti(import.meta.url, {
interopDefault: opts?.interopDefault !== false,
})
return jiti(pathToFileURL(resolvedPath).href) as T
}
/**
* @deprecated Please use `tryImportModule` instead.
*/
export function tryRequireModule<T = unknown> (id: string, opts?: ImportModuleOptions) {
try {
return requireModule<T>(id, opts)
} catch {
// intentionally empty as this is a `try-` function
}

View File

@ -39,13 +39,13 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
// Nuxt 3
if (majorVersion && majorVersion >= 3) {
const { loadNuxt } = await importModule((pkg as any)._name || pkg.name, rootDir)
const { loadNuxt } = await importModule<typeof import('nuxt')>((pkg as any)._name || pkg.name, { paths: rootDir })
const nuxt = await loadNuxt(opts)
return nuxt
}
// Nuxt 2
const { loadNuxt } = await tryImportModule('nuxt-edge', rootDir) || await importModule('nuxt', rootDir)
const { loadNuxt } = await tryImportModule<{ loadNuxt: any }>('nuxt-edge', { paths: rootDir }) || await importModule<{ loadNuxt: any }>('nuxt', { paths: rootDir })
const nuxt = await loadNuxt({
rootDir: opts.cwd,
for: opts.dev ? 'dev' : 'build',
@ -75,11 +75,11 @@ export async function buildNuxt (nuxt: Nuxt): Promise<any> {
// Nuxt 3
if (nuxt.options._majorVersion === 3) {
const { build } = await tryImportModule('nuxt-nightly', rootDir) || await tryImportModule('nuxt3', rootDir) || await importModule('nuxt', rootDir)
const { build } = await tryImportModule<typeof import('nuxt')>('nuxt-nightly', { paths: rootDir }) || await tryImportModule<typeof import('nuxt')>('nuxt3', { paths: rootDir }) || await importModule<typeof import('nuxt')>('nuxt', { paths: rootDir })
return build(nuxt)
}
// Nuxt 2
const { build } = await tryImportModule('nuxt-edge', rootDir) || await importModule('nuxt', rootDir)
const { build } = await tryImportModule<{ build: any }>('nuxt-edge', { paths: rootDir }) || await importModule<{ build: any }>('nuxt', { paths: rootDir })
return build(nuxt)
}

View File

@ -2,11 +2,10 @@ import { existsSync, promises as fsp, lstatSync } from 'node:fs'
import type { ModuleMeta, Nuxt, NuxtConfig, NuxtModule } from '@nuxt/schema'
import { dirname, isAbsolute, join, resolve } from 'pathe'
import { defu } from 'defu'
import { createJiti } from 'jiti'
import { isNuxt2 } from '../compatibility'
import { useNuxt } from '../context'
import { requireModule } from '../internal/cjs'
import { importModule } from '../internal/esm'
import { resolveAlias, resolvePath } from '../resolve'
import { resolveAlias } from '../resolve'
import { logger } from '../logger'
const NODE_MODULES_RE = /[/\\]node_modules[/\\]/
@ -78,15 +77,20 @@ export const normalizeModuleTranspilePath = (p: string) => {
export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, nuxt: Nuxt = useNuxt()) {
let buildTimeModuleMeta: ModuleMeta = {}
const jiti = createJiti(nuxt.options.rootDir, {
interopDefault: true,
alias: nuxt.options.alias,
})
// Import if input is string
if (typeof nuxtModule === 'string') {
const paths = [join(nuxtModule, 'nuxt'), join(nuxtModule, 'module'), nuxtModule]
let error: unknown
for (const path of paths) {
try {
const src = await resolvePath(path, { fallbackToOriginal: true })
// Prefer ESM resolution if possible
nuxtModule = await importModule(src, nuxt.options.modulesDir).catch(() => null) ?? requireModule(src, { paths: nuxt.options.modulesDir })
const src = jiti.esmResolve(path)
nuxtModule = await jiti.import(src) as NuxtModule
// nuxt-module-builder generates a module.json with metadata including the version
const moduleMetadataPath = join(dirname(src), 'module.json')
@ -100,7 +104,7 @@ export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, n
}
}
if (typeof nuxtModule !== 'function' && error) {
logger.error(`Error while requiring module \`${nuxtModule}\`: ${error}`)
logger.error(`Error while importing module \`${nuxtModule}\`: ${error}`)
throw error
}
}

View File

@ -11,7 +11,6 @@ import { readPackageJSON } from 'pkg-types'
import { tryResolveModule } from './internal/esm'
import { getDirectory } from './module/install'
import { tryUseNuxt, useNuxt } from './context'
import { getNodeModulesPaths } from './internal/cjs'
import { resolveNuxtModule } from './resolve'
/**
@ -268,7 +267,7 @@ export async function _generateTypes (nuxt: Nuxt) {
await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
if (typeof id !== 'string') { return }
const pkg = await readPackageJSON(id, { url: getNodeModulesPaths(nuxt.options.modulesDir) }).catch(() => null)
const pkg = await readPackageJSON(id, { url: nuxt.options.modulesDir }).catch(() => null)
references.push(({ types: pkg?.name || id }))
}))

View File

@ -2,8 +2,6 @@
declare global {
var __NUXT_VERSION__: string
var __NUXT_ASYNC_CONTEXT__: boolean
var __NUXT_PREPATHS__: string[] | string | undefined
var __NUXT_PATHS__: string[] | string | undefined
interface Navigator {
connection?: {

View File

@ -1,9 +1,7 @@
import { pathToFileURL } from 'node:url'
import type { EventType } from '@parcel/watcher'
import type { FSWatcher } from 'chokidar'
import { watch as chokidarWatch } from 'chokidar'
import { isIgnored, logger, tryResolveModule, useNuxt } from '@nuxt/kit'
import { interopDefault } from 'mlly'
import { importModule, isIgnored, logger, tryResolveModule, useNuxt } from '@nuxt/kit'
import { debounce } from 'perfect-debounce'
import { normalize, relative, resolve } from 'pathe'
import type { Nuxt, NuxtBuilder } from 'nuxt/schema'
@ -171,7 +169,7 @@ async function createParcelWatcher () {
return false
}
const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault) as typeof import('@parcel/watcher')
const { subscribe } = await importModule<typeof import('@parcel/watcher')>(watcherPath)
for (const layer of nuxt.options._layers) {
if (!layer.config.srcDir) { continue }
const watcher = subscribe(layer.config.srcDir, (err, events) => {
@ -222,5 +220,5 @@ async function loadBuilder (nuxt: Nuxt, builder: string): Promise<NuxtBuilder> {
if (!builderPath) {
throw new Error(`Loading \`${builder}\` builder failed. You can read more about the nuxt \`builder\` option at: \`https://nuxt.com/docs/api/nuxt-config#builder\``)
}
return import(pathToFileURL(builderPath).href)
return importModule(builderPath)
}

View File

@ -6,7 +6,7 @@ import { createRouter as createRadixRouter, exportMatcher, toRouteMatcher } from
import { joinURL, withTrailingSlash } from 'ufo'
import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, scanHandlers, writeTypes } from 'nitropack'
import type { Nitro, NitroConfig, NitroOptions } from 'nitropack'
import { findPath, logger, resolveAlias, resolveIgnorePatterns, resolveNuxtModule, resolvePath } from '@nuxt/kit'
import { findPath, logger, resolveAlias, resolveIgnorePatterns, resolveNuxtModule } from '@nuxt/kit'
import escapeRE from 'escape-string-regexp'
import { defu } from 'defu'
import { dynamicEventHandler } from 'h3'
@ -409,7 +409,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
})
const cacheDir = resolve(nuxt.options.buildDir, 'cache/nitro/prerender')
const cacheDriverPath = await resolvePath(join(distDir, 'core/runtime/nitro/cache-driver'))
const cacheDriverPath = join(distDir, 'core/runtime/nitro/cache-driver.js')
await fsp.rm(cacheDir, { recursive: true, force: true }).catch(() => {})
nitro.options._config.storage = defu(nitro.options._config.storage, {
'internal:nuxt:prerender': {

View File

@ -1,10 +1,18 @@
// @ts-check
import { defineDriver } from 'unstorage'
import fsDriver, { type FSStorageOptions } from 'unstorage/drivers/fs-lite'
import fsDriver from 'unstorage/drivers/fs-lite'
import lruCache from 'unstorage/drivers/lru-cache'
const normalizeFsKey = (item: string) => item.replaceAll(':', '_')
/**
* @param {string} item
*/
const normalizeFsKey = item => item.replaceAll(':', '_')
export default defineDriver((opts: FSStorageOptions) => {
/**
* @param {{ base: string }} opts
*/
export default defineDriver((opts) => {
const fs = fsDriver({ base: opts.base })
const lru = lruCache({ max: 1000 })

View File

@ -1,12 +1,11 @@
import { existsSync } from 'node:fs'
import { mkdir, writeFile } from 'node:fs/promises'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { fileURLToPath } from 'node:url'
import { resolve } from 'pathe'
import { watch } from 'chokidar'
import { interopDefault } from 'mlly'
import { defu } from 'defu'
import { debounce } from 'perfect-debounce'
import { createResolver, defineNuxtModule, logger, tryResolveModule } from '@nuxt/kit'
import { createResolver, defineNuxtModule, importModule, logger, tryResolveModule } from '@nuxt/kit'
import {
generateTypes,
resolveSchema as resolveUntypedSchema,
@ -63,7 +62,7 @@ export default defineNuxtModule({
if (nuxt.options.experimental.watcher === 'parcel') {
const watcherPath = await tryResolveModule('@parcel/watcher', [nuxt.options.rootDir, ...nuxt.options.modulesDir])
if (watcherPath) {
const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault) as typeof import('@parcel/watcher')
const { subscribe } = await importModule<typeof import('@parcel/watcher')>(watcherPath)
for (const layer of nuxt.options._layers) {
const subscription = await subscribe(layer.config.rootDir, onChange, {
ignore: ['!nuxt.schema.*'],

View File

@ -47,6 +47,7 @@
"externality": "^1.0.2",
"get-port-please": "^3.1.2",
"h3": "^1.12.0",
"jiti": "^2.0.0-rc.1",
"knitwork": "^1.1.0",
"magic-string": "^0.30.11",
"mlly": "^1.7.1",

View File

@ -1,10 +1,7 @@
import { fileURLToPath, pathToFileURL } from 'node:url'
import { requireModule, resolveAlias, tryResolveModule } from '@nuxt/kit'
import type { Nuxt, NuxtOptions } from '@nuxt/schema'
import type { InlineConfig as ViteConfig } from 'vite'
import { interopDefault } from 'mlly'
import type { Plugin } from 'postcss'
import { isAbsolute, resolve } from 'pathe'
import { createJiti } from 'jiti'
function sortPlugins ({ plugins, order }: NuxtOptions['postcss']): string[] {
const names = Object.keys(plugins)
@ -19,36 +16,23 @@ export async function resolveCSSOptions (nuxt: Nuxt): Promise<ViteConfig['css']>
}
css.postcss.plugins = []
const postcssOptions = nuxt.options.postcss
const cwd = fileURLToPath(new URL('.', import.meta.url))
const jiti = createJiti(nuxt.options.rootDir, {
interopDefault: true,
alias: nuxt.options.alias,
})
for (const pluginName of sortPlugins(postcssOptions)) {
const pluginOptions = postcssOptions.plugins[pluginName]
if (!pluginOptions) { continue }
let pluginPath: string | undefined = resolveAlias(pluginName, nuxt.options.alias)
let pluginFn: (opts: Record<string, any>) => Plugin
if (pluginPath[0] === '.') {
pluginPath = resolve(nuxt.options.rootDir, pluginPath)
}
const path = await tryResolveModule(pluginPath, nuxt.options.modulesDir)
// TODO: use jiti v2
if (path) {
pluginFn = await import(pathToFileURL(path).href).then(interopDefault)
} else {
// warn for libraries, not for local plugins
if (!isAbsolute(pluginPath)) {
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`)
}
// fall back to cjs
pluginFn = requireModule(pluginPath, { paths: [cwd] })
}
const path = jiti.esmResolve(pluginName)
const pluginFn = (await jiti.import(path)) as (opts: Record<string, any>) => Plugin
if (typeof pluginFn === 'function') {
css.postcss.plugins.push(pluginFn(pluginOptions))
} else {
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\`. Please report this as a bug.`)
}
}

View File

@ -2,9 +2,10 @@ import { resolve } from 'pathe'
import * as vite from 'vite'
import vuePlugin from '@vitejs/plugin-vue'
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
import { logger, resolvePath, tryResolveModule } from '@nuxt/kit'
import { logger, resolvePath, tryImportModule } from '@nuxt/kit'
import { joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo'
import type { ViteConfig } from '@nuxt/schema'
import type { PackageJson } from 'pkg-types'
import defu from 'defu'
import type { Nitro } from 'nitropack'
import type { ViteBuildContext } from './vite'
@ -112,8 +113,9 @@ export async function buildServer (ctx: ViteBuildContext) {
} satisfies vite.InlineConfig, ctx.nuxt.options.vite.$server || {}))
if (!ctx.nuxt.options.dev) {
const nitroDependencies = await tryResolveModule('nitropack/package.json', ctx.nuxt.options.modulesDir)
.then(r => import(r!)).then(r => r.dependencies ? Object.keys(r.dependencies) : []).catch(() => [])
const runtimeDependencies = await tryImportModule<PackageJson>('nitropack/package.json', {
paths: ctx.nuxt.options.modulesDir,
})?.then(r => r?.dependencies ? Object.keys(r.dependencies) : []).catch(() => []) || []
if (Array.isArray(serverConfig.ssr!.external)) {
serverConfig.ssr!.external.push(
// explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build
@ -121,7 +123,7 @@ export async function buildServer (ctx: ViteBuildContext) {
// ensure we only have one version of vue if nitro is going to inline anyway
...((ctx.nuxt as any)._nitro as Nitro).options.inlineDynamicImports ? ['vue', '@vue/server-renderer', '@unhead/vue'] : [],
// dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
...nitroDependencies,
...runtimeDependencies,
)
}
}

View File

@ -39,6 +39,7 @@
"fork-ts-checker-webpack-plugin": "^9.0.2",
"h3": "^1.12.0",
"hash-sum": "^2.0.0",
"jiti": "^2.0.0-rc.1",
"lodash-es": "4.17.21",
"magic-string": "^0.30.11",
"memfs": "^4.12.0",

View File

@ -1,11 +1,8 @@
import { fileURLToPath, pathToFileURL } from 'node:url'
import createResolver from 'postcss-import-resolver'
import { interopDefault } from 'mlly'
import { requireModule, resolveAlias, tryResolveModule } from '@nuxt/kit'
import type { Nuxt, NuxtOptions } from '@nuxt/schema'
import { defu } from 'defu'
import { createJiti } from 'jiti'
import type { Plugin } from 'postcss'
import { isAbsolute, resolve } from 'pathe'
const isPureObject = (obj: unknown): obj is object => obj !== null && !Array.isArray(obj) && typeof obj === 'object'
@ -39,37 +36,25 @@ export async function getPostcssConfig (nuxt: Nuxt) {
sourceMap: nuxt.options.webpack.cssSourceMap,
})
const jiti = createJiti(nuxt.options.rootDir, {
interopDefault: true,
alias: nuxt.options.alias,
})
// Keep the order of default plugins
if (!Array.isArray(postcssOptions.plugins) && isPureObject(postcssOptions.plugins)) {
// Map postcss plugins into instances on object mode once
const cwd = fileURLToPath(new URL('.', import.meta.url))
const plugins: Plugin[] = []
for (const pluginName of sortPlugins(postcssOptions)) {
const pluginOptions = postcssOptions.plugins[pluginName]
if (!pluginOptions) { continue }
let pluginPath: string | undefined = resolveAlias(pluginName, nuxt.options.alias)
let pluginFn: (opts: Record<string, any>) => Plugin
if (pluginPath[0] === '.') {
pluginPath = resolve(nuxt.options.rootDir, pluginPath)
}
const path = await tryResolveModule(pluginPath, nuxt.options.modulesDir)
// TODO: use jiti v2
if (path) {
pluginFn = await import(pathToFileURL(path).href).then(interopDefault)
} else {
// warn for libraries, not for local plugins
if (!isAbsolute(pluginPath)) {
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`)
}
// fall back to cjs
pluginFn = requireModule(pluginPath, { paths: [cwd] })
}
const path = jiti.esmResolve(pluginName)
const pluginFn = (await jiti.import(path)) as (opts: Record<string, any>) => Plugin
if (typeof pluginFn === 'function') {
plugins.push(pluginFn(pluginOptions))
} else {
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\`. Please report this as a bug.`)
}
}

View File

@ -710,6 +710,9 @@ importers:
h3:
specifier: ^1.12.0
version: 1.12.0
jiti:
specifier: ^2.0.0-rc.1
version: 2.0.0-rc.1
knitwork:
specifier: ^1.1.0
version: 1.1.0
@ -760,7 +763,7 @@ importers:
version: 2.1.1(@types/node@20.16.5)(sass@1.78.0)(terser@5.32.0)
vite-plugin-checker:
specifier: ^0.8.0
version: 0.8.0(eslint@9.10.0(jiti@1.21.6))(optionator@0.9.4)(typescript@5.6.2)(vite@5.4.6(@types/node@20.16.5)(sass@1.78.0)(terser@5.32.0))(vue-tsc@2.1.6(typescript@5.6.2))
version: 0.8.0(eslint@9.10.0(jiti@2.0.0-rc.1))(optionator@0.9.4)(typescript@5.6.2)(vite@5.4.6(@types/node@20.16.5)(sass@1.78.0)(terser@5.32.0))(vue-tsc@2.1.6(typescript@5.6.2))
vue-bundle-renderer:
specifier: ^2.1.0
version: 2.1.0
@ -828,6 +831,9 @@ importers:
hash-sum:
specifier: ^2.0.0
version: 2.0.0
jiti:
specifier: ^2.0.0-rc.1
version: 2.0.0-rc.1
lodash-es:
specifier: 4.17.21
version: 4.17.21
@ -956,6 +962,9 @@ importers:
'@vue/devtools-api':
specifier: latest
version: 7.4.5
postcss:
specifier: 8.4.47
version: 8.4.47
ufo:
specifier: 1.5.4
version: 1.5.4
@ -2291,8 +2300,8 @@ packages:
'@shikijs/core@1.17.6':
resolution: {integrity: sha512-9ztslig6/YmCg/XwESAXbKjAjOhaq6HVced9NY6qcbDz1X5g/S90Wco2vMjBNX/6V71ASkzri76JewSGPa7kiQ==}
'@shikijs/core@1.17.7':
resolution: {integrity: sha512-ZnIDxFu/yvje3Q8owSHaEHd+bu/jdWhHAaJ17ggjXofHx5rc4bhpCSW+OjC6smUBi5s5dd023jWtZ1gzMu/yrw==}
'@shikijs/core@1.18.0':
resolution: {integrity: sha512-VK4BNVCd2leY62Nm2JjyxtRLkyrZT/tv104O81eyaCjHq4Adceq2uJVFJJAIof6lT1mBwZrEo2qT/T+grv3MQQ==}
'@shikijs/engine-javascript@1.17.0':
resolution: {integrity: sha512-EiBVlxmzJZdC2ypzn8k+vxLngbBNgHLS4RilwrFOABGRc72kUZubbD/6Chrq2RcVtD3yq1GtiiIdFMGd9BTX3Q==}
@ -2300,8 +2309,8 @@ packages:
'@shikijs/engine-javascript@1.17.6':
resolution: {integrity: sha512-5EEZj8tVcierNxm4V0UMS2PVoflb0UJPalWWV8l9rRg+oOfnr5VivqBJbkyq5grltVPvByIXvVbY8GSM/356jQ==}
'@shikijs/engine-javascript@1.17.7':
resolution: {integrity: sha512-wwSf7lKPsm+hiYQdX+1WfOXujtnUG6fnN4rCmExxa4vo+OTmvZ9B1eKauilvol/LHUPrQgW12G3gzem7pY5ckw==}
'@shikijs/engine-javascript@1.18.0':
resolution: {integrity: sha512-qoP/aO/ATNwYAUw1YMdaip/YVEstMZEgrwhePm83Ll9OeQPuxDZd48szZR8oSQNQBT8m8UlWxZv8EA3lFuyI5A==}
'@shikijs/engine-oniguruma@1.17.0':
resolution: {integrity: sha512-nsXzJGLQ0fhKmA4Gwt1cF7vC8VuZ1HSDrTRuj48h/qDeX/TzmOlTDXQ3uPtyuhyg/2rbZRzNhN8UFU4fSnQfXg==}
@ -2309,14 +2318,14 @@ packages:
'@shikijs/engine-oniguruma@1.17.6':
resolution: {integrity: sha512-NLfWDMXFYe0nDHFbEoyZdz89aIIey3bTfF3zLYSUNTXks5s4uinZVmuPOFf1HfTeGqIn8uErJSBc3VnpJO7Alw==}
'@shikijs/engine-oniguruma@1.17.7':
resolution: {integrity: sha512-pvSYGnVeEIconU28NEzBXqSQC/GILbuNbAHwMoSfdTBrobKAsV1vq2K4cAgiaW1TJceLV9QMGGh18hi7cCzbVQ==}
'@shikijs/engine-oniguruma@1.18.0':
resolution: {integrity: sha512-B9u0ZKI/cud+TcmF8Chyh+R4V5qQVvyDOqXC2l2a4x73PBSBc6sZ0JRAX3eqyJswqir6ktwApUUGBYePdKnMJg==}
'@shikijs/transformers@1.17.0':
resolution: {integrity: sha512-C/s6z0knkWBVRG6cmklTUn+70URKVE8qlQuFg6Bi/9iqpX68NZloZhxCtVHeTd56pit15hivTlgSAY+SP7C8hA==}
'@shikijs/twoslash@1.17.7':
resolution: {integrity: sha512-GAD5UMD69aL5WiXfrWWZRLVekK3060cV/Qg2a8ZjSVdN8VwjZIw25UmbF5b/3QJxKdSvTirg0senL5gTb+NHJw==}
'@shikijs/twoslash@1.18.0':
resolution: {integrity: sha512-nbv1vEiNlM9GbXpN0++5QiT2NdUbAJ6y8yBuMWIiT04dxD3tdl7Ud3TL6hAZ6CAwMGn5hRaN+2va2oN1Rsy1Ww==}
'@shikijs/types@1.17.0':
resolution: {integrity: sha512-Tvu2pA69lbpXB+MmgIaROP1tio8y0uYvKb5Foh3q0TJBTAJuaoa5eDEtS/0LquyveacsiVrYF4uEZILju+7Ybg==}
@ -2324,8 +2333,8 @@ packages:
'@shikijs/types@1.17.6':
resolution: {integrity: sha512-ndTFa2TJi2w51ddKQDn3Jy8f6K4E5Q2x3dA3Hmsd3+YmxDQ10UWHjcw7VbVbKzv3VcUvYPLy+z9neqytSzUMUg==}
'@shikijs/types@1.17.7':
resolution: {integrity: sha512-+qA4UyhWLH2q4EFd+0z4K7GpERDU+c+CN2XYD3sC+zjvAr5iuwD1nToXZMt1YODshjkEGEDV86G7j66bKjqDdg==}
'@shikijs/types@1.18.0':
resolution: {integrity: sha512-O9N36UEaGGrxv1yUrN2nye7gDLG5Uq0/c1LyfmxsvzNPqlHzWo9DI0A4+fhW2y3bGKuQu/fwS7EPdKJJCowcVA==}
'@shikijs/vitepress-twoslash@1.17.0':
resolution: {integrity: sha512-FcdZUtF1jL51fZfkITd1qEnmnVe/w8lnOGhEWptMqMNvMYzB8vxDv5y+E1zvE+rw0NbBuWtOmZea3WOah1nr6g==}
@ -4471,6 +4480,9 @@ packages:
hast-util-to-html@9.0.2:
resolution: {integrity: sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==}
hast-util-to-html@9.0.3:
resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==}
hast-util-to-parse5@8.0.0:
resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
@ -5180,10 +5192,6 @@ packages:
resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==}
engines: {node: '>= 4.0.0'}
memfs@4.11.2:
resolution: {integrity: sha512-VcR7lEtgQgv7AxGkrNNeUAimFLT+Ov8uGu1LuOfbe/iF/dKoh/QgpoaMZlhfejvLtMxtXYyeoT7Ar1jEbWdbPA==}
engines: {node: '>= 4.0.0'}
memfs@4.12.0:
resolution: {integrity: sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==}
engines: {node: '>= 4.0.0'}
@ -7987,12 +7995,6 @@ snapshots:
'@esbuild/win32-x64@0.23.1':
optional: true
'@eslint-community/eslint-utils@4.4.0(eslint@9.10.0(jiti@1.21.6))':
dependencies:
eslint: 9.10.0(jiti@1.21.6)
eslint-visitor-keys: 3.4.3
optional: true
'@eslint-community/eslint-utils@4.4.0(eslint@9.10.0(jiti@2.0.0-rc.1))':
dependencies:
eslint: 9.10.0(jiti@2.0.0-rc.1)
@ -8727,14 +8729,14 @@ snapshots:
'@types/hast': 3.0.4
hast-util-to-html: 9.0.2
'@shikijs/core@1.17.7':
'@shikijs/core@1.18.0':
dependencies:
'@shikijs/engine-javascript': 1.17.7
'@shikijs/engine-oniguruma': 1.17.7
'@shikijs/types': 1.17.7
'@shikijs/engine-javascript': 1.18.0
'@shikijs/engine-oniguruma': 1.18.0
'@shikijs/types': 1.18.0
'@shikijs/vscode-textmate': 9.2.2
'@types/hast': 3.0.4
hast-util-to-html: 9.0.2
hast-util-to-html: 9.0.3
'@shikijs/engine-javascript@1.17.0':
dependencies:
@ -8747,9 +8749,9 @@ snapshots:
'@shikijs/types': 1.17.6
oniguruma-to-js: 0.4.3
'@shikijs/engine-javascript@1.17.7':
'@shikijs/engine-javascript@1.18.0':
dependencies:
'@shikijs/types': 1.17.7
'@shikijs/types': 1.18.0
'@shikijs/vscode-textmate': 9.2.2
oniguruma-to-js: 0.4.3
@ -8763,19 +8765,19 @@ snapshots:
'@shikijs/types': 1.17.6
'@shikijs/vscode-textmate': 9.2.2
'@shikijs/engine-oniguruma@1.17.7':
'@shikijs/engine-oniguruma@1.18.0':
dependencies:
'@shikijs/types': 1.17.7
'@shikijs/types': 1.18.0
'@shikijs/vscode-textmate': 9.2.2
'@shikijs/transformers@1.17.0':
dependencies:
shiki: 1.17.0
'@shikijs/twoslash@1.17.7(typescript@5.6.2)':
'@shikijs/twoslash@1.18.0(typescript@5.6.2)':
dependencies:
'@shikijs/core': 1.17.7
'@shikijs/types': 1.17.7
'@shikijs/core': 1.18.0
'@shikijs/types': 1.18.0
twoslash: 0.2.11(typescript@5.6.2)
transitivePeerDependencies:
- supports-color
@ -8791,14 +8793,14 @@ snapshots:
'@shikijs/vscode-textmate': 9.2.2
'@types/hast': 3.0.4
'@shikijs/types@1.17.7':
'@shikijs/types@1.18.0':
dependencies:
'@shikijs/vscode-textmate': 9.2.2
'@types/hast': 3.0.4
'@shikijs/vitepress-twoslash@1.17.0(@nuxt/kit@packages+kit)(typescript@5.6.2)':
dependencies:
'@shikijs/twoslash': 1.17.7(typescript@5.6.2)
'@shikijs/twoslash': 1.18.0(typescript@5.6.2)
floating-vue: 5.2.2(@nuxt/kit@packages+kit)(vue@3.5.6(typescript@5.6.2))
mdast-util-from-markdown: 2.0.1
mdast-util-gfm: 3.0.0
@ -11008,48 +11010,6 @@ snapshots:
eslint-visitor-keys@4.0.0: {}
eslint@9.10.0(jiti@1.21.6):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
'@eslint-community/regexpp': 4.11.0
'@eslint/config-array': 0.18.0
'@eslint/eslintrc': 3.1.0
'@eslint/js': 9.10.0
'@eslint/plugin-kit': 0.1.0
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.3.0
'@nodelib/fs.walk': 1.2.8
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.7
escape-string-regexp: 4.0.0
eslint-scope: 8.0.2
eslint-visitor-keys: 4.0.0
espree: 10.1.0
esquery: 1.6.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 8.0.0
find-up: 5.0.0
glob-parent: 6.0.2
ignore: 5.3.2
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
json-stable-stringify-without-jsonify: 1.0.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.4
strip-ansi: 6.0.1
text-table: 0.2.0
optionalDependencies:
jiti: 1.21.6
transitivePeerDependencies:
- supports-color
optional: true
eslint@9.10.0(jiti@2.0.0-rc.1):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@2.0.0-rc.1))
@ -11556,6 +11516,20 @@ snapshots:
stringify-entities: 4.0.4
zwitch: 2.0.4
hast-util-to-html@9.0.3:
dependencies:
'@types/hast': 3.0.4
'@types/unist': 3.0.3
ccount: 2.0.1
comma-separated-tokens: 2.0.3
hast-util-whitespace: 3.0.0
html-void-elements: 3.0.0
mdast-util-to-hast: 13.2.0
property-information: 6.5.0
space-separated-tokens: 2.0.2
stringify-entities: 4.0.4
zwitch: 2.0.4
hast-util-to-parse5@8.0.0:
dependencies:
'@types/hast': 3.0.4
@ -12328,13 +12302,6 @@ snapshots:
dependencies:
fs-monkey: 1.0.6
memfs@4.11.2:
dependencies:
'@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0)
'@jsonjoy.com/util': 1.3.0(tslib@2.7.0)
tree-dump: 1.0.2(tslib@2.7.0)
tslib: 2.7.0
memfs@4.12.0:
dependencies:
'@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0)
@ -14557,7 +14524,7 @@ snapshots:
- supports-color
- terser
vite-plugin-checker@0.8.0(eslint@9.10.0(jiti@1.21.6))(optionator@0.9.4)(typescript@5.6.2)(vite@5.4.6(@types/node@20.16.5)(sass@1.78.0)(terser@5.32.0))(vue-tsc@2.1.6(typescript@5.6.2)):
vite-plugin-checker@0.8.0(eslint@9.10.0(jiti@2.0.0-rc.1))(optionator@0.9.4)(typescript@5.6.2)(vite@5.4.6(@types/node@20.16.5)(sass@1.78.0)(terser@5.32.0))(vue-tsc@2.1.6(typescript@5.6.2)):
dependencies:
'@babel/code-frame': 7.24.7
ansi-escapes: 4.3.2
@ -14575,7 +14542,7 @@ snapshots:
vscode-languageserver-textdocument: 1.0.12
vscode-uri: 3.0.8
optionalDependencies:
eslint: 9.10.0(jiti@1.21.6)
eslint: 9.10.0(jiti@2.0.0-rc.1)
optionator: 0.9.4
typescript: 5.6.2
vue-tsc: 2.1.6(typescript@5.6.2)
@ -14834,7 +14801,7 @@ snapshots:
webpack-dev-middleware@7.4.2(webpack@5.94.0):
dependencies:
colorette: 2.0.20
memfs: 4.11.2
memfs: 4.12.0
mime-types: 2.1.35
on-finished: 2.4.1
range-parser: 1.2.1

View File

@ -78,6 +78,11 @@ export default defineNuxtConfig({
],
},
},
postcss: {
plugins: {
'~/postcss/plugin': {},
},
},
optimization: {
keyedComposables: [
{

View File

@ -10,6 +10,7 @@
},
"devDependencies": {
"@vue/devtools-api": "latest",
"postcss": "^8.4.47",
"ufo": "latest",
"unplugin": "latest",
"vue": "latest"

11
test/fixtures/basic/postcss/plugin.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import type { Plugin } from 'postcss'
const componentRoot = (_opts = {}): Plugin => {
console.log('loaded custom postcss plugin')
return {
postcssPlugin: 'custom-postcss-plugin',
}
}
componentRoot.postcss = true
export default componentRoot