@wyw-in-js/esbuild 2.0.0-alpha.0 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,6 +34,14 @@ esbuild
34
34
  .catch(() => process.exit(1));
35
35
  ```
36
36
 
37
+ ## Eval resolver modes
38
+
39
+ `eval.resolver: 'native'` and the native step of `eval.resolver: 'hybrid'` use `oxc-resolver` with automatic
40
+ `tsconfig.json` discovery. The plugin also forwards esbuild's top-level `alias` option.
41
+
42
+ Use `hybrid` when evaluated imports may rely on esbuild `onResolve` plugins. Use `native` only when `oxc-resolver` can
43
+ resolve all evaluated imports, or mirror plugin-only aliases in `oxcOptions.resolver.alias`.
44
+
37
45
  ## Additional Oxc transformations
38
46
 
39
47
  `@wyw-in-js/esbuild` runs WyW evaluation after an `esbuild.transform()` step, so transform options that must run on the
package/esm/index.mjs CHANGED
@@ -8,7 +8,7 @@ import { dirname, isAbsolute, join, parse, posix } from "path";
8
8
  import { transformSync as esbuildTransformSync } from "esbuild";
9
9
  import { transformSync as oxcTransformSync } from "oxc-transform";
10
10
  import { disposeEvalBroker, slugify, transform, TransformCacheCollection, createFileReporter, loadWywOptions } from "@wyw-in-js/transform";
11
- import { asyncResolverFactory } from "@wyw-in-js/shared";
11
+ import { asyncResolverFactory, mergeOxcResolverAlias, toNativeResolverAlias } from "@wyw-in-js/shared";
12
12
  const supportedFilterFlags = new Set([
13
13
  "i",
14
14
  "m",
@@ -36,6 +36,7 @@ export default function wywInJS({ debug, sourceMap, keepComments, oxcTransform,
36
36
  const cssResolveDirs = new Map();
37
37
  const warnedFilters = new Set();
38
38
  let warnedEmptyOxcOptions = false;
39
+ const nativeResolverAlias = toNativeResolverAlias(build.initialOptions.alias);
39
40
  const { emitter, onDone } = createFileReporter(debug ?? false);
40
41
  const warnOnUnsupportedFlags = (filterRegexp, removedFlags, sanitizedFlags) => {
41
42
  const key = `${filterRegexp.source}/${filterRegexp.flags}`;
@@ -155,7 +156,10 @@ export default function wywInJS({ debug, sourceMap, keepComments, oxcTransform,
155
156
  const transformServices = {
156
157
  options: {
157
158
  filename: args.path,
158
- pluginOptions: rest,
159
+ pluginOptions: {
160
+ ...rest,
161
+ oxcOptions: mergeOxcResolverAlias(rest.oxcOptions, nativeResolverAlias)
162
+ },
159
163
  prefixer,
160
164
  keepComments,
161
165
  preprocessor,
package/esm/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","names":[],"sources":["../src/index.ts"],"version":3,"sourcesContent":["/**\n * This file contains an esbuild loader for wyw-in-js.\n * It uses the transform.ts function to generate class names from source code,\n * returns transformed code without template literals and attaches generated source maps\n */\n\nimport { readFileSync } from 'fs';\nimport { dirname, isAbsolute, join, parse, posix } from 'path';\n\nimport type { Plugin, TransformOptions, Loader } from 'esbuild';\nimport { transformSync as esbuildTransformSync } from 'esbuild';\nimport {\n transformSync as oxcTransformSync,\n type TransformOptions as OxcTransformOptions,\n} from 'oxc-transform';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n disposeEvalBroker,\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n loadWywOptions,\n} from '@wyw-in-js/transform';\nimport { asyncResolverFactory } from '@wyw-in-js/shared';\n\ntype EsbuildPluginOptions = {\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n keepComments?: boolean | RegExp;\n oxcTransform?: boolean;\n prefixer?: boolean;\n preprocessor?: Preprocessor;\n sourceMap?: boolean;\n transformLibraries?: boolean;\n} & Partial<PluginOptions>;\n\nconst supportedFilterFlags = new Set(['i', 'm', 's']);\n\nconst nodeModulesRegex = /^(?:.*[\\\\/])?node_modules(?:[\\\\/].*)?$/;\n\nexport default function wywInJS({\n debug,\n sourceMap,\n keepComments,\n oxcTransform,\n prefixer,\n preprocessor,\n esbuildOptions,\n filter = /\\.(js|jsx|ts|tsx)$/,\n transformLibraries,\n ...rest\n}: EsbuildPluginOptions = {}): Plugin {\n let options = esbuildOptions;\n const cache = new TransformCacheCollection();\n const shouldRunOxcTransform = oxcTransform ?? false;\n const resolvedWywOptions = shouldRunOxcTransform\n ? loadWywOptions(rest)\n : null;\n const createAsyncResolver = asyncResolverFactory(\n async (\n resolved: {\n errors: unknown[];\n path: string;\n },\n token: string\n ): Promise<string> => {\n if (resolved.errors.length > 0) {\n throw new Error(`Cannot resolve ${token}`);\n }\n\n return resolved.path.replace(/\\\\/g, posix.sep);\n },\n (what, importer) => [\n what,\n {\n resolveDir: isAbsolute(importer)\n ? dirname(importer)\n : join(process.cwd(), dirname(importer)),\n kind: 'import-statement',\n },\n ]\n );\n return {\n name: 'wyw-in-js',\n setup(build) {\n const cssLookup = new Map<string, string>();\n const cssResolveDirs = new Map<string, string>();\n const warnedFilters = new Set<string>();\n let warnedEmptyOxcOptions = false;\n\n const { emitter, onDone } = createFileReporter(debug ?? false);\n\n const warnOnUnsupportedFlags = (\n filterRegexp: RegExp,\n removedFlags: string,\n sanitizedFlags: string\n ) => {\n const key = `${filterRegexp.source}/${filterRegexp.flags}`;\n if (warnedFilters.has(key)) {\n return;\n }\n warnedFilters.add(key);\n const nextFlags = sanitizedFlags || 'none';\n // eslint-disable-next-line no-console\n console.warn(\n `[wyw-in-js] Ignoring unsupported RegExp flags \"${removedFlags}\" ` +\n `in esbuild filter /${filterRegexp.source}/${filterRegexp.flags}. ` +\n `Using flags \"${nextFlags}\".`\n );\n };\n\n const sanitizeFilter = (filterRegexp: RegExp): RegExp => {\n const { flags } = filterRegexp;\n const sanitizedFlags = flags\n .split('')\n .filter((flag) => supportedFilterFlags.has(flag))\n .join('');\n if (sanitizedFlags === flags) {\n return filterRegexp;\n }\n const removedFlags = flags\n .split('')\n .filter((flag) => !supportedFilterFlags.has(flag))\n .join('');\n warnOnUnsupportedFlags(filterRegexp, removedFlags, sanitizedFlags);\n return new RegExp(filterRegexp.source, sanitizedFlags);\n };\n\n const getOxcLang = (loader: Loader): OxcTransformOptions['lang'] => {\n if (loader === 'tsx') return 'tsx';\n if (loader === 'ts') return 'ts';\n if (loader === 'jsx') return 'jsx';\n return 'js';\n };\n\n const asyncResolve = createAsyncResolver(build.resolve);\n\n build.onEnd(() => {\n onDone(process.cwd());\n disposeEvalBroker(cache);\n });\n\n build.onResolve({ filter: /\\.wyw\\.css$/ }, (args) => {\n return {\n namespace: 'wyw-in-js',\n path: args.path,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: 'wyw-in-js' }, (args) => {\n return {\n contents: cssLookup.get(args.path),\n loader: 'css',\n resolveDir: cssResolveDirs.get(args.path),\n };\n });\n\n const filterRegexp =\n typeof filter === 'string'\n ? new RegExp(filter)\n : sanitizeFilter(filter);\n\n build.onLoad({ filter: filterRegexp }, async (args) => {\n const rawCode = readFileSync(args.path, 'utf8');\n const { ext, name: filename } = parse(args.path);\n const loader = ext.replace(/^\\./, '') as Loader;\n\n if (!transformLibraries && nodeModulesRegex.test(args.path)) {\n return {\n loader,\n contents: rawCode,\n };\n }\n\n if (!options) {\n options = {};\n if ('jsxFactory' in build.initialOptions) {\n options.jsxFactory = build.initialOptions.jsxFactory;\n }\n if ('jsxFragment' in build.initialOptions) {\n options.jsxFragment = build.initialOptions.jsxFragment;\n }\n }\n\n let codeForEsbuild = rawCode;\n if (shouldRunOxcTransform) {\n if (!resolvedWywOptions) {\n throw new Error(\n '[wyw-in-js] Internal error: oxcTransform is enabled but WyW options are not initialized'\n );\n }\n\n const transformOptions = resolvedWywOptions.oxcOptions.transform as\n | OxcTransformOptions\n | undefined;\n if (!transformOptions || !Object.keys(transformOptions).length) {\n if (!warnedEmptyOxcOptions) {\n warnedEmptyOxcOptions = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[wyw-in-js] oxcTransform is enabled but oxcOptions.transform is empty; skipping Oxc transform.'\n );\n }\n } else {\n let oxcResult;\n try {\n oxcResult = oxcTransformSync(args.path, codeForEsbuild, {\n cwd: process.cwd(),\n lang: getOxcLang(loader),\n sourceType: 'module',\n sourcemap: sourceMap,\n ...transformOptions,\n });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `[wyw-in-js] Oxc transform failed for ${args.path}: ${message}`\n );\n }\n\n if (oxcResult.errors.length > 0) {\n const details = oxcResult.errors\n .map((error) =>\n error.codeframe\n ? `${error.message}\\n${error.codeframe}`\n : error.message\n )\n .join('\\n');\n throw new Error(\n `[wyw-in-js] Oxc transform failed for ${args.path}: ${details}`\n );\n }\n\n codeForEsbuild = oxcResult.code;\n\n if (sourceMap && oxcResult.map) {\n const oxcMap = Buffer.from(\n JSON.stringify(oxcResult.map)\n ).toString('base64');\n codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${oxcMap}*/`;\n }\n }\n }\n\n const transformed = esbuildTransformSync(codeForEsbuild, {\n ...options,\n sourcefile: args.path,\n sourcemap: sourceMap,\n loader,\n });\n let { code } = transformed;\n\n if (sourceMap) {\n const esbuildMap = Buffer.from(transformed.map).toString('base64');\n code += `/*# sourceMappingURL=data:application/json;base64,${esbuildMap}*/`;\n }\n\n const transformServices = {\n options: {\n filename: args.path,\n pluginOptions: rest,\n prefixer,\n keepComments,\n preprocessor,\n root: process.cwd(),\n },\n cache,\n eventEmitter: emitter,\n };\n\n const result = await transform(transformServices, code, asyncResolve);\n const resolveDir = dirname(args.path);\n\n if (typeof result.cssText === 'undefined') {\n return {\n contents: code,\n loader,\n resolveDir,\n };\n }\n\n if (result.cssText === '') {\n let contents = result.code;\n\n if (sourceMap && result.sourceMap) {\n const wywMap = Buffer.from(\n JSON.stringify(result.sourceMap)\n ).toString('base64');\n contents += `/*# sourceMappingURL=data:application/json;base64,${wywMap}*/`;\n }\n\n return {\n contents,\n loader,\n resolveDir,\n };\n }\n\n let { cssText } = result;\n\n const slug = slugify(cssText);\n const cssFilename = `${filename}_${slug}.wyw.css`;\n\n let contents = `import ${JSON.stringify(cssFilename)}; ${result.code}`;\n\n if (sourceMap && result.cssSourceMapText) {\n const map = Buffer.from(result.cssSourceMapText).toString('base64');\n cssText += `/*# sourceMappingURL=data:application/json;base64,${map}*/`;\n const wywMap = Buffer.from(JSON.stringify(result.sourceMap)).toString(\n 'base64'\n );\n contents += `/*# sourceMappingURL=data:application/json;base64,${wywMap}*/`;\n }\n\n cssLookup.set(cssFilename, cssText);\n cssResolveDirs.set(cssFilename, resolveDir);\n\n return {\n contents,\n loader,\n resolveDir,\n };\n });\n },\n };\n}\n"],"file":"index.mjs"}
1
+ {"mappings":"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","names":[],"sources":["../src/index.ts"],"version":3,"sourcesContent":["/**\n * This file contains an esbuild loader for wyw-in-js.\n * It uses the transform.ts function to generate class names from source code,\n * returns transformed code without template literals and attaches generated source maps\n */\n\nimport { readFileSync } from 'fs';\nimport { dirname, isAbsolute, join, parse, posix } from 'path';\n\nimport type { Plugin, TransformOptions, Loader } from 'esbuild';\nimport { transformSync as esbuildTransformSync } from 'esbuild';\nimport {\n transformSync as oxcTransformSync,\n type TransformOptions as OxcTransformOptions,\n} from 'oxc-transform';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n disposeEvalBroker,\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n loadWywOptions,\n} from '@wyw-in-js/transform';\nimport {\n asyncResolverFactory,\n mergeOxcResolverAlias,\n toNativeResolverAlias,\n} from '@wyw-in-js/shared';\n\ntype EsbuildPluginOptions = {\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n keepComments?: boolean | RegExp;\n oxcTransform?: boolean;\n prefixer?: boolean;\n preprocessor?: Preprocessor;\n sourceMap?: boolean;\n transformLibraries?: boolean;\n} & Partial<PluginOptions>;\n\nconst supportedFilterFlags = new Set(['i', 'm', 's']);\n\nconst nodeModulesRegex = /^(?:.*[\\\\/])?node_modules(?:[\\\\/].*)?$/;\n\nexport default function wywInJS({\n debug,\n sourceMap,\n keepComments,\n oxcTransform,\n prefixer,\n preprocessor,\n esbuildOptions,\n filter = /\\.(js|jsx|ts|tsx)$/,\n transformLibraries,\n ...rest\n}: EsbuildPluginOptions = {}): Plugin {\n let options = esbuildOptions;\n const cache = new TransformCacheCollection();\n const shouldRunOxcTransform = oxcTransform ?? false;\n const resolvedWywOptions = shouldRunOxcTransform\n ? loadWywOptions(rest)\n : null;\n const createAsyncResolver = asyncResolverFactory(\n async (\n resolved: {\n errors: unknown[];\n path: string;\n },\n token: string\n ): Promise<string> => {\n if (resolved.errors.length > 0) {\n throw new Error(`Cannot resolve ${token}`);\n }\n\n return resolved.path.replace(/\\\\/g, posix.sep);\n },\n (what, importer) => [\n what,\n {\n resolveDir: isAbsolute(importer)\n ? dirname(importer)\n : join(process.cwd(), dirname(importer)),\n kind: 'import-statement',\n },\n ]\n );\n return {\n name: 'wyw-in-js',\n setup(build) {\n const cssLookup = new Map<string, string>();\n const cssResolveDirs = new Map<string, string>();\n const warnedFilters = new Set<string>();\n let warnedEmptyOxcOptions = false;\n const nativeResolverAlias = toNativeResolverAlias(\n build.initialOptions.alias\n );\n\n const { emitter, onDone } = createFileReporter(debug ?? false);\n\n const warnOnUnsupportedFlags = (\n filterRegexp: RegExp,\n removedFlags: string,\n sanitizedFlags: string\n ) => {\n const key = `${filterRegexp.source}/${filterRegexp.flags}`;\n if (warnedFilters.has(key)) {\n return;\n }\n warnedFilters.add(key);\n const nextFlags = sanitizedFlags || 'none';\n // eslint-disable-next-line no-console\n console.warn(\n `[wyw-in-js] Ignoring unsupported RegExp flags \"${removedFlags}\" ` +\n `in esbuild filter /${filterRegexp.source}/${filterRegexp.flags}. ` +\n `Using flags \"${nextFlags}\".`\n );\n };\n\n const sanitizeFilter = (filterRegexp: RegExp): RegExp => {\n const { flags } = filterRegexp;\n const sanitizedFlags = flags\n .split('')\n .filter((flag) => supportedFilterFlags.has(flag))\n .join('');\n if (sanitizedFlags === flags) {\n return filterRegexp;\n }\n const removedFlags = flags\n .split('')\n .filter((flag) => !supportedFilterFlags.has(flag))\n .join('');\n warnOnUnsupportedFlags(filterRegexp, removedFlags, sanitizedFlags);\n return new RegExp(filterRegexp.source, sanitizedFlags);\n };\n\n const getOxcLang = (loader: Loader): OxcTransformOptions['lang'] => {\n if (loader === 'tsx') return 'tsx';\n if (loader === 'ts') return 'ts';\n if (loader === 'jsx') return 'jsx';\n return 'js';\n };\n\n const asyncResolve = createAsyncResolver(build.resolve);\n\n build.onEnd(() => {\n onDone(process.cwd());\n disposeEvalBroker(cache);\n });\n\n build.onResolve({ filter: /\\.wyw\\.css$/ }, (args) => {\n return {\n namespace: 'wyw-in-js',\n path: args.path,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: 'wyw-in-js' }, (args) => {\n return {\n contents: cssLookup.get(args.path),\n loader: 'css',\n resolveDir: cssResolveDirs.get(args.path),\n };\n });\n\n const filterRegexp =\n typeof filter === 'string'\n ? new RegExp(filter)\n : sanitizeFilter(filter);\n\n build.onLoad({ filter: filterRegexp }, async (args) => {\n const rawCode = readFileSync(args.path, 'utf8');\n const { ext, name: filename } = parse(args.path);\n const loader = ext.replace(/^\\./, '') as Loader;\n\n if (!transformLibraries && nodeModulesRegex.test(args.path)) {\n return {\n loader,\n contents: rawCode,\n };\n }\n\n if (!options) {\n options = {};\n if ('jsxFactory' in build.initialOptions) {\n options.jsxFactory = build.initialOptions.jsxFactory;\n }\n if ('jsxFragment' in build.initialOptions) {\n options.jsxFragment = build.initialOptions.jsxFragment;\n }\n }\n\n let codeForEsbuild = rawCode;\n if (shouldRunOxcTransform) {\n if (!resolvedWywOptions) {\n throw new Error(\n '[wyw-in-js] Internal error: oxcTransform is enabled but WyW options are not initialized'\n );\n }\n\n const transformOptions = resolvedWywOptions.oxcOptions.transform as\n | OxcTransformOptions\n | undefined;\n if (!transformOptions || !Object.keys(transformOptions).length) {\n if (!warnedEmptyOxcOptions) {\n warnedEmptyOxcOptions = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[wyw-in-js] oxcTransform is enabled but oxcOptions.transform is empty; skipping Oxc transform.'\n );\n }\n } else {\n let oxcResult;\n try {\n oxcResult = oxcTransformSync(args.path, codeForEsbuild, {\n cwd: process.cwd(),\n lang: getOxcLang(loader),\n sourceType: 'module',\n sourcemap: sourceMap,\n ...transformOptions,\n });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `[wyw-in-js] Oxc transform failed for ${args.path}: ${message}`\n );\n }\n\n if (oxcResult.errors.length > 0) {\n const details = oxcResult.errors\n .map((error) =>\n error.codeframe\n ? `${error.message}\\n${error.codeframe}`\n : error.message\n )\n .join('\\n');\n throw new Error(\n `[wyw-in-js] Oxc transform failed for ${args.path}: ${details}`\n );\n }\n\n codeForEsbuild = oxcResult.code;\n\n if (sourceMap && oxcResult.map) {\n const oxcMap = Buffer.from(\n JSON.stringify(oxcResult.map)\n ).toString('base64');\n codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${oxcMap}*/`;\n }\n }\n }\n\n const transformed = esbuildTransformSync(codeForEsbuild, {\n ...options,\n sourcefile: args.path,\n sourcemap: sourceMap,\n loader,\n });\n let { code } = transformed;\n\n if (sourceMap) {\n const esbuildMap = Buffer.from(transformed.map).toString('base64');\n code += `/*# sourceMappingURL=data:application/json;base64,${esbuildMap}*/`;\n }\n\n const transformServices = {\n options: {\n filename: args.path,\n pluginOptions: {\n ...rest,\n oxcOptions: mergeOxcResolverAlias(\n rest.oxcOptions,\n nativeResolverAlias\n ),\n },\n prefixer,\n keepComments,\n preprocessor,\n root: process.cwd(),\n },\n cache,\n eventEmitter: emitter,\n };\n\n const result = await transform(transformServices, code, asyncResolve);\n const resolveDir = dirname(args.path);\n\n if (typeof result.cssText === 'undefined') {\n return {\n contents: code,\n loader,\n resolveDir,\n };\n }\n\n if (result.cssText === '') {\n let contents = result.code;\n\n if (sourceMap && result.sourceMap) {\n const wywMap = Buffer.from(\n JSON.stringify(result.sourceMap)\n ).toString('base64');\n contents += `/*# sourceMappingURL=data:application/json;base64,${wywMap}*/`;\n }\n\n return {\n contents,\n loader,\n resolveDir,\n };\n }\n\n let { cssText } = result;\n\n const slug = slugify(cssText);\n const cssFilename = `${filename}_${slug}.wyw.css`;\n\n let contents = `import ${JSON.stringify(cssFilename)}; ${result.code}`;\n\n if (sourceMap && result.cssSourceMapText) {\n const map = Buffer.from(result.cssSourceMapText).toString('base64');\n cssText += `/*# sourceMappingURL=data:application/json;base64,${map}*/`;\n const wywMap = Buffer.from(JSON.stringify(result.sourceMap)).toString(\n 'base64'\n );\n contents += `/*# sourceMappingURL=data:application/json;base64,${wywMap}*/`;\n }\n\n cssLookup.set(cssFilename, cssText);\n cssResolveDirs.set(cssFilename, resolveDir);\n\n return {\n contents,\n loader,\n resolveDir,\n };\n });\n },\n };\n}\n"],"file":"index.mjs"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@wyw-in-js/esbuild",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0-alpha.1",
4
4
  "type": "module",
5
5
  "dependencies": {
6
- "@wyw-in-js/shared": "2.0.0-alpha.0",
7
- "@wyw-in-js/transform": "2.0.0-alpha.0",
6
+ "@wyw-in-js/shared": "2.0.0-alpha.1",
7
+ "@wyw-in-js/transform": "2.0.0-alpha.1",
8
8
  "oxc-transform": "0.127.0"
9
9
  },
10
10
  "devDependencies": {
package/types/index.js CHANGED
@@ -8,7 +8,7 @@ import { dirname, isAbsolute, join, parse, posix } from 'path';
8
8
  import { transformSync as esbuildTransformSync } from 'esbuild';
9
9
  import { transformSync as oxcTransformSync, } from 'oxc-transform';
10
10
  import { disposeEvalBroker, slugify, transform, TransformCacheCollection, createFileReporter, loadWywOptions, } from '@wyw-in-js/transform';
11
- import { asyncResolverFactory } from '@wyw-in-js/shared';
11
+ import { asyncResolverFactory, mergeOxcResolverAlias, toNativeResolverAlias, } from '@wyw-in-js/shared';
12
12
  const supportedFilterFlags = new Set(['i', 'm', 's']);
13
13
  const nodeModulesRegex = /^(?:.*[\\/])?node_modules(?:[\\/].*)?$/;
14
14
  export default function wywInJS({ debug, sourceMap, keepComments, oxcTransform, prefixer, preprocessor, esbuildOptions, filter = /\.(js|jsx|ts|tsx)$/, transformLibraries, ...rest } = {}) {
@@ -39,6 +39,7 @@ export default function wywInJS({ debug, sourceMap, keepComments, oxcTransform,
39
39
  const cssResolveDirs = new Map();
40
40
  const warnedFilters = new Set();
41
41
  let warnedEmptyOxcOptions = false;
42
+ const nativeResolverAlias = toNativeResolverAlias(build.initialOptions.alias);
42
43
  const { emitter, onDone } = createFileReporter(debug ?? false);
43
44
  const warnOnUnsupportedFlags = (filterRegexp, removedFlags, sanitizedFlags) => {
44
45
  const key = `${filterRegexp.source}/${filterRegexp.flags}`;
@@ -174,7 +175,10 @@ export default function wywInJS({ debug, sourceMap, keepComments, oxcTransform,
174
175
  const transformServices = {
175
176
  options: {
176
177
  filename: args.path,
177
- pluginOptions: rest,
178
+ pluginOptions: {
179
+ ...rest,
180
+ oxcOptions: mergeOxcResolverAlias(rest.oxcOptions, nativeResolverAlias),
181
+ },
178
182
  prefixer,
179
183
  keepComments,
180
184
  preprocessor,