diff --git a/src/rspack/context.ts b/src/rspack/context.ts index 85c850a..a3ddba3 100644 --- a/src/rspack/context.ts +++ b/src/rspack/context.ts @@ -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) { diff --git a/src/rspack/loaders/transform.ts b/src/rspack/loaders/transform.ts index b0ac2a6..43cbd34 100644 --- a/src/rspack/loaders/transform.ts +++ b/src/rspack/loaders/transform.ts @@ -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, diff --git a/src/types.ts b/src/types.ts index 008fa55..382cdc3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -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 } diff --git a/src/webpack/context.ts b/src/webpack/context.ts index c4fda9d..7471d28 100644 --- a/src/webpack/context.ts +++ b/src/webpack/context.ts @@ -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 } }, } } diff --git a/src/webpack/loaders/transform.ts b/src/webpack/loaders/transform.ts index 2c2e1f3..247250d 100644 --- a/src/webpack/loaders/transform.ts +++ b/src/webpack/loaders/transform.ts @@ -24,7 +24,7 @@ export default async function transform(this: LoaderContext, source: string getWatchFiles: () => { return this.getDependencies() }, - }, this._compiler!, this._compilation, this), context), + }, this._compiler!, this._compilation, this, map), context), source, this.resource, ) diff --git a/test/unit-tests/rspack/context.test.ts b/test/unit-tests/rspack/context.test.ts index a2039db..dfce35a 100644 --- a/test/unit-tests/rspack/context.test.ts +++ b/test/unit-tests/rspack/context.test.ts @@ -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, }) }) diff --git a/test/unit-tests/rspack/loaders/transform.test.ts b/test/unit-tests/rspack/loaders/transform.test.ts index 48e1a2d..c6e85b3 100644 --- a/test/unit-tests/rspack/loaders/transform.test.ts +++ b/test/unit-tests/rspack/loaders/transform.test.ts @@ -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) + }) }) diff --git a/test/unit-tests/webpack/context.test.ts b/test/unit-tests/webpack/context.test.ts index 692eee2..3be96a0 100644 --- a/test/unit-tests/webpack/context.test.ts +++ b/test/unit-tests/webpack/context.test.ts @@ -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', () => { diff --git a/test/unit-tests/webpack/loaders/transform.test.ts b/test/unit-tests/webpack/loaders/transform.test.ts index 597587e..646c6c9 100644 --- a/test/unit-tests/webpack/loaders/transform.test.ts +++ b/test/unit-tests/webpack/loaders/transform.test.ts @@ -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) + }) })