A seemingly feasible solution (webpack external module)
xxXyh1908 opened this issue · comments
xxXyh1908 commented
A seemingly feasible solution (webpack external module)
async function handleResolveId(resolveData, callback) {
let id, external = false
// do resolveId =============================================
let resolveIdResult = await resolveId(
resolveData.request,
webpackResourceToVirtualId(resolveData.contextInfo?.issuer)
)
if (typeof resolveIdResult === 'string') {
id = resolveIdResult
} else if (resolveIdResult) {
id = resolveIdResult.id
external = resolveIdResult.external
}
// ==========================================================
if (id) {
if (external) {
// Redirect the original request to the external module
resolveData.request = id
// Generate external modules and return
return callback(null, new ExternalModule(id, 'commonjs2' /* module type */, id))
}
// Convert to the id (absolute path) recognized by webpack
let resource = virtualIdToWebpackResource(id)
// Redirect the original request to the resolved resource
resolveData.request = resource
// Write module code to `webpack-virtual-modules`
vfs.writeModule(resource, loadedCode)
}
}
compiler.hooks.normalModuleFactory.tap('name', (normalModuleFactory) => {
if (normalModuleFactory.hooks.resolve) {
// webpack5
normalModuleFactory.hooks.resolve.tapAsync('name', async (resolveData, callback) => {
let isCallbackCalled = false
await handleResolveId(resolveData, (...args) => {
isCallbackCalled = true
callback(...args)
})
if (!isCallbackCalled) {
callback(null)
}
})
} else {
// webpack4
// Function for generating modules from resolveData
const oldFactory = normalModuleFactory.hooks.factory.call(null)
// Override factory
normalModuleFactory.hooks.factory.tap('name', () => async (resolveData, callback) => {
let isCallbackCalled = false
await handleResolveId(resolveData, (...args) => {
isCallbackCalled = true
callback(...args)
})
if (!isCallbackCalled) {
oldFactory(resolveData, callback)
}
})
}
})