mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-30 23:32:38 +00:00
feat(bridge): better resolution within wp4 (with fallback) (#608)
This commit is contained in:
parent
699d58968f
commit
2b51af76d8
@ -17,6 +17,7 @@
|
|||||||
"@nuxt/postcss8": "^1.1.3",
|
"@nuxt/postcss8": "^1.1.3",
|
||||||
"@vue/composition-api": "^1.2.2",
|
"@vue/composition-api": "^1.2.2",
|
||||||
"acorn": "^8.5.0",
|
"acorn": "^8.5.0",
|
||||||
|
"enhanced-resolve": "^5.8.3",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"magic-string": "^0.25.7",
|
"magic-string": "^0.25.7",
|
||||||
|
@ -2,6 +2,7 @@ import { defineNuxtModule, installModule } from '@nuxt/kit'
|
|||||||
import { setupNitroBridge } from './nitro'
|
import { setupNitroBridge } from './nitro'
|
||||||
import { setupAppBridge } from './app'
|
import { setupAppBridge } from './app'
|
||||||
import { setupCAPIBridge } from './capi'
|
import { setupCAPIBridge } from './capi'
|
||||||
|
import { setupBetterResolve } from './resolve'
|
||||||
|
|
||||||
export default defineNuxtModule({
|
export default defineNuxtModule({
|
||||||
name: 'nuxt-bridge',
|
name: 'nuxt-bridge',
|
||||||
@ -13,7 +14,8 @@ export default defineNuxtModule({
|
|||||||
capi: {},
|
capi: {},
|
||||||
// TODO: Remove from 2.16
|
// TODO: Remove from 2.16
|
||||||
postcss8: true,
|
postcss8: true,
|
||||||
swc: true
|
swc: true,
|
||||||
|
resolve: true
|
||||||
},
|
},
|
||||||
async setup (opts, nuxt) {
|
async setup (opts, nuxt) {
|
||||||
if (opts.nitro) {
|
if (opts.nitro) {
|
||||||
@ -37,5 +39,8 @@ export default defineNuxtModule({
|
|||||||
if (opts.swc) {
|
if (opts.swc) {
|
||||||
await installModule(nuxt, require.resolve('nuxt-swc'))
|
await installModule(nuxt, require.resolve('nuxt-swc'))
|
||||||
}
|
}
|
||||||
|
if (opts.resolve) {
|
||||||
|
setupBetterResolve()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
79
packages/bridge/src/resolve.ts
Normal file
79
packages/bridge/src/resolve.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
import { promisify } from 'util'
|
||||||
|
import defu from 'defu'
|
||||||
|
|
||||||
|
import { CachedInputFileSystem, ResolveContext, ResolverFactory } from 'enhanced-resolve'
|
||||||
|
import { ResolveOptions } from 'webpack/types'
|
||||||
|
import { extendWebpackConfig, useNuxt } from '@nuxt/kit'
|
||||||
|
|
||||||
|
type UserResolveOptions = Parameters<typeof ResolverFactory['createResolver']>[0]
|
||||||
|
type ResolverOptions = Omit<UserResolveOptions, 'fileSystem'> & { fileSystem?: CachedInputFileSystem }
|
||||||
|
|
||||||
|
const DEFAULTS: UserResolveOptions = {
|
||||||
|
fileSystem: new CachedInputFileSystem(fs, 4000),
|
||||||
|
extensions: ['.ts', '.mjs', '.cjs', '.js', '.json'],
|
||||||
|
mainFields: ['module', 'main']
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abstracted resolver factory which can be used in rollup, webpack, etc.
|
||||||
|
const createResolver = (resolveOptions: ResolverOptions) => {
|
||||||
|
const options = defu(resolveOptions, DEFAULTS) as UserResolveOptions
|
||||||
|
const resolver = ResolverFactory.createResolver(options)
|
||||||
|
|
||||||
|
const root = options.roots?.[0] || '.'
|
||||||
|
|
||||||
|
const promisifiedResolve = promisify(resolver.resolve.bind(resolver)) as (context: object, path: string, request: string, resolveContext: ResolveContext) => Promise<string | false>
|
||||||
|
|
||||||
|
const resolve = (id: string, importer?: string) => promisifiedResolve({}, importer || root, id, {})
|
||||||
|
|
||||||
|
return { resolve, resolver }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webpack plugin to add first-level support for subpath exports, etc.
|
||||||
|
class EnhancedResolverPlugin {
|
||||||
|
resolver: ReturnType<typeof createResolver>
|
||||||
|
|
||||||
|
constructor (options: ResolverOptions) {
|
||||||
|
this.resolver = createResolver(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply (defaultResolver: any) {
|
||||||
|
const enhancedResolver = this.resolver
|
||||||
|
|
||||||
|
defaultResolver.getHook('resolve').tapPromise('EnhancedResolverPlugin', async (request) => {
|
||||||
|
const id = request.request
|
||||||
|
// Fall back to default webpack4 resolver if not a node_modules import
|
||||||
|
if (!id || !defaultResolver.isModule(id)) { return }
|
||||||
|
|
||||||
|
const importer = request.context?.issuer
|
||||||
|
try {
|
||||||
|
const result = await enhancedResolver.resolve(id, importer)
|
||||||
|
// Fall back to default webpack4 resolver if we can't resolve id
|
||||||
|
if (!result) { return }
|
||||||
|
request.path = result
|
||||||
|
return request
|
||||||
|
} catch {
|
||||||
|
// Fall back to default webpack4 resolver in the event of error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setupBetterResolve () {
|
||||||
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
|
extendWebpackConfig((config) => {
|
||||||
|
const isServer = config.name === 'server'
|
||||||
|
|
||||||
|
config.resolve = config.resolve || {}
|
||||||
|
config.resolve.plugins = config.resolve.plugins || []
|
||||||
|
|
||||||
|
config.resolve.plugins.push(new EnhancedResolverPlugin({
|
||||||
|
conditionNames: ['import', ...isServer ? ['node'] : []],
|
||||||
|
alias: config.resolve.alias,
|
||||||
|
modules: config.resolve.modules,
|
||||||
|
plugins: config.resolve.plugins as Array<Exclude<ResolveOptions['plugins'][number], string>>,
|
||||||
|
roots: config.resolve.roots || [nuxt.options.rootDir]
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
@ -1443,6 +1443,7 @@ __metadata:
|
|||||||
"@types/node-fetch": ^3.0.2
|
"@types/node-fetch": ^3.0.2
|
||||||
"@vue/composition-api": ^1.2.2
|
"@vue/composition-api": ^1.2.2
|
||||||
acorn: ^8.5.0
|
acorn: ^8.5.0
|
||||||
|
enhanced-resolve: ^5.8.3
|
||||||
estree-walker: ^2.0.2
|
estree-walker: ^2.0.2
|
||||||
fs-extra: ^10.0.0
|
fs-extra: ^10.0.0
|
||||||
magic-string: ^0.25.7
|
magic-string: ^0.25.7
|
||||||
|
Loading…
Reference in New Issue
Block a user