@wyw-in-js/esbuild 0.8.0 → 1.0.0

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
@@ -11,6 +11,8 @@ npm i -D @wyw-in-js/esbuild
11
11
  yarn add --dev @wyw-in-js/esbuild
12
12
  # pnpm
13
13
  pnpm add -D @wyw-in-js/esbuild
14
+ # bun
15
+ bun add -d @wyw-in-js/esbuild
14
16
  ```
15
17
 
16
18
  ## Usage
@@ -32,4 +34,52 @@ esbuild
32
34
  .catch(() => process.exit(1));
33
35
  ```
34
36
 
37
+ ## Additional Babel transformations
38
+
39
+ `@wyw-in-js/esbuild` runs WyW evaluation after an `esbuild.transform()` step, so some Babel plugins may not be able to
40
+ operate on the original TS/JSX source.
41
+
42
+ Enable `babelTransform` to apply `babelOptions` to the original source code before the esbuild/WyW pipeline:
43
+
44
+ ```js
45
+ wyw({
46
+ babelTransform: true,
47
+ babelOptions: {
48
+ plugins: [
49
+ // your custom Babel plugins
50
+ ],
51
+ },
52
+ });
53
+ ```
54
+
55
+ Order: `Babel(source) → esbuild.transform() → WyW transform`.
56
+
57
+ Note: `babelOptions` are still used by WyW when parsing/evaluating modules. With `babelTransform: true`, the same plugins
58
+ may run both before esbuild and again during WyW's internal Babel stage. Prefer idempotent plugins.
59
+
60
+ This is an opt-in feature and may increase build times, so it's recommended to keep `filter` narrow.
61
+
62
+ ## Disabling vendor prefixing
63
+
64
+ Stylis adds vendor-prefixed CSS by default. To disable it (and reduce CSS size), pass `prefixer: false`:
65
+
66
+ ```js
67
+ wyw({
68
+ prefixer: false,
69
+ });
70
+ ```
71
+
72
+ ## Transforming libraries in `node_modules`
73
+
74
+ By default, the esbuild plugin skips transforming files from `node_modules` for performance.
75
+
76
+ To transform a specific library, enable `transformLibraries` and narrow `filter`:
77
+
78
+ ```js
79
+ wyw({
80
+ transformLibraries: true,
81
+ filter: /node_modules\\/(?:@fluentui)\\//,
82
+ });
83
+ ```
84
+
35
85
  To get details about supported options by the plugin, please check [documentation](https://wyw-in-js.dev/bundlers/esbuild).
package/esm/index.mjs CHANGED
@@ -6,40 +6,80 @@
6
6
 
7
7
  import { readFileSync } from 'fs';
8
8
  import { dirname, isAbsolute, join, parse, posix } from 'path';
9
- import { transformSync } from 'esbuild';
10
- import { slugify, transform, TransformCacheCollection, createFileReporter } from '@wyw-in-js/transform';
9
+ import { transformSync as esbuildTransformSync } from 'esbuild';
10
+ import { slugify, transform, TransformCacheCollection, createFileReporter, loadWywOptions, withDefaultServices } from '@wyw-in-js/transform';
11
+ import { asyncResolverFactory } from '@wyw-in-js/shared';
12
+ const supportedFilterFlags = new Set(['i', 'm', 's']);
11
13
  const nodeModulesRegex = /^(?:.*[\\/])?node_modules(?:[\\/].*)?$/;
12
14
  export default function wywInJS({
15
+ babelTransform,
13
16
  debug,
14
17
  sourceMap,
18
+ keepComments,
15
19
  prefixer,
16
20
  preprocessor,
17
21
  esbuildOptions,
18
22
  filter = /\.(js|jsx|ts|tsx)$/,
23
+ transformLibraries,
19
24
  ...rest
20
25
  } = {}) {
21
26
  let options = esbuildOptions;
22
27
  const cache = new TransformCacheCollection();
28
+ let resolvedWywOptions = null;
29
+ let babel = null;
30
+ if (babelTransform) {
31
+ resolvedWywOptions = loadWywOptions(rest);
32
+ babel = withDefaultServices({
33
+ options: {
34
+ filename: '<wyw-in-js/esbuild>',
35
+ pluginOptions: resolvedWywOptions,
36
+ root: process.cwd()
37
+ }
38
+ }).babel;
39
+ }
40
+ const createAsyncResolver = asyncResolverFactory(async (resolved, token) => {
41
+ if (resolved.errors.length > 0) {
42
+ throw new Error(`Cannot resolve ${token}`);
43
+ }
44
+ return resolved.path.replace(/\\/g, posix.sep);
45
+ }, (what, importer) => [what, {
46
+ resolveDir: isAbsolute(importer) ? dirname(importer) : join(process.cwd(), dirname(importer)),
47
+ kind: 'import-statement'
48
+ }]);
23
49
  return {
24
50
  name: 'wyw-in-js',
25
51
  setup(build) {
26
52
  const cssLookup = new Map();
27
53
  const cssResolveDirs = new Map();
54
+ const warnedFilters = new Set();
55
+ let warnedEmptyBabelOptions = false;
28
56
  const {
29
57
  emitter,
30
58
  onDone
31
59
  } = createFileReporter(debug ?? false);
32
- const asyncResolve = async (token, importer) => {
33
- const context = isAbsolute(importer) ? dirname(importer) : join(process.cwd(), dirname(importer));
34
- const result = await build.resolve(token, {
35
- resolveDir: context,
36
- kind: 'import-statement'
37
- });
38
- if (result.errors.length > 0) {
39
- throw new Error(`Cannot resolve ${token}`);
60
+ const warnOnUnsupportedFlags = (filterRegexp, removedFlags, sanitizedFlags) => {
61
+ const key = `${filterRegexp.source}/${filterRegexp.flags}`;
62
+ if (warnedFilters.has(key)) {
63
+ return;
64
+ }
65
+ warnedFilters.add(key);
66
+ const nextFlags = sanitizedFlags || 'none';
67
+ // eslint-disable-next-line no-console
68
+ console.warn(`[wyw-in-js] Ignoring unsupported RegExp flags "${removedFlags}" ` + `in esbuild filter /${filterRegexp.source}/${filterRegexp.flags}. ` + `Using flags "${nextFlags}".`);
69
+ };
70
+ const sanitizeFilter = filterRegexp => {
71
+ const {
72
+ flags
73
+ } = filterRegexp;
74
+ const sanitizedFlags = flags.split('').filter(flag => supportedFilterFlags.has(flag)).join('');
75
+ if (sanitizedFlags === flags) {
76
+ return filterRegexp;
40
77
  }
41
- return result.path.replace(/\\/g, posix.sep);
78
+ const removedFlags = flags.split('').filter(flag => !supportedFilterFlags.has(flag)).join('');
79
+ warnOnUnsupportedFlags(filterRegexp, removedFlags, sanitizedFlags);
80
+ return new RegExp(filterRegexp.source, sanitizedFlags);
42
81
  };
82
+ const asyncResolve = createAsyncResolver(build.resolve);
43
83
  build.onEnd(() => {
44
84
  onDone(process.cwd());
45
85
  });
@@ -61,7 +101,7 @@ export default function wywInJS({
61
101
  resolveDir: cssResolveDirs.get(args.path)
62
102
  };
63
103
  });
64
- const filterRegexp = typeof filter === 'string' ? new RegExp(filter) : filter;
104
+ const filterRegexp = typeof filter === 'string' ? new RegExp(filter) : sanitizeFilter(filter);
65
105
  build.onLoad({
66
106
  filter: filterRegexp
67
107
  }, async args => {
@@ -71,7 +111,7 @@ export default function wywInJS({
71
111
  name: filename
72
112
  } = parse(args.path);
73
113
  const loader = ext.replace(/^\./, '');
74
- if (nodeModulesRegex.test(args.path)) {
114
+ if (!transformLibraries && nodeModulesRegex.test(args.path)) {
75
115
  return {
76
116
  loader,
77
117
  contents: rawCode
@@ -86,7 +126,45 @@ export default function wywInJS({
86
126
  options.jsxFragment = build.initialOptions.jsxFragment;
87
127
  }
88
128
  }
89
- const transformed = transformSync(rawCode, {
129
+ let codeForEsbuild = rawCode;
130
+ if (babelTransform) {
131
+ if (!babel || !resolvedWywOptions) {
132
+ throw new Error('[wyw-in-js] Internal error: babelTransform is enabled but Babel services are not initialized');
133
+ }
134
+ const {
135
+ babelOptions
136
+ } = resolvedWywOptions;
137
+ if (!Object.keys(babelOptions).length) {
138
+ if (!warnedEmptyBabelOptions) {
139
+ warnedEmptyBabelOptions = true;
140
+ // eslint-disable-next-line no-console
141
+ console.warn('[wyw-in-js] babelTransform is enabled but babelOptions is empty; skipping Babel transform.');
142
+ }
143
+ } else {
144
+ let babelResult;
145
+ try {
146
+ babelResult = babel.transformSync(codeForEsbuild, {
147
+ ...babelOptions,
148
+ ast: false,
149
+ filename: args.path,
150
+ sourceFileName: args.path,
151
+ sourceMaps: sourceMap
152
+ });
153
+ } catch (e) {
154
+ const message = e instanceof Error ? e.message : String(e);
155
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}: ${message}`);
156
+ }
157
+ if (!babelResult?.code) {
158
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}`);
159
+ }
160
+ codeForEsbuild = babelResult.code;
161
+ if (sourceMap && babelResult.map) {
162
+ const babelMap = Buffer.from(JSON.stringify(babelResult.map)).toString('base64');
163
+ codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${babelMap}*/`;
164
+ }
165
+ }
166
+ }
167
+ const transformed = esbuildTransformSync(codeForEsbuild, {
90
168
  ...options,
91
169
  sourcefile: args.path,
92
170
  sourcemap: sourceMap,
@@ -104,6 +182,7 @@ export default function wywInJS({
104
182
  filename: args.path,
105
183
  pluginOptions: rest,
106
184
  prefixer,
185
+ keepComments,
107
186
  preprocessor,
108
187
  root: process.cwd()
109
188
  },
package/esm/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["readFileSync","dirname","isAbsolute","join","parse","posix","transformSync","slugify","transform","TransformCacheCollection","createFileReporter","nodeModulesRegex","wywInJS","debug","sourceMap","prefixer","preprocessor","esbuildOptions","filter","rest","options","cache","name","setup","build","cssLookup","Map","cssResolveDirs","emitter","onDone","asyncResolve","token","importer","context","process","cwd","result","resolve","resolveDir","kind","errors","length","Error","path","replace","sep","onEnd","onResolve","args","namespace","onLoad","contents","get","loader","filterRegexp","RegExp","rawCode","ext","filename","test","initialOptions","jsxFactory","jsxFragment","transformed","sourcefile","sourcemap","code","esbuildMap","Buffer","from","map","toString","transformServices","pluginOptions","root","eventEmitter","cssText","slug","cssFilename","JSON","stringify","cssSourceMapText","wywMap","set"],"sources":["../src/index.ts"],"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 } from 'esbuild';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n} from '@wyw-in-js/transform';\n\ntype EsbuildPluginOptions = {\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n prefixer?: boolean;\n preprocessor?: Preprocessor;\n sourceMap?: boolean;\n} & Partial<PluginOptions>;\n\nconst nodeModulesRegex = /^(?:.*[\\\\/])?node_modules(?:[\\\\/].*)?$/;\n\nexport default function wywInJS({\n debug,\n sourceMap,\n prefixer,\n preprocessor,\n esbuildOptions,\n filter = /\\.(js|jsx|ts|tsx)$/,\n ...rest\n}: EsbuildPluginOptions = {}): Plugin {\n let options = esbuildOptions;\n const cache = new TransformCacheCollection();\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\n const { emitter, onDone } = createFileReporter(debug ?? false);\n\n const asyncResolve = async (\n token: string,\n importer: string\n ): Promise<string> => {\n const context = isAbsolute(importer)\n ? dirname(importer)\n : join(process.cwd(), dirname(importer));\n\n const result = await build.resolve(token, {\n resolveDir: context,\n kind: 'import-statement',\n });\n\n if (result.errors.length > 0) {\n throw new Error(`Cannot resolve ${token}`);\n }\n\n return result.path.replace(/\\\\/g, posix.sep);\n };\n\n build.onEnd(() => {\n onDone(process.cwd());\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' ? new RegExp(filter) : 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 (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 const transformed = transformSync(rawCode, {\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 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 (!result.cssText) {\n return {\n contents: code,\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"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["readFileSync","dirname","isAbsolute","join","parse","posix","transformSync","esbuildTransformSync","slugify","transform","TransformCacheCollection","createFileReporter","loadWywOptions","withDefaultServices","asyncResolverFactory","supportedFilterFlags","Set","nodeModulesRegex","wywInJS","babelTransform","debug","sourceMap","keepComments","prefixer","preprocessor","esbuildOptions","filter","transformLibraries","rest","options","cache","resolvedWywOptions","babel","filename","pluginOptions","root","process","cwd","createAsyncResolver","resolved","token","errors","length","Error","path","replace","sep","what","importer","resolveDir","kind","name","setup","build","cssLookup","Map","cssResolveDirs","warnedFilters","warnedEmptyBabelOptions","emitter","onDone","warnOnUnsupportedFlags","filterRegexp","removedFlags","sanitizedFlags","key","source","flags","has","add","nextFlags","console","warn","sanitizeFilter","split","flag","RegExp","asyncResolve","resolve","onEnd","onResolve","args","namespace","onLoad","contents","get","loader","rawCode","ext","test","initialOptions","jsxFactory","jsxFragment","codeForEsbuild","babelOptions","Object","keys","babelResult","ast","sourceFileName","sourceMaps","e","message","String","code","map","babelMap","Buffer","from","JSON","stringify","toString","transformed","sourcefile","sourcemap","esbuildMap","transformServices","eventEmitter","result","cssText","slug","cssFilename","cssSourceMapText","wywMap","set"],"sources":["../src/index.ts"],"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';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n loadWywOptions,\n withDefaultServices,\n} from '@wyw-in-js/transform';\nimport { asyncResolverFactory } from '@wyw-in-js/shared';\n\ntype EsbuildPluginOptions = {\n babelTransform?: boolean;\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n keepComments?: boolean | RegExp;\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 babelTransform,\n debug,\n sourceMap,\n keepComments,\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 let resolvedWywOptions: ReturnType<typeof loadWywOptions> | null = null;\n let babel: ReturnType<typeof withDefaultServices>['babel'] | null = null;\n if (babelTransform) {\n resolvedWywOptions = loadWywOptions(rest);\n babel = withDefaultServices({\n options: {\n filename: '<wyw-in-js/esbuild>',\n pluginOptions: resolvedWywOptions,\n root: process.cwd(),\n },\n }).babel;\n }\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 warnedEmptyBabelOptions = 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 asyncResolve = createAsyncResolver(build.resolve);\n\n build.onEnd(() => {\n onDone(process.cwd());\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 (babelTransform) {\n if (!babel || !resolvedWywOptions) {\n throw new Error(\n '[wyw-in-js] Internal error: babelTransform is enabled but Babel services are not initialized'\n );\n }\n\n const { babelOptions } = resolvedWywOptions;\n if (!Object.keys(babelOptions).length) {\n if (!warnedEmptyBabelOptions) {\n warnedEmptyBabelOptions = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[wyw-in-js] babelTransform is enabled but babelOptions is empty; skipping Babel transform.'\n );\n }\n } else {\n let babelResult;\n try {\n babelResult = babel.transformSync(codeForEsbuild, {\n ...babelOptions,\n ast: false,\n filename: args.path,\n sourceFileName: args.path,\n sourceMaps: sourceMap,\n });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `[wyw-in-js] Babel transform failed for ${args.path}: ${message}`\n );\n }\n\n if (!babelResult?.code) {\n throw new Error(\n `[wyw-in-js] Babel transform failed for ${args.path}`\n );\n }\n\n codeForEsbuild = babelResult.code;\n\n if (sourceMap && babelResult.map) {\n const babelMap = Buffer.from(\n JSON.stringify(babelResult.map)\n ).toString('base64');\n codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${babelMap}*/`;\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 (!result.cssText) {\n return {\n contents: code,\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"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,YAAY,QAAQ,IAAI;AACjC,SAASC,OAAO,EAAEC,UAAU,EAAEC,IAAI,EAAEC,KAAK,EAAEC,KAAK,QAAQ,MAAM;AAG9D,SAASC,aAAa,IAAIC,oBAAoB,QAAQ,SAAS;AAO/D,SACEC,OAAO,EACPC,SAAS,EACTC,wBAAwB,EACxBC,kBAAkB,EAClBC,cAAc,EACdC,mBAAmB,QACd,sBAAsB;AAC7B,SAASC,oBAAoB,QAAQ,mBAAmB;AAcxD,MAAMC,oBAAoB,GAAG,IAAIC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAErD,MAAMC,gBAAgB,GAAG,wCAAwC;AAEjE,eAAe,SAASC,OAAOA,CAAC;EAC9BC,cAAc;EACdC,KAAK;EACLC,SAAS;EACTC,YAAY;EACZC,QAAQ;EACRC,YAAY;EACZC,cAAc;EACdC,MAAM,GAAG,oBAAoB;EAC7BC,kBAAkB;EAClB,GAAGC;AACiB,CAAC,GAAG,CAAC,CAAC,EAAU;EACpC,IAAIC,OAAO,GAAGJ,cAAc;EAC5B,MAAMK,KAAK,GAAG,IAAIpB,wBAAwB,CAAC,CAAC;EAC5C,IAAIqB,kBAA4D,GAAG,IAAI;EACvE,IAAIC,KAA6D,GAAG,IAAI;EACxE,IAAIb,cAAc,EAAE;IAClBY,kBAAkB,GAAGnB,cAAc,CAACgB,IAAI,CAAC;IACzCI,KAAK,GAAGnB,mBAAmB,CAAC;MAC1BgB,OAAO,EAAE;QACPI,QAAQ,EAAE,qBAAqB;QAC/BC,aAAa,EAAEH,kBAAkB;QACjCI,IAAI,EAAEC,OAAO,CAACC,GAAG,CAAC;MACpB;IACF,CAAC,CAAC,CAACL,KAAK;EACV;EACA,MAAMM,mBAAmB,GAAGxB,oBAAoB,CAC9C,OACEyB,QAGC,EACDC,KAAa,KACO;IACpB,IAAID,QAAQ,CAACE,MAAM,CAACC,MAAM,GAAG,CAAC,EAAE;MAC9B,MAAM,IAAIC,KAAK,CAAC,kBAAkBH,KAAK,EAAE,CAAC;IAC5C;IAEA,OAAOD,QAAQ,CAACK,IAAI,CAACC,OAAO,CAAC,KAAK,EAAExC,KAAK,CAACyC,GAAG,CAAC;EAChD,CAAC,EACD,CAACC,IAAI,EAAEC,QAAQ,KAAK,CAClBD,IAAI,EACJ;IACEE,UAAU,EAAE/C,UAAU,CAAC8C,QAAQ,CAAC,GAC5B/C,OAAO,CAAC+C,QAAQ,CAAC,GACjB7C,IAAI,CAACiC,OAAO,CAACC,GAAG,CAAC,CAAC,EAAEpC,OAAO,CAAC+C,QAAQ,CAAC,CAAC;IAC1CE,IAAI,EAAE;EACR,CAAC,CAEL,CAAC;EACD,OAAO;IACLC,IAAI,EAAE,WAAW;IACjBC,KAAKA,CAACC,KAAK,EAAE;MACX,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAAiB,CAAC;MAC3C,MAAMC,cAAc,GAAG,IAAID,GAAG,CAAiB,CAAC;MAChD,MAAME,aAAa,GAAG,IAAIzC,GAAG,CAAS,CAAC;MACvC,IAAI0C,uBAAuB,GAAG,KAAK;MAEnC,MAAM;QAAEC,OAAO;QAAEC;MAAO,CAAC,GAAGjD,kBAAkB,CAACS,KAAK,IAAI,KAAK,CAAC;MAE9D,MAAMyC,sBAAsB,GAAGA,CAC7BC,YAAoB,EACpBC,YAAoB,EACpBC,cAAsB,KACnB;QACH,MAAMC,GAAG,GAAG,GAAGH,YAAY,CAACI,MAAM,IAAIJ,YAAY,CAACK,KAAK,EAAE;QAC1D,IAAIV,aAAa,CAACW,GAAG,CAACH,GAAG,CAAC,EAAE;UAC1B;QACF;QACAR,aAAa,CAACY,GAAG,CAACJ,GAAG,CAAC;QACtB,MAAMK,SAAS,GAAGN,cAAc,IAAI,MAAM;QAC1C;QACAO,OAAO,CAACC,IAAI,CACV,kDAAkDT,YAAY,IAAI,GAChE,sBAAsBD,YAAY,CAACI,MAAM,IAAIJ,YAAY,CAACK,KAAK,IAAI,GACnE,gBAAgBG,SAAS,IAC7B,CAAC;MACH,CAAC;MAED,MAAMG,cAAc,GAAIX,YAAoB,IAAa;QACvD,MAAM;UAAEK;QAAM,CAAC,GAAGL,YAAY;QAC9B,MAAME,cAAc,GAAGG,KAAK,CACzBO,KAAK,CAAC,EAAE,CAAC,CACThD,MAAM,CAAEiD,IAAI,IAAK5D,oBAAoB,CAACqD,GAAG,CAACO,IAAI,CAAC,CAAC,CAChDxE,IAAI,CAAC,EAAE,CAAC;QACX,IAAI6D,cAAc,KAAKG,KAAK,EAAE;UAC5B,OAAOL,YAAY;QACrB;QACA,MAAMC,YAAY,GAAGI,KAAK,CACvBO,KAAK,CAAC,EAAE,CAAC,CACThD,MAAM,CAAEiD,IAAI,IAAK,CAAC5D,oBAAoB,CAACqD,GAAG,CAACO,IAAI,CAAC,CAAC,CACjDxE,IAAI,CAAC,EAAE,CAAC;QACX0D,sBAAsB,CAACC,YAAY,EAAEC,YAAY,EAAEC,cAAc,CAAC;QAClE,OAAO,IAAIY,MAAM,CAACd,YAAY,CAACI,MAAM,EAAEF,cAAc,CAAC;MACxD,CAAC;MAED,MAAMa,YAAY,GAAGvC,mBAAmB,CAACe,KAAK,CAACyB,OAAO,CAAC;MAEvDzB,KAAK,CAAC0B,KAAK,CAAC,MAAM;QAChBnB,MAAM,CAACxB,OAAO,CAACC,GAAG,CAAC,CAAC,CAAC;MACvB,CAAC,CAAC;MAEFgB,KAAK,CAAC2B,SAAS,CAAC;QAAEtD,MAAM,EAAE;MAAc,CAAC,EAAGuD,IAAI,IAAK;QACnD,OAAO;UACLC,SAAS,EAAE,WAAW;UACtBtC,IAAI,EAAEqC,IAAI,CAACrC;QACb,CAAC;MACH,CAAC,CAAC;MAEFS,KAAK,CAAC8B,MAAM,CAAC;QAAEzD,MAAM,EAAE,IAAI;QAAEwD,SAAS,EAAE;MAAY,CAAC,EAAGD,IAAI,IAAK;QAC/D,OAAO;UACLG,QAAQ,EAAE9B,SAAS,CAAC+B,GAAG,CAACJ,IAAI,CAACrC,IAAI,CAAC;UAClC0C,MAAM,EAAE,KAAK;UACbrC,UAAU,EAAEO,cAAc,CAAC6B,GAAG,CAACJ,IAAI,CAACrC,IAAI;QAC1C,CAAC;MACH,CAAC,CAAC;MAEF,MAAMkB,YAAY,GAChB,OAAOpC,MAAM,KAAK,QAAQ,GACtB,IAAIkD,MAAM,CAAClD,MAAM,CAAC,GAClB+C,cAAc,CAAC/C,MAAM,CAAC;MAE5B2B,KAAK,CAAC8B,MAAM,CAAC;QAAEzD,MAAM,EAAEoC;MAAa,CAAC,EAAE,MAAOmB,IAAI,IAAK;QACrD,MAAMM,OAAO,GAAGvF,YAAY,CAACiF,IAAI,CAACrC,IAAI,EAAE,MAAM,CAAC;QAC/C,MAAM;UAAE4C,GAAG;UAAErC,IAAI,EAAElB;QAAS,CAAC,GAAG7B,KAAK,CAAC6E,IAAI,CAACrC,IAAI,CAAC;QAChD,MAAM0C,MAAM,GAAGE,GAAG,CAAC3C,OAAO,CAAC,KAAK,EAAE,EAAE,CAAW;QAE/C,IAAI,CAAClB,kBAAkB,IAAIV,gBAAgB,CAACwE,IAAI,CAACR,IAAI,CAACrC,IAAI,CAAC,EAAE;UAC3D,OAAO;YACL0C,MAAM;YACNF,QAAQ,EAAEG;UACZ,CAAC;QACH;QAEA,IAAI,CAAC1D,OAAO,EAAE;UACZA,OAAO,GAAG,CAAC,CAAC;UACZ,IAAI,YAAY,IAAIwB,KAAK,CAACqC,cAAc,EAAE;YACxC7D,OAAO,CAAC8D,UAAU,GAAGtC,KAAK,CAACqC,cAAc,CAACC,UAAU;UACtD;UACA,IAAI,aAAa,IAAItC,KAAK,CAACqC,cAAc,EAAE;YACzC7D,OAAO,CAAC+D,WAAW,GAAGvC,KAAK,CAACqC,cAAc,CAACE,WAAW;UACxD;QACF;QAEA,IAAIC,cAAc,GAAGN,OAAO;QAC5B,IAAIpE,cAAc,EAAE;UAClB,IAAI,CAACa,KAAK,IAAI,CAACD,kBAAkB,EAAE;YACjC,MAAM,IAAIY,KAAK,CACb,8FACF,CAAC;UACH;UAEA,MAAM;YAAEmD;UAAa,CAAC,GAAG/D,kBAAkB;UAC3C,IAAI,CAACgE,MAAM,CAACC,IAAI,CAACF,YAAY,CAAC,CAACpD,MAAM,EAAE;YACrC,IAAI,CAACgB,uBAAuB,EAAE;cAC5BA,uBAAuB,GAAG,IAAI;cAC9B;cACAa,OAAO,CAACC,IAAI,CACV,4FACF,CAAC;YACH;UACF,CAAC,MAAM;YACL,IAAIyB,WAAW;YACf,IAAI;cACFA,WAAW,GAAGjE,KAAK,CAAC1B,aAAa,CAACuF,cAAc,EAAE;gBAChD,GAAGC,YAAY;gBACfI,GAAG,EAAE,KAAK;gBACVjE,QAAQ,EAAEgD,IAAI,CAACrC,IAAI;gBACnBuD,cAAc,EAAElB,IAAI,CAACrC,IAAI;gBACzBwD,UAAU,EAAE/E;cACd,CAAC,CAAC;YACJ,CAAC,CAAC,OAAOgF,CAAC,EAAE;cACV,MAAMC,OAAO,GAAGD,CAAC,YAAY1D,KAAK,GAAG0D,CAAC,CAACC,OAAO,GAAGC,MAAM,CAACF,CAAC,CAAC;cAC1D,MAAM,IAAI1D,KAAK,CACb,0CAA0CsC,IAAI,CAACrC,IAAI,KAAK0D,OAAO,EACjE,CAAC;YACH;YAEA,IAAI,CAACL,WAAW,EAAEO,IAAI,EAAE;cACtB,MAAM,IAAI7D,KAAK,CACb,0CAA0CsC,IAAI,CAACrC,IAAI,EACrD,CAAC;YACH;YAEAiD,cAAc,GAAGI,WAAW,CAACO,IAAI;YAEjC,IAAInF,SAAS,IAAI4E,WAAW,CAACQ,GAAG,EAAE;cAChC,MAAMC,QAAQ,GAAGC,MAAM,CAACC,IAAI,CAC1BC,IAAI,CAACC,SAAS,CAACb,WAAW,CAACQ,GAAG,CAChC,CAAC,CAACM,QAAQ,CAAC,QAAQ,CAAC;cACpBlB,cAAc,IAAI,qDAAqDa,QAAQ,IAAI;YACrF;UACF;QACF;QAEA,MAAMM,WAAW,GAAGzG,oBAAoB,CAACsF,cAAc,EAAE;UACvD,GAAGhE,OAAO;UACVoF,UAAU,EAAEhC,IAAI,CAACrC,IAAI;UACrBsE,SAAS,EAAE7F,SAAS;UACpBiE;QACF,CAAC,CAAC;QACF,IAAI;UAAEkB;QAAK,CAAC,GAAGQ,WAAW;QAE1B,IAAI3F,SAAS,EAAE;UACb,MAAM8F,UAAU,GAAGR,MAAM,CAACC,IAAI,CAACI,WAAW,CAACP,GAAG,CAAC,CAACM,QAAQ,CAAC,QAAQ,CAAC;UAClEP,IAAI,IAAI,qDAAqDW,UAAU,IAAI;QAC7E;QAEA,MAAMC,iBAAiB,GAAG;UACxBvF,OAAO,EAAE;YACPI,QAAQ,EAAEgD,IAAI,CAACrC,IAAI;YACnBV,aAAa,EAAEN,IAAI;YACnBL,QAAQ;YACRD,YAAY;YACZE,YAAY;YACZW,IAAI,EAAEC,OAAO,CAACC,GAAG,CAAC;UACpB,CAAC;UACDP,KAAK;UACLuF,YAAY,EAAE1D;QAChB,CAAC;QAED,MAAM2D,MAAM,GAAG,MAAM7G,SAAS,CAAC2G,iBAAiB,EAAEZ,IAAI,EAAE3B,YAAY,CAAC;QACrE,MAAM5B,UAAU,GAAGhD,OAAO,CAACgF,IAAI,CAACrC,IAAI,CAAC;QAErC,IAAI,CAAC0E,MAAM,CAACC,OAAO,EAAE;UACnB,OAAO;YACLnC,QAAQ,EAAEoB,IAAI;YACdlB,MAAM;YACNrC;UACF,CAAC;QACH;QAEA,IAAI;UAAEsE;QAAQ,CAAC,GAAGD,MAAM;QAExB,MAAME,IAAI,GAAGhH,OAAO,CAAC+G,OAAO,CAAC;QAC7B,MAAME,WAAW,GAAG,GAAGxF,QAAQ,IAAIuF,IAAI,UAAU;QAEjD,IAAIpC,QAAQ,GAAG,UAAUyB,IAAI,CAACC,SAAS,CAACW,WAAW,CAAC,KAAKH,MAAM,CAACd,IAAI,EAAE;QAEtE,IAAInF,SAAS,IAAIiG,MAAM,CAACI,gBAAgB,EAAE;UACxC,MAAMjB,GAAG,GAAGE,MAAM,CAACC,IAAI,CAACU,MAAM,CAACI,gBAAgB,CAAC,CAACX,QAAQ,CAAC,QAAQ,CAAC;UACnEQ,OAAO,IAAI,qDAAqDd,GAAG,IAAI;UACvE,MAAMkB,MAAM,GAAGhB,MAAM,CAACC,IAAI,CAACC,IAAI,CAACC,SAAS,CAACQ,MAAM,CAACjG,SAAS,CAAC,CAAC,CAAC0F,QAAQ,CACnE,QACF,CAAC;UACD3B,QAAQ,IAAI,qDAAqDuC,MAAM,IAAI;QAC7E;QAEArE,SAAS,CAACsE,GAAG,CAACH,WAAW,EAAEF,OAAO,CAAC;QACnC/D,cAAc,CAACoE,GAAG,CAACH,WAAW,EAAExE,UAAU,CAAC;QAE3C,OAAO;UACLmC,QAAQ;UACRE,MAAM;UACNrC;QACF,CAAC;MACH,CAAC,CAAC;IACJ;EACF,CAAC;AACH","ignoreList":[]}
package/lib/index.js CHANGED
@@ -8,44 +8,84 @@ var _fs = require("fs");
8
8
  var _path = require("path");
9
9
  var _esbuild = require("esbuild");
10
10
  var _transform = require("@wyw-in-js/transform");
11
+ var _shared = require("@wyw-in-js/shared");
11
12
  /**
12
13
  * This file contains an esbuild loader for wyw-in-js.
13
14
  * It uses the transform.ts function to generate class names from source code,
14
15
  * returns transformed code without template literals and attaches generated source maps
15
16
  */
16
17
 
18
+ const supportedFilterFlags = new Set(['i', 'm', 's']);
17
19
  const nodeModulesRegex = /^(?:.*[\\/])?node_modules(?:[\\/].*)?$/;
18
20
  function wywInJS({
21
+ babelTransform,
19
22
  debug,
20
23
  sourceMap,
24
+ keepComments,
21
25
  prefixer,
22
26
  preprocessor,
23
27
  esbuildOptions,
24
28
  filter = /\.(js|jsx|ts|tsx)$/,
29
+ transformLibraries,
25
30
  ...rest
26
31
  } = {}) {
27
32
  let options = esbuildOptions;
28
33
  const cache = new _transform.TransformCacheCollection();
34
+ let resolvedWywOptions = null;
35
+ let babel = null;
36
+ if (babelTransform) {
37
+ resolvedWywOptions = (0, _transform.loadWywOptions)(rest);
38
+ babel = (0, _transform.withDefaultServices)({
39
+ options: {
40
+ filename: '<wyw-in-js/esbuild>',
41
+ pluginOptions: resolvedWywOptions,
42
+ root: process.cwd()
43
+ }
44
+ }).babel;
45
+ }
46
+ const createAsyncResolver = (0, _shared.asyncResolverFactory)(async (resolved, token) => {
47
+ if (resolved.errors.length > 0) {
48
+ throw new Error(`Cannot resolve ${token}`);
49
+ }
50
+ return resolved.path.replace(/\\/g, _path.posix.sep);
51
+ }, (what, importer) => [what, {
52
+ resolveDir: (0, _path.isAbsolute)(importer) ? (0, _path.dirname)(importer) : (0, _path.join)(process.cwd(), (0, _path.dirname)(importer)),
53
+ kind: 'import-statement'
54
+ }]);
29
55
  return {
30
56
  name: 'wyw-in-js',
31
57
  setup(build) {
32
58
  const cssLookup = new Map();
33
59
  const cssResolveDirs = new Map();
60
+ const warnedFilters = new Set();
61
+ let warnedEmptyBabelOptions = false;
34
62
  const {
35
63
  emitter,
36
64
  onDone
37
65
  } = (0, _transform.createFileReporter)(debug !== null && debug !== void 0 ? debug : false);
38
- const asyncResolve = async (token, importer) => {
39
- const context = (0, _path.isAbsolute)(importer) ? (0, _path.dirname)(importer) : (0, _path.join)(process.cwd(), (0, _path.dirname)(importer));
40
- const result = await build.resolve(token, {
41
- resolveDir: context,
42
- kind: 'import-statement'
43
- });
44
- if (result.errors.length > 0) {
45
- throw new Error(`Cannot resolve ${token}`);
66
+ const warnOnUnsupportedFlags = (filterRegexp, removedFlags, sanitizedFlags) => {
67
+ const key = `${filterRegexp.source}/${filterRegexp.flags}`;
68
+ if (warnedFilters.has(key)) {
69
+ return;
70
+ }
71
+ warnedFilters.add(key);
72
+ const nextFlags = sanitizedFlags || 'none';
73
+ // eslint-disable-next-line no-console
74
+ console.warn(`[wyw-in-js] Ignoring unsupported RegExp flags "${removedFlags}" ` + `in esbuild filter /${filterRegexp.source}/${filterRegexp.flags}. ` + `Using flags "${nextFlags}".`);
75
+ };
76
+ const sanitizeFilter = filterRegexp => {
77
+ const {
78
+ flags
79
+ } = filterRegexp;
80
+ const sanitizedFlags = flags.split('').filter(flag => supportedFilterFlags.has(flag)).join('');
81
+ if (sanitizedFlags === flags) {
82
+ return filterRegexp;
46
83
  }
47
- return result.path.replace(/\\/g, _path.posix.sep);
84
+ const removedFlags = flags.split('').filter(flag => !supportedFilterFlags.has(flag)).join('');
85
+ warnOnUnsupportedFlags(filterRegexp, removedFlags, sanitizedFlags);
86
+ return new RegExp(filterRegexp.source, sanitizedFlags);
48
87
  };
88
+ const asyncResolve = createAsyncResolver(build.resolve);
49
89
  build.onEnd(() => {
50
90
  onDone(process.cwd());
51
91
  });
@@ -67,7 +107,7 @@ function wywInJS({
67
107
  resolveDir: cssResolveDirs.get(args.path)
68
108
  };
69
109
  });
70
- const filterRegexp = typeof filter === 'string' ? new RegExp(filter) : filter;
110
+ const filterRegexp = typeof filter === 'string' ? new RegExp(filter) : sanitizeFilter(filter);
71
111
  build.onLoad({
72
112
  filter: filterRegexp
73
113
  }, async args => {
@@ -77,7 +117,7 @@ function wywInJS({
77
117
  name: filename
78
118
  } = (0, _path.parse)(args.path);
79
119
  const loader = ext.replace(/^\./, '');
80
- if (nodeModulesRegex.test(args.path)) {
120
+ if (!transformLibraries && nodeModulesRegex.test(args.path)) {
81
121
  return {
82
122
  loader,
83
123
  contents: rawCode
@@ -92,7 +132,46 @@ function wywInJS({
92
132
  options.jsxFragment = build.initialOptions.jsxFragment;
93
133
  }
94
134
  }
95
- const transformed = (0, _esbuild.transformSync)(rawCode, {
135
+ let codeForEsbuild = rawCode;
136
+ if (babelTransform) {
137
+ if (!babel || !resolvedWywOptions) {
138
+ throw new Error('[wyw-in-js] Internal error: babelTransform is enabled but Babel services are not initialized');
139
+ }
140
+ const {
141
+ babelOptions
142
+ } = resolvedWywOptions;
143
+ if (!Object.keys(babelOptions).length) {
144
+ if (!warnedEmptyBabelOptions) {
145
+ warnedEmptyBabelOptions = true;
146
+ // eslint-disable-next-line no-console
147
+ console.warn('[wyw-in-js] babelTransform is enabled but babelOptions is empty; skipping Babel transform.');
148
+ }
149
+ } else {
150
+ var _babelResult;
151
+ let babelResult;
152
+ try {
153
+ babelResult = babel.transformSync(codeForEsbuild, {
154
+ ...babelOptions,
155
+ ast: false,
156
+ filename: args.path,
157
+ sourceFileName: args.path,
158
+ sourceMaps: sourceMap
159
+ });
160
+ } catch (e) {
161
+ const message = e instanceof Error ? e.message : String(e);
162
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}: ${message}`);
163
+ }
164
+ if (!((_babelResult = babelResult) !== null && _babelResult !== void 0 && _babelResult.code)) {
165
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}`);
166
+ }
167
+ codeForEsbuild = babelResult.code;
168
+ if (sourceMap && babelResult.map) {
169
+ const babelMap = Buffer.from(JSON.stringify(babelResult.map)).toString('base64');
170
+ codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${babelMap}*/`;
171
+ }
172
+ }
173
+ }
174
+ const transformed = (0, _esbuild.transformSync)(codeForEsbuild, {
96
175
  ...options,
97
176
  sourcefile: args.path,
98
177
  sourcemap: sourceMap,
@@ -110,6 +189,7 @@ function wywInJS({
110
189
  filename: args.path,
111
190
  pluginOptions: rest,
112
191
  prefixer,
192
+ keepComments,
113
193
  preprocessor,
114
194
  root: process.cwd()
115
195
  },
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_fs","require","_path","_esbuild","_transform","nodeModulesRegex","wywInJS","debug","sourceMap","prefixer","preprocessor","esbuildOptions","filter","rest","options","cache","TransformCacheCollection","name","setup","build","cssLookup","Map","cssResolveDirs","emitter","onDone","createFileReporter","asyncResolve","token","importer","context","isAbsolute","dirname","join","process","cwd","result","resolve","resolveDir","kind","errors","length","Error","path","replace","posix","sep","onEnd","onResolve","args","namespace","onLoad","contents","get","loader","filterRegexp","RegExp","rawCode","readFileSync","ext","filename","parse","test","initialOptions","jsxFactory","jsxFragment","transformed","transformSync","sourcefile","sourcemap","code","esbuildMap","Buffer","from","map","toString","transformServices","pluginOptions","root","eventEmitter","transform","cssText","slug","slugify","cssFilename","JSON","stringify","cssSourceMapText","wywMap","set"],"sources":["../src/index.ts"],"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 } from 'esbuild';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n} from '@wyw-in-js/transform';\n\ntype EsbuildPluginOptions = {\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n prefixer?: boolean;\n preprocessor?: Preprocessor;\n sourceMap?: boolean;\n} & Partial<PluginOptions>;\n\nconst nodeModulesRegex = /^(?:.*[\\\\/])?node_modules(?:[\\\\/].*)?$/;\n\nexport default function wywInJS({\n debug,\n sourceMap,\n prefixer,\n preprocessor,\n esbuildOptions,\n filter = /\\.(js|jsx|ts|tsx)$/,\n ...rest\n}: EsbuildPluginOptions = {}): Plugin {\n let options = esbuildOptions;\n const cache = new TransformCacheCollection();\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\n const { emitter, onDone } = createFileReporter(debug ?? false);\n\n const asyncResolve = async (\n token: string,\n importer: string\n ): Promise<string> => {\n const context = isAbsolute(importer)\n ? dirname(importer)\n : join(process.cwd(), dirname(importer));\n\n const result = await build.resolve(token, {\n resolveDir: context,\n kind: 'import-statement',\n });\n\n if (result.errors.length > 0) {\n throw new Error(`Cannot resolve ${token}`);\n }\n\n return result.path.replace(/\\\\/g, posix.sep);\n };\n\n build.onEnd(() => {\n onDone(process.cwd());\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' ? new RegExp(filter) : 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 (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 const transformed = transformSync(rawCode, {\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 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 (!result.cssText) {\n return {\n contents: code,\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"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_fs","require","_path","_esbuild","_transform","_shared","supportedFilterFlags","Set","nodeModulesRegex","wywInJS","babelTransform","debug","sourceMap","keepComments","prefixer","preprocessor","esbuildOptions","filter","transformLibraries","rest","options","cache","TransformCacheCollection","resolvedWywOptions","babel","loadWywOptions","withDefaultServices","filename","pluginOptions","root","process","cwd","createAsyncResolver","asyncResolverFactory","resolved","token","errors","length","Error","path","replace","posix","sep","what","importer","resolveDir","isAbsolute","dirname","join","kind","name","setup","build","cssLookup","Map","cssResolveDirs","warnedFilters","warnedEmptyBabelOptions","emitter","onDone","createFileReporter","warnOnUnsupportedFlags","filterRegexp","removedFlags","sanitizedFlags","key","source","flags","has","add","nextFlags","console","warn","sanitizeFilter","split","flag","RegExp","asyncResolve","resolve","onEnd","onResolve","args","namespace","onLoad","contents","get","loader","rawCode","readFileSync","ext","parse","test","initialOptions","jsxFactory","jsxFragment","codeForEsbuild","babelOptions","Object","keys","_babelResult","babelResult","transformSync","ast","sourceFileName","sourceMaps","e","message","String","code","map","babelMap","Buffer","from","JSON","stringify","toString","transformed","esbuildTransformSync","sourcefile","sourcemap","esbuildMap","transformServices","eventEmitter","result","transform","cssText","slug","slugify","cssFilename","cssSourceMapText","wywMap","set"],"sources":["../src/index.ts"],"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';\n\nimport type {\n PluginOptions,\n Preprocessor,\n IFileReporterOptions,\n} from '@wyw-in-js/transform';\nimport {\n slugify,\n transform,\n TransformCacheCollection,\n createFileReporter,\n loadWywOptions,\n withDefaultServices,\n} from '@wyw-in-js/transform';\nimport { asyncResolverFactory } from '@wyw-in-js/shared';\n\ntype EsbuildPluginOptions = {\n babelTransform?: boolean;\n debug?: IFileReporterOptions | false | null | undefined;\n esbuildOptions?: TransformOptions;\n filter?: RegExp | string;\n keepComments?: boolean | RegExp;\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 babelTransform,\n debug,\n sourceMap,\n keepComments,\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 let resolvedWywOptions: ReturnType<typeof loadWywOptions> | null = null;\n let babel: ReturnType<typeof withDefaultServices>['babel'] | null = null;\n if (babelTransform) {\n resolvedWywOptions = loadWywOptions(rest);\n babel = withDefaultServices({\n options: {\n filename: '<wyw-in-js/esbuild>',\n pluginOptions: resolvedWywOptions,\n root: process.cwd(),\n },\n }).babel;\n }\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 warnedEmptyBabelOptions = 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 asyncResolve = createAsyncResolver(build.resolve);\n\n build.onEnd(() => {\n onDone(process.cwd());\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 (babelTransform) {\n if (!babel || !resolvedWywOptions) {\n throw new Error(\n '[wyw-in-js] Internal error: babelTransform is enabled but Babel services are not initialized'\n );\n }\n\n const { babelOptions } = resolvedWywOptions;\n if (!Object.keys(babelOptions).length) {\n if (!warnedEmptyBabelOptions) {\n warnedEmptyBabelOptions = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[wyw-in-js] babelTransform is enabled but babelOptions is empty; skipping Babel transform.'\n );\n }\n } else {\n let babelResult;\n try {\n babelResult = babel.transformSync(codeForEsbuild, {\n ...babelOptions,\n ast: false,\n filename: args.path,\n sourceFileName: args.path,\n sourceMaps: sourceMap,\n });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `[wyw-in-js] Babel transform failed for ${args.path}: ${message}`\n );\n }\n\n if (!babelResult?.code) {\n throw new Error(\n `[wyw-in-js] Babel transform failed for ${args.path}`\n );\n }\n\n codeForEsbuild = babelResult.code;\n\n if (sourceMap && babelResult.map) {\n const babelMap = Buffer.from(\n JSON.stringify(babelResult.map)\n ).toString('base64');\n codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${babelMap}*/`;\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 (!result.cssText) {\n return {\n contents: code,\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"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@wyw-in-js/esbuild",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "dependencies": {
5
- "@wyw-in-js/shared": "0.8.0",
6
- "@wyw-in-js/transform": "0.8.0"
5
+ "@wyw-in-js/shared": "workspace:*",
6
+ "@wyw-in-js/transform": "workspace:*"
7
7
  },
8
8
  "devDependencies": {
9
9
  "@types/node": "^16.18.55",
10
- "esbuild": "^0.15.16",
11
- "@wyw-in-js/babel-config": "0.8.0",
12
- "@wyw-in-js/eslint-config": "0.8.0",
13
- "@wyw-in-js/jest-preset": "0.8.0",
14
- "@wyw-in-js/ts-config": "0.8.0"
10
+ "@wyw-in-js/babel-config": "workspace:*",
11
+ "@wyw-in-js/eslint-config": "workspace:*",
12
+ "@wyw-in-js/ts-config": "workspace:*",
13
+ "esbuild": "^0.15.16"
15
14
  },
16
15
  "engines": {
17
16
  "node": ">=16.0.0"
@@ -35,11 +34,12 @@
35
34
  "publishConfig": {
36
35
  "access": "public"
37
36
  },
38
- "types": "types/index.d.ts",
39
37
  "scripts": {
40
38
  "build:esm": "babel src --out-dir esm --out-file-extension .mjs --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
41
39
  "build:lib": "cross-env NODE_ENV=legacy babel src --out-dir lib --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
42
40
  "build:types": "tsc --project ./tsconfig.lib.json --baseUrl . --rootDir ./src",
43
- "lint": "eslint --ext .js,.ts ."
44
- }
45
- }
41
+ "lint": "eslint --ext .js,.ts .",
42
+ "test": "bun test src"
43
+ },
44
+ "types": "types/index.d.ts"
45
+ }
package/types/index.d.ts CHANGED
@@ -6,12 +6,15 @@
6
6
  import type { Plugin, TransformOptions } from 'esbuild';
7
7
  import type { PluginOptions, Preprocessor, IFileReporterOptions } from '@wyw-in-js/transform';
8
8
  type EsbuildPluginOptions = {
9
+ babelTransform?: boolean;
9
10
  debug?: IFileReporterOptions | false | null | undefined;
10
11
  esbuildOptions?: TransformOptions;
11
12
  filter?: RegExp | string;
13
+ keepComments?: boolean | RegExp;
12
14
  prefixer?: boolean;
13
15
  preprocessor?: Preprocessor;
14
16
  sourceMap?: boolean;
17
+ transformLibraries?: boolean;
15
18
  } & Partial<PluginOptions>;
16
- export default function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, filter, ...rest }?: EsbuildPluginOptions): Plugin;
19
+ export default function wywInJS({ babelTransform, debug, sourceMap, keepComments, prefixer, preprocessor, esbuildOptions, filter, transformLibraries, ...rest }?: EsbuildPluginOptions): Plugin;
17
20
  export {};
package/types/index.js CHANGED
@@ -5,33 +5,80 @@
5
5
  * returns transformed code without template literals and attaches generated source maps
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.default = wywInJS;
8
9
  const fs_1 = require("fs");
9
10
  const path_1 = require("path");
10
11
  const esbuild_1 = require("esbuild");
11
12
  const transform_1 = require("@wyw-in-js/transform");
13
+ const shared_1 = require("@wyw-in-js/shared");
14
+ const supportedFilterFlags = new Set(['i', 'm', 's']);
12
15
  const nodeModulesRegex = /^(?:.*[\\/])?node_modules(?:[\\/].*)?$/;
13
- function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, filter = /\.(js|jsx|ts|tsx)$/, ...rest } = {}) {
16
+ function wywInJS({ babelTransform, debug, sourceMap, keepComments, prefixer, preprocessor, esbuildOptions, filter = /\.(js|jsx|ts|tsx)$/, transformLibraries, ...rest } = {}) {
14
17
  let options = esbuildOptions;
15
18
  const cache = new transform_1.TransformCacheCollection();
19
+ let resolvedWywOptions = null;
20
+ let babel = null;
21
+ if (babelTransform) {
22
+ resolvedWywOptions = (0, transform_1.loadWywOptions)(rest);
23
+ babel = (0, transform_1.withDefaultServices)({
24
+ options: {
25
+ filename: '<wyw-in-js/esbuild>',
26
+ pluginOptions: resolvedWywOptions,
27
+ root: process.cwd(),
28
+ },
29
+ }).babel;
30
+ }
31
+ const createAsyncResolver = (0, shared_1.asyncResolverFactory)(async (resolved, token) => {
32
+ if (resolved.errors.length > 0) {
33
+ throw new Error(`Cannot resolve ${token}`);
34
+ }
35
+ return resolved.path.replace(/\\/g, path_1.posix.sep);
36
+ }, (what, importer) => [
37
+ what,
38
+ {
39
+ resolveDir: (0, path_1.isAbsolute)(importer)
40
+ ? (0, path_1.dirname)(importer)
41
+ : (0, path_1.join)(process.cwd(), (0, path_1.dirname)(importer)),
42
+ kind: 'import-statement',
43
+ },
44
+ ]);
16
45
  return {
17
46
  name: 'wyw-in-js',
18
47
  setup(build) {
19
48
  const cssLookup = new Map();
20
49
  const cssResolveDirs = new Map();
50
+ const warnedFilters = new Set();
51
+ let warnedEmptyBabelOptions = false;
21
52
  const { emitter, onDone } = (0, transform_1.createFileReporter)(debug ?? false);
22
- const asyncResolve = async (token, importer) => {
23
- const context = (0, path_1.isAbsolute)(importer)
24
- ? (0, path_1.dirname)(importer)
25
- : (0, path_1.join)(process.cwd(), (0, path_1.dirname)(importer));
26
- const result = await build.resolve(token, {
27
- resolveDir: context,
28
- kind: 'import-statement',
29
- });
30
- if (result.errors.length > 0) {
31
- throw new Error(`Cannot resolve ${token}`);
53
+ const warnOnUnsupportedFlags = (filterRegexp, removedFlags, sanitizedFlags) => {
54
+ const key = `${filterRegexp.source}/${filterRegexp.flags}`;
55
+ if (warnedFilters.has(key)) {
56
+ return;
57
+ }
58
+ warnedFilters.add(key);
59
+ const nextFlags = sanitizedFlags || 'none';
60
+ // eslint-disable-next-line no-console
61
+ console.warn(`[wyw-in-js] Ignoring unsupported RegExp flags "${removedFlags}" ` +
62
+ `in esbuild filter /${filterRegexp.source}/${filterRegexp.flags}. ` +
63
+ `Using flags "${nextFlags}".`);
64
+ };
65
+ const sanitizeFilter = (filterRegexp) => {
66
+ const { flags } = filterRegexp;
67
+ const sanitizedFlags = flags
68
+ .split('')
69
+ .filter((flag) => supportedFilterFlags.has(flag))
70
+ .join('');
71
+ if (sanitizedFlags === flags) {
72
+ return filterRegexp;
32
73
  }
33
- return result.path.replace(/\\/g, path_1.posix.sep);
74
+ const removedFlags = flags
75
+ .split('')
76
+ .filter((flag) => !supportedFilterFlags.has(flag))
77
+ .join('');
78
+ warnOnUnsupportedFlags(filterRegexp, removedFlags, sanitizedFlags);
79
+ return new RegExp(filterRegexp.source, sanitizedFlags);
34
80
  };
81
+ const asyncResolve = createAsyncResolver(build.resolve);
35
82
  build.onEnd(() => {
36
83
  onDone(process.cwd());
37
84
  });
@@ -48,12 +95,14 @@ function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, fil
48
95
  resolveDir: cssResolveDirs.get(args.path),
49
96
  };
50
97
  });
51
- const filterRegexp = typeof filter === 'string' ? new RegExp(filter) : filter;
98
+ const filterRegexp = typeof filter === 'string'
99
+ ? new RegExp(filter)
100
+ : sanitizeFilter(filter);
52
101
  build.onLoad({ filter: filterRegexp }, async (args) => {
53
102
  const rawCode = (0, fs_1.readFileSync)(args.path, 'utf8');
54
103
  const { ext, name: filename } = (0, path_1.parse)(args.path);
55
104
  const loader = ext.replace(/^\./, '');
56
- if (nodeModulesRegex.test(args.path)) {
105
+ if (!transformLibraries && nodeModulesRegex.test(args.path)) {
57
106
  return {
58
107
  loader,
59
108
  contents: rawCode,
@@ -68,7 +117,45 @@ function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, fil
68
117
  options.jsxFragment = build.initialOptions.jsxFragment;
69
118
  }
70
119
  }
71
- const transformed = (0, esbuild_1.transformSync)(rawCode, {
120
+ let codeForEsbuild = rawCode;
121
+ if (babelTransform) {
122
+ if (!babel || !resolvedWywOptions) {
123
+ throw new Error('[wyw-in-js] Internal error: babelTransform is enabled but Babel services are not initialized');
124
+ }
125
+ const { babelOptions } = resolvedWywOptions;
126
+ if (!Object.keys(babelOptions).length) {
127
+ if (!warnedEmptyBabelOptions) {
128
+ warnedEmptyBabelOptions = true;
129
+ // eslint-disable-next-line no-console
130
+ console.warn('[wyw-in-js] babelTransform is enabled but babelOptions is empty; skipping Babel transform.');
131
+ }
132
+ }
133
+ else {
134
+ let babelResult;
135
+ try {
136
+ babelResult = babel.transformSync(codeForEsbuild, {
137
+ ...babelOptions,
138
+ ast: false,
139
+ filename: args.path,
140
+ sourceFileName: args.path,
141
+ sourceMaps: sourceMap,
142
+ });
143
+ }
144
+ catch (e) {
145
+ const message = e instanceof Error ? e.message : String(e);
146
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}: ${message}`);
147
+ }
148
+ if (!babelResult?.code) {
149
+ throw new Error(`[wyw-in-js] Babel transform failed for ${args.path}`);
150
+ }
151
+ codeForEsbuild = babelResult.code;
152
+ if (sourceMap && babelResult.map) {
153
+ const babelMap = Buffer.from(JSON.stringify(babelResult.map)).toString('base64');
154
+ codeForEsbuild += `/*# sourceMappingURL=data:application/json;base64,${babelMap}*/`;
155
+ }
156
+ }
157
+ }
158
+ const transformed = (0, esbuild_1.transformSync)(codeForEsbuild, {
72
159
  ...options,
73
160
  sourcefile: args.path,
74
161
  sourcemap: sourceMap,
@@ -84,6 +171,7 @@ function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, fil
84
171
  filename: args.path,
85
172
  pluginOptions: rest,
86
173
  prefixer,
174
+ keepComments,
87
175
  preprocessor,
88
176
  root: process.cwd(),
89
177
  },
@@ -120,4 +208,3 @@ function wywInJS({ debug, sourceMap, prefixer, preprocessor, esbuildOptions, fil
120
208
  },
121
209
  };
122
210
  }
123
- exports.default = wywInJS;
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Anton Evzhakov
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.