mirror of
https://github.com/unjs/unplugin.git
synced 2025-12-08 20:26:33 +00:00
feat: expose input source map for webpack-like bundlers (#562)
This commit is contained in:
parent
c1cf2213a8
commit
a8975f7010
@ -4,7 +4,7 @@ import { Buffer } from 'node:buffer'
|
||||
import { resolve } from 'node:path'
|
||||
import { parse } from '../utils/parse'
|
||||
|
||||
export function createBuildContext(compiler: Compiler, compilation: Compilation, loaderContext?: LoaderContext): UnpluginBuildContext {
|
||||
export function createBuildContext(compiler: Compiler, compilation: Compilation, loaderContext?: LoaderContext, inputSourceMap?: any): UnpluginBuildContext {
|
||||
return {
|
||||
getNativeBuildContext() {
|
||||
return {
|
||||
@ -12,6 +12,7 @@ export function createBuildContext(compiler: Compiler, compilation: Compilation,
|
||||
compiler,
|
||||
compilation,
|
||||
loaderContext,
|
||||
inputSourceMap,
|
||||
}
|
||||
},
|
||||
addWatchFile(file) {
|
||||
|
||||
@ -23,7 +23,7 @@ export default async function transform(
|
||||
const res = await handler.call(
|
||||
Object.assign(
|
||||
{},
|
||||
this._compilation && createBuildContext(this._compiler, this._compilation, this),
|
||||
this._compilation && createBuildContext(this._compiler, this._compilation, this, map),
|
||||
context,
|
||||
),
|
||||
source,
|
||||
|
||||
@ -50,9 +50,9 @@ export type TransformResult = string | { code: string, map?: SourceMapInput | So
|
||||
export interface ExternalIdResult { id: string, external?: boolean | undefined }
|
||||
|
||||
export type NativeBuildContext
|
||||
= { framework: 'webpack', compiler: WebpackCompiler, compilation?: WebpackCompilation | undefined, loaderContext?: WebpackLoaderContext<{ unpluginName: string }> | undefined }
|
||||
= { framework: 'webpack', compiler: WebpackCompiler, compilation?: WebpackCompilation | undefined, loaderContext?: WebpackLoaderContext<{ unpluginName: string }> | undefined, inputSourceMap?: any }
|
||||
| { framework: 'esbuild', build: PluginBuild }
|
||||
| { framework: 'rspack', compiler: RspackCompiler, compilation: RspackCompilation, loaderContext?: RspackLoaderContext | undefined }
|
||||
| { framework: 'rspack', compiler: RspackCompiler, compilation: RspackCompilation, loaderContext?: RspackLoaderContext | undefined, inputSourceMap?: any }
|
||||
| { framework: 'farm', context: FarmCompilationContext }
|
||||
| { framework: 'bun', build: BunPluginBuilder }
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ export function getSource(fileSource: string | Uint8Array): sources.RawSource {
|
||||
)
|
||||
}
|
||||
|
||||
export function createBuildContext(options: ContextOptions, compiler: Compiler, compilation?: Compilation, loaderContext?: LoaderContext<{ unpluginName: string }>): UnpluginBuildContext {
|
||||
export function createBuildContext(options: ContextOptions, compiler: Compiler, compilation?: Compilation, loaderContext?: LoaderContext<{ unpluginName: string }>, inputSourceMap?: any): UnpluginBuildContext {
|
||||
return {
|
||||
parse,
|
||||
addWatchFile(id) {
|
||||
@ -51,7 +51,7 @@ export function createBuildContext(options: ContextOptions, compiler: Compiler,
|
||||
return options.getWatchFiles()
|
||||
},
|
||||
getNativeBuildContext() {
|
||||
return { framework: 'webpack', compiler, compilation, loaderContext }
|
||||
return { framework: 'webpack', compiler, compilation, loaderContext, inputSourceMap }
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ export default async function transform(this: LoaderContext<any>, source: string
|
||||
getWatchFiles: () => {
|
||||
return this.getDependencies()
|
||||
},
|
||||
}, this._compiler!, this._compilation, this), context),
|
||||
}, this._compiler!, this._compilation, this, map), context),
|
||||
source,
|
||||
this.resource,
|
||||
)
|
||||
|
||||
@ -7,14 +7,16 @@ describe('createBuildContext', () => {
|
||||
const compiler = { name: 'testCompiler' }
|
||||
const compilation = { name: 'testCompilation' }
|
||||
const loaderContext = { name: 'testLoaderContext' }
|
||||
const inputSourceMap = { name: 'inputSourceMap' }
|
||||
|
||||
const buildContext = createBuildContext(compiler as any, compilation as any, loaderContext as any)
|
||||
const buildContext = createBuildContext(compiler as any, compilation as any, loaderContext as any, inputSourceMap as any)
|
||||
|
||||
expect(buildContext.getNativeBuildContext!()).toEqual({
|
||||
framework: 'rspack',
|
||||
compiler,
|
||||
compilation,
|
||||
loaderContext,
|
||||
inputSourceMap,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { NativeBuildContext, UnpluginBuildContext } from '../../../../src/types'
|
||||
import { assert, describe, expect, it, vi } from 'vitest'
|
||||
import transform from '../../../../src/rspack/loaders/transform'
|
||||
|
||||
describe('transform', () => {
|
||||
@ -35,10 +36,6 @@ describe('transform', () => {
|
||||
const source = 'test source'
|
||||
const map = 'test map'
|
||||
|
||||
vi.mock('../../../../src/utils/filter', () => ({
|
||||
normalizeObjectHook: vi.fn(() => ({ handler: vi.fn().mockRejectedValue(new Error('Handler error')), filter: vi.fn().mockReturnValue(true) })),
|
||||
}))
|
||||
|
||||
await transform.call(mockLoaderContext, source, map)
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledWith(expect.any(Error))
|
||||
@ -63,13 +60,54 @@ describe('transform', () => {
|
||||
const source = 'test source'
|
||||
const map = 'test map'
|
||||
|
||||
vi.mock('../../../../src/utils/filter', () => ({
|
||||
normalizeObjectHook: vi.fn(() => ({ handler: vi.fn().mockRejectedValue(new Error('Handler error')), filter: vi.fn().mockReturnValue(true) })),
|
||||
}))
|
||||
|
||||
await transform.call(mockLoaderContext, source, map)
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledWith(expect.any(Error))
|
||||
expect(mockCallback.mock.calls[0][0].message).toBe('Handler error')
|
||||
})
|
||||
|
||||
it('should include input source map on native build context', async () => {
|
||||
const source = 'source code'
|
||||
const map = 'source map'
|
||||
const transformedCode = 'transformed code'
|
||||
const transformedMap = 'transformed map'
|
||||
|
||||
let handlerSource: string | undefined
|
||||
let handlerId: string | undefined
|
||||
let handlerNativeBuildContext: NativeBuildContext | undefined
|
||||
const handlerMock = vi.fn().mockImplementation(function (this: UnpluginBuildContext, source: string, id: string) {
|
||||
handlerSource = source
|
||||
handlerId = id
|
||||
handlerNativeBuildContext = this.getNativeBuildContext?.()
|
||||
return { code: transformedCode, map: transformedMap }
|
||||
})
|
||||
|
||||
const mockCallback = vi.fn()
|
||||
const mockLoaderContext = {
|
||||
async: () => mockCallback,
|
||||
query: {
|
||||
plugin: {
|
||||
transform: {
|
||||
handler: handlerMock,
|
||||
filter: vi.fn().mockReturnValue(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
resource: 'test resource',
|
||||
addDependency: vi.fn(),
|
||||
getDependencies: vi.fn().mockReturnValue(['/path/to/dependency']),
|
||||
_compiler: {},
|
||||
_compilation: {},
|
||||
} as any
|
||||
|
||||
await transform.call(mockLoaderContext as any, source, map)
|
||||
|
||||
expect(handlerMock).toHaveBeenCalled()
|
||||
expect(handlerSource).toBe(source)
|
||||
expect(handlerId).toBe(mockLoaderContext.resource)
|
||||
assert(handlerNativeBuildContext?.framework === 'rspack')
|
||||
expect(handlerNativeBuildContext?.inputSourceMap).toBe(map)
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledWith(null, transformedCode, transformedMap)
|
||||
})
|
||||
})
|
||||
|
||||
@ -46,6 +46,27 @@ describe('webpack - utils', () => {
|
||||
expect.anything(),
|
||||
)
|
||||
})
|
||||
|
||||
it('should add expected values to native build context', () => {
|
||||
const options = {
|
||||
addWatchFile: vi.fn(),
|
||||
getWatchFiles: vi.fn(() => ['file1.js']),
|
||||
}
|
||||
const compiler = { name: 'testCompiler' } as Compiler
|
||||
const compilation = { name: 'testCompilation' } as Compilation
|
||||
const loaderContext = { name: 'testLoaderContext' } as unknown as LoaderContext<{ unpluginName: string }>
|
||||
const inputSourceMap = { name: 'inputSourceMap' }
|
||||
|
||||
const buildContext = createBuildContext(options, compiler, compilation, loaderContext, inputSourceMap)
|
||||
|
||||
expect(buildContext.getNativeBuildContext!()).toEqual({
|
||||
framework: 'webpack',
|
||||
compiler,
|
||||
compilation,
|
||||
loaderContext,
|
||||
inputSourceMap,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('createContext', () => {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { NativeBuildContext, UnpluginBuildContext } from '../../../../src/types'
|
||||
import { assert, describe, expect, it, vi } from 'vitest'
|
||||
import transform from '../../../../src/webpack/loaders/transform'
|
||||
|
||||
describe('transform loader', () => {
|
||||
@ -104,4 +105,40 @@ describe('transform loader', () => {
|
||||
expect(handlerMock).toHaveBeenCalled()
|
||||
expect(mockCallback).toHaveBeenCalledWith(error)
|
||||
})
|
||||
|
||||
it('should include input source map on native build context', async () => {
|
||||
const source = 'source code'
|
||||
const map = 'source map'
|
||||
const transformedCode = 'transformed code'
|
||||
const transformedMap = 'transformed map'
|
||||
|
||||
let handlerSource: string | undefined
|
||||
let handlerId: string | undefined
|
||||
let handlerNativeBuildContext: NativeBuildContext | undefined
|
||||
const handlerMock = vi.fn().mockImplementation(function (this: UnpluginBuildContext, source: string, id: string) {
|
||||
handlerSource = source
|
||||
handlerId = id
|
||||
handlerNativeBuildContext = this.getNativeBuildContext?.()
|
||||
return { code: transformedCode, map: transformedMap }
|
||||
})
|
||||
|
||||
mockLoaderContext.query = {
|
||||
plugin: {
|
||||
transform: {
|
||||
handler: handlerMock,
|
||||
filter: vi.fn().mockReturnValue(true),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
await transform.call(mockLoaderContext as any, source, map)
|
||||
|
||||
expect(handlerMock).toHaveBeenCalled()
|
||||
expect(handlerSource).toBe(source)
|
||||
expect(handlerId).toBe(mockLoaderContext.resource)
|
||||
assert(handlerNativeBuildContext?.framework === 'webpack')
|
||||
expect(handlerNativeBuildContext?.inputSourceMap).toBe(map)
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledWith(null, transformedCode, transformedMap)
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user