mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
refactor(nuxt): rework and use isJS
and isVue
utilities consistently (#20344)
This commit is contained in:
parent
5febd46d23
commit
c7be5b4ec6
@ -3,7 +3,7 @@ import type { ComponentsOptions } from '@nuxt/schema'
|
|||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { isAbsolute, relative } from 'pathe'
|
import { isAbsolute, relative } from 'pathe'
|
||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
import { isVueTemplate } from './helpers'
|
import { isVue } from '../core/utils'
|
||||||
interface LoaderOptions {
|
interface LoaderOptions {
|
||||||
sourcemap?: boolean
|
sourcemap?: boolean
|
||||||
transform?: ComponentsOptions['transform'],
|
transform?: ComponentsOptions['transform'],
|
||||||
@ -25,7 +25,7 @@ export const clientFallbackAutoIdPlugin = createUnplugin((options: LoaderOptions
|
|||||||
if (include.some(pattern => id.match(pattern))) {
|
if (include.some(pattern => id.match(pattern))) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return isVueTemplate(id)
|
return isVue(id, { type: ['template'] })
|
||||||
},
|
},
|
||||||
transform (code, id) {
|
transform (code, id) {
|
||||||
if (!CLIENT_FALLBACK_RE.test(code)) { return }
|
if (!CLIENT_FALLBACK_RE.test(code)) { return }
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
|
||||||
|
|
||||||
export function isVueTemplate (id: string) {
|
|
||||||
// Bare `.vue` file (in Vite)
|
|
||||||
if (id.endsWith('.vue')) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
|
||||||
if (!search) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = parseQuery(search)
|
|
||||||
|
|
||||||
// Macro
|
|
||||||
if (query.macro) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-Vue or Styles
|
|
||||||
if (!('vue' in query) || query.type === 'style') {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query `?vue&type=template` (in Webpack or external template)
|
|
||||||
return true
|
|
||||||
}
|
|
@ -6,7 +6,7 @@ import { resolve } from 'pathe'
|
|||||||
import type { Component, ComponentsOptions } from 'nuxt/schema'
|
import type { Component, ComponentsOptions } from 'nuxt/schema'
|
||||||
|
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../dirs'
|
||||||
import { isVueTemplate } from './helpers'
|
import { isVue } from '../core/utils'
|
||||||
|
|
||||||
interface LoaderOptions {
|
interface LoaderOptions {
|
||||||
getComponents (): Component[]
|
getComponents (): Component[]
|
||||||
@ -31,7 +31,7 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
|||||||
if (include.some(pattern => id.match(pattern))) {
|
if (include.some(pattern => id.match(pattern))) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return isVueTemplate(id)
|
return isVue(id, { type: ['template', 'script'] })
|
||||||
},
|
},
|
||||||
transform (code) {
|
transform (code) {
|
||||||
const components = options.getComponents()
|
const components = options.getComponents()
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import { stripLiteral } from 'strip-literal'
|
import { stripLiteral } from 'strip-literal'
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
|
import { isJS, isVue } from '../utils'
|
||||||
|
|
||||||
type ImportPath = string
|
type ImportPath = string
|
||||||
|
|
||||||
@ -22,18 +21,7 @@ export const TreeShakeComposablesPlugin = createUnplugin((options: TreeShakeComp
|
|||||||
name: 'nuxt:tree-shake-composables:transform',
|
name: 'nuxt:tree-shake-composables:transform',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
transformInclude (id) {
|
transformInclude (id) {
|
||||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
return isVue(id, { type: ['script'] }) || isJS(id)
|
||||||
const { type } = parseQuery(search)
|
|
||||||
|
|
||||||
// vue files
|
|
||||||
if (pathname.endsWith('.vue') && (type === 'script' || !search)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// js files
|
|
||||||
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
transform (code) {
|
transform (code) {
|
||||||
if (!code.match(COMPOSABLE_RE)) { return }
|
if (!code.match(COMPOSABLE_RE)) { return }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
|
||||||
import type { TransformerOptions } from 'unctx/transform'
|
import type { TransformerOptions } from 'unctx/transform'
|
||||||
import { createTransformer } from 'unctx/transform'
|
import { createTransformer } from 'unctx/transform'
|
||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
|
|
||||||
|
import { isJS, isVue } from '../utils'
|
||||||
|
|
||||||
const TRANSFORM_MARKER = '/* _processed_nuxt_unctx_transform */\n'
|
const TRANSFORM_MARKER = '/* _processed_nuxt_unctx_transform */\n'
|
||||||
|
|
||||||
interface UnctxTransformPluginOptions {
|
interface UnctxTransformPluginOptions {
|
||||||
@ -17,22 +17,7 @@ export const UnctxTransformPlugin = createUnplugin((options: UnctxTransformPlugi
|
|||||||
name: 'unctx:transform',
|
name: 'unctx:transform',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
transformInclude (id) {
|
transformInclude (id) {
|
||||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
return isVue(id) || isJS(id)
|
||||||
const query = parseQuery(search)
|
|
||||||
|
|
||||||
// Vue files
|
|
||||||
if (
|
|
||||||
pathname.endsWith('.vue') ||
|
|
||||||
'macro' in query ||
|
|
||||||
('vue' in query && (query.type === 'template' || query.type === 'script' || 'setup' in query))
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// JavaScript files
|
|
||||||
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
transform (code) {
|
transform (code) {
|
||||||
// TODO: needed for webpack - update transform in unctx/unplugin?
|
// TODO: needed for webpack - update transform in unctx/unplugin?
|
||||||
|
13
packages/nuxt/src/core/utils/index.ts
Normal file
13
packages/nuxt/src/core/utils/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export * from './names'
|
||||||
|
export * from './plugins'
|
||||||
|
|
||||||
|
export function uniqueBy<T, K extends keyof T> (arr: T[], key: K) {
|
||||||
|
const res: T[] = []
|
||||||
|
const seen = new Set<T[K]>()
|
||||||
|
for (const item of arr) {
|
||||||
|
if (seen.has(item[key])) { continue }
|
||||||
|
seen.add(item[key])
|
||||||
|
res.push(item)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
@ -5,17 +5,6 @@ export function getNameFromPath (path: string) {
|
|||||||
return kebabCase(basename(path).replace(extname(path), '')).replace(/["']/g, '')
|
return kebabCase(basename(path).replace(extname(path), '')).replace(/["']/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uniqueBy <T, K extends keyof T> (arr: T[], key: K) {
|
|
||||||
const res: T[] = []
|
|
||||||
const seen = new Set<T[K]>()
|
|
||||||
for (const item of arr) {
|
|
||||||
if (seen.has(item[key])) { continue }
|
|
||||||
seen.add(item[key])
|
|
||||||
res.push(item)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hasSuffix (path: string, suffix: string) {
|
export function hasSuffix (path: string, suffix: string) {
|
||||||
return basename(path).replace(extname(path), '').endsWith(suffix)
|
return basename(path).replace(extname(path), '').endsWith(suffix)
|
||||||
}
|
}
|
38
packages/nuxt/src/core/utils/plugins.ts
Normal file
38
packages/nuxt/src/core/utils/plugins.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
|
import { parseQuery, parseURL } from 'ufo'
|
||||||
|
|
||||||
|
export function isVue (id: string, opts: { type?: Array<'template' | 'script' | 'style'> } = {}) {
|
||||||
|
// Bare `.vue` file (in Vite)
|
||||||
|
const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
||||||
|
if (id.endsWith('.vue') && !search) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!search) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = parseQuery(search)
|
||||||
|
|
||||||
|
// Macro
|
||||||
|
if (query.macro && (!opts.type || opts.type.includes('script'))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-Vue or Styles
|
||||||
|
const type = 'setup' in query ? 'script' : query.type as 'script' | 'template' | 'style'
|
||||||
|
if (!('vue' in query) || (opts.type && !opts.type.includes(type))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query `?vue&type=template` (in Webpack or external template)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const JS_RE = /\.((c|m)?j|t)sx?$/
|
||||||
|
|
||||||
|
export function isJS (id: string) {
|
||||||
|
// JavaScript files
|
||||||
|
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
||||||
|
return JS_RE.test(pathname)
|
||||||
|
}
|
@ -1,18 +1,14 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
|
||||||
import type { Unimport } from 'unimport'
|
import type { Unimport } from 'unimport'
|
||||||
import { normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
import type { ImportsOptions } from 'nuxt/schema'
|
import type { ImportsOptions } from 'nuxt/schema'
|
||||||
|
import { isJS, isVue } from '../core/utils'
|
||||||
|
|
||||||
export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ctx: Unimport, options: Partial<ImportsOptions>, sourcemap?: boolean }) => {
|
export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ctx: Unimport, options: Partial<ImportsOptions>, sourcemap?: boolean }) => {
|
||||||
return {
|
return {
|
||||||
name: 'nuxt:imports-transform',
|
name: 'nuxt:imports-transform',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
transformInclude (id) {
|
transformInclude (id) {
|
||||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
|
||||||
const query = parseQuery(search)
|
|
||||||
|
|
||||||
// Included
|
// Included
|
||||||
if (options.transform?.include?.some(pattern => id.match(pattern))) {
|
if (options.transform?.include?.some(pattern => id.match(pattern))) {
|
||||||
return true
|
return true
|
||||||
@ -23,18 +19,12 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ct
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vue files
|
// Vue files
|
||||||
if (
|
if (isVue(id, { type: ['script', 'template'] })) {
|
||||||
id.endsWith('.vue') ||
|
|
||||||
'macro' in query ||
|
|
||||||
('vue' in query && (query.type === 'template' || query.type === 'script' || 'setup' in query))
|
|
||||||
) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// JavaScript files
|
// JavaScript files
|
||||||
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
return isJS(id)
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
async transform (code, id) {
|
async transform (code, id) {
|
||||||
id = normalize(id)
|
id = normalize(id)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
|
||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
import { stripLiteral } from 'strip-literal'
|
import { stripLiteral } from 'strip-literal'
|
||||||
|
import { isJS, isVue } from '../../../nuxt/src/core/utils/plugins'
|
||||||
|
|
||||||
export interface PureAnnotationsOptions {
|
export interface PureAnnotationsOptions {
|
||||||
sourcemap: boolean
|
sourcemap: boolean
|
||||||
@ -16,18 +15,7 @@ export const pureAnnotationsPlugin = createUnplugin((options: PureAnnotationsOpt
|
|||||||
name: 'nuxt:pure-annotations',
|
name: 'nuxt:pure-annotations',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
transformInclude (id) {
|
transformInclude (id) {
|
||||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
return isVue(id, { type: ['script'] }) || isJS(id)
|
||||||
const { type } = parseQuery(search)
|
|
||||||
|
|
||||||
// vue files
|
|
||||||
if (pathname.endsWith('.vue') && (type === 'script' || !search)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// js files
|
|
||||||
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
transform (code) {
|
transform (code) {
|
||||||
if (!FUNCTION_RE_SINGLE.test(code)) { return }
|
if (!FUNCTION_RE_SINGLE.test(code)) { return }
|
||||||
|
5
test/fixtures/basic/pages/index.vue
vendored
5
test/fixtures/basic/pages/index.vue
vendored
@ -46,6 +46,11 @@ const config = useRuntimeConfig()
|
|||||||
|
|
||||||
const someValue = useState('val', () => 1)
|
const someValue = useState('val', () => 1)
|
||||||
|
|
||||||
|
const NestedSugarCounter = resolveComponent('NestedSugarCounter')
|
||||||
|
if (!NestedSugarCounter) {
|
||||||
|
throw new Error('Component not found')
|
||||||
|
}
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
alias: '/some-alias',
|
alias: '/some-alias',
|
||||||
other: ref('test'),
|
other: ref('test'),
|
||||||
|
Loading…
Reference in New Issue
Block a user