@wyw-in-js/vite 1.0.8 → 1.1.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/types/index.js CHANGED
@@ -4,6 +4,39 @@
4
4
  * It uses the transform.ts function to generate class names from source code,
5
5
  * returns transformed code without template literals and attaches generated source maps
6
6
  */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
7
40
  var __importDefault = (this && this.__importDefault) || function (mod) {
8
41
  return (mod && mod.__esModule) ? mod : { "default": mod };
9
42
  };
@@ -13,7 +46,18 @@ const fs_1 = require("fs");
13
46
  const path_1 = __importDefault(require("path"));
14
47
  const vite_1 = require("vite");
15
48
  const shared_1 = require("@wyw-in-js/shared");
16
- const transform_1 = require("@wyw-in-js/transform");
49
+ const transformPkg = __importStar(require("@wyw-in-js/transform"));
50
+ const { createTransformManifest, createFileReporter, getFileIdx, stringifyTransformManifest, transform, TransformCacheCollection, } = transformPkg;
51
+ const createMetadataManifest = (metadata, context) => typeof createTransformManifest === 'function'
52
+ ? createTransformManifest(metadata, context)
53
+ : {
54
+ ...metadata,
55
+ ...context,
56
+ version: 1,
57
+ };
58
+ const stringifyMetadataManifest = (manifest) => typeof stringifyTransformManifest === 'function'
59
+ ? stringifyTransformManifest(manifest)
60
+ : `${JSON.stringify(manifest, null, 2)}\n`;
17
61
  const isWindowsAbsolutePath = (value) => /^[a-zA-Z]:[\\/]/.test(value);
18
62
  const normalizeToPosix = (value) => value.replace(/\\/g, path_1.default.posix.sep);
19
63
  const isInside = (childPath, parentPath) => {
@@ -32,6 +76,107 @@ const stripExtension = (value) => {
32
76
  const ext = path_1.default.posix.extname(value);
33
77
  return ext ? value.slice(0, -ext.length) : value;
34
78
  };
79
+ const getComparableAssetPaths = (value, rootDir) => {
80
+ const variants = new Set();
81
+ const normalized = normalizeToPosix(value);
82
+ variants.add(normalized);
83
+ if (path_1.default.isAbsolute(value) || isWindowsAbsolutePath(normalized)) {
84
+ if (isInside(value, rootDir)) {
85
+ const relativeToRoot = normalizeAssetRelativePath(path_1.default.relative(rootDir, value));
86
+ if (relativeToRoot) {
87
+ variants.add(relativeToRoot);
88
+ }
89
+ }
90
+ return variants;
91
+ }
92
+ const relativePath = normalizeAssetRelativePath(value);
93
+ if (relativePath) {
94
+ variants.add(relativePath);
95
+ }
96
+ return variants;
97
+ };
98
+ const getStringValues = (value) => {
99
+ if (!Array.isArray(value))
100
+ return [];
101
+ return value.filter((item) => typeof item === 'string');
102
+ };
103
+ const getOutputAssetNames = (asset) => [
104
+ ...(typeof asset.name === 'string' ? [asset.name] : []),
105
+ ...getStringValues(asset.names),
106
+ ...(typeof asset.originalFileName === 'string'
107
+ ? [asset.originalFileName]
108
+ : []),
109
+ ...getStringValues(asset.originalFileNames),
110
+ ];
111
+ const isOutputAssetLike = (value) => !!value &&
112
+ typeof value === 'object' &&
113
+ value.type === 'asset' &&
114
+ typeof value.fileName === 'string';
115
+ const isOutputChunkLike = (value) => !!value &&
116
+ typeof value === 'object' &&
117
+ value.type === 'chunk' &&
118
+ typeof value.fileName === 'string' &&
119
+ typeof value.code === 'string';
120
+ const getTrackedModuleIdForChunk = (chunk, cssFilesByModuleId) => {
121
+ if (typeof chunk.facadeModuleId === 'string' &&
122
+ cssFilesByModuleId.has(chunk.facadeModuleId)) {
123
+ return chunk.facadeModuleId;
124
+ }
125
+ if (!Array.isArray(chunk.moduleIds)) {
126
+ return null;
127
+ }
128
+ const moduleId = chunk.moduleIds.find((id) => typeof id === 'string' && cssFilesByModuleId.has(id));
129
+ return moduleId ?? null;
130
+ };
131
+ const findWywCssAssetFileName = (bundle, cssFilename, rootDir) => {
132
+ const expectedNames = getComparableAssetPaths(cssFilename, rootDir);
133
+ for (const item of Object.values(bundle)) {
134
+ if (isOutputAssetLike(item) && item.fileName.endsWith('.css')) {
135
+ const isMatch = getOutputAssetNames(item).some((assetName) => {
136
+ const variants = getComparableAssetPaths(assetName, rootDir);
137
+ return Array.from(variants).some((variant) => expectedNames.has(variant));
138
+ });
139
+ if (isMatch) {
140
+ return normalizeToPosix(item.fileName);
141
+ }
142
+ }
143
+ }
144
+ return null;
145
+ };
146
+ const getRelativeImportPath = (fromFileName, toFileName) => {
147
+ const fromDir = path_1.default.posix.dirname(normalizeToPosix(fromFileName));
148
+ const relativePath = path_1.default.posix.relative(fromDir, normalizeToPosix(toFileName));
149
+ return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
150
+ };
151
+ const escapeForRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
152
+ const hasStaticImport = (code, specifier) => new RegExp(`(^|\\n)\\s*import\\s*(?:["']${escapeForRegExp(specifier)}["']|[^\\n;]+\\s+from\\s+["']${escapeForRegExp(specifier)}["'])`, 'm').test(code);
153
+ const hasRequireCall = (code, specifier) => new RegExp(`(^|[;\\n])\\s*require\\(\\s*["']${escapeForRegExp(specifier)}["']\\s*\\)`, 'm').test(code);
154
+ const getCssLoadStatement = (format, specifier) => format === 'cjs'
155
+ ? `require(${JSON.stringify(specifier)});\n`
156
+ : `import ${JSON.stringify(specifier)};\n`;
157
+ const hasCssLoadStatement = (code, specifier, format) => format === 'cjs'
158
+ ? hasRequireCall(code, specifier)
159
+ : hasStaticImport(code, specifier);
160
+ const prependCssLoadStatement = (code, specifier, format) => {
161
+ const statement = getCssLoadStatement(format, specifier);
162
+ let insertAt = 0;
163
+ if (code.startsWith('#!')) {
164
+ const lineBreakIndex = code.indexOf('\n');
165
+ if (lineBreakIndex >= 0) {
166
+ insertAt = lineBreakIndex + 1;
167
+ }
168
+ else {
169
+ return `${code}\n${statement}`;
170
+ }
171
+ }
172
+ if (format === 'cjs') {
173
+ const directiveMatch = /^(?:\s*(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*');)+/.exec(code.slice(insertAt));
174
+ if (directiveMatch) {
175
+ insertAt += directiveMatch[0].length;
176
+ }
177
+ }
178
+ return `${code.slice(0, insertAt)}${statement}${code.slice(insertAt)}`;
179
+ };
35
180
  const VITE_FS_PREFIX = '/@fs/';
36
181
  const safeDecodeURIComponent = (value) => {
37
182
  try {
@@ -143,9 +288,21 @@ const getWywCssAssetFileNames = (resolvedConfig, output, originalAssetFileNames)
143
288
  };
144
289
  };
145
290
  function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepComments, prefixer, preprocessor, ssrDevCss, ssrDevCssPath, transformLibraries, ...rest } = {}) {
291
+ const supportedModuleExtensions = new Set([
292
+ '.cjs',
293
+ '.cts',
294
+ '.js',
295
+ '.jsx',
296
+ '.mjs',
297
+ '.mts',
298
+ '.ts',
299
+ '.tsx',
300
+ ]);
146
301
  const filter = (0, vite_1.createFilter)(include, exclude);
147
302
  const cssLookup = {};
148
303
  const cssFileLookup = {};
304
+ const metadataLookup = {};
305
+ const cssFilesByModuleId = new Map();
149
306
  const pendingCssReloads = new WeakMap();
150
307
  let ssrDevCssVersion = 0;
151
308
  let config;
@@ -173,7 +330,35 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
173
330
  .join('\n');
174
331
  return `${merged}\n`;
175
332
  };
176
- const { emitter, onDone } = (0, transform_1.createFileReporter)(debug ?? false);
333
+ const { emitter, onDone } = createFileReporter(debug ?? false);
334
+ const isSafeAssetPath = (fileName) => fileName !== '' &&
335
+ fileName !== '..' &&
336
+ !fileName.startsWith(`..${path_1.default.posix.sep}`) &&
337
+ !path_1.default.posix.isAbsolute(fileName) &&
338
+ !isWindowsAbsolutePath(fileName);
339
+ const replaceModuleExtension = (filename, nextExtension) => {
340
+ const extension = path_1.default.extname(filename);
341
+ return supportedModuleExtensions.has(extension)
342
+ ? `${filename.slice(0, -extension.length)}${nextExtension}`
343
+ : `${filename}${nextExtension}`;
344
+ };
345
+ const toBundleRelativePath = (filename) => {
346
+ const relativePath = normalizeToPosix(path_1.default.relative(config.root, filename));
347
+ if (isSafeAssetPath(relativePath)) {
348
+ return relativePath;
349
+ }
350
+ if (!path_1.default.isAbsolute(relativePath) &&
351
+ !isWindowsAbsolutePath(relativePath)) {
352
+ return path_1.default.posix.join('_wyw-in-js', 'external', ...relativePath
353
+ .split(path_1.default.posix.sep)
354
+ .filter(Boolean)
355
+ .map((segment) => (segment === '..' ? '__up__' : segment)));
356
+ }
357
+ return path_1.default.posix.join('_wyw-in-js', 'external', ...normalizeToPosix(path_1.default.resolve(filename))
358
+ .split(path_1.default.posix.sep)
359
+ .filter(Boolean)
360
+ .map((segment) => segment.replace(/:$/, '')));
361
+ };
177
362
  const scheduleCssReload = (reloadTarget, cssFilename) => {
178
363
  let state = pendingCssReloads.get(reloadTarget);
179
364
  if (!state) {
@@ -197,8 +382,8 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
197
382
  };
198
383
  // <dependency id, targets>
199
384
  const targets = [];
200
- const clientCache = new transform_1.TransformCacheCollection();
201
- const ssrCache = new transform_1.TransformCacheCollection();
385
+ const clientCache = new TransformCacheCollection();
386
+ const ssrCache = new TransformCacheCollection();
202
387
  const caches = new Set([clientCache, ssrCache]);
203
388
  const getCache = (isSsr) => isSsr ? ssrCache : clientCache;
204
389
  const isInsideCacheDir = (filename) => {
@@ -246,7 +431,7 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
246
431
  return viteResolver(what, importer, false, true);
247
432
  };
248
433
  const createAsyncResolver = (0, shared_1.asyncResolverFactory)(async (resolved, what, importer, stack) => {
249
- const log = shared_1.logger.extend('vite').extend((0, transform_1.getFileIdx)(importer));
434
+ const log = shared_1.logger.extend('vite').extend(getFileIdx(importer));
250
435
  if (resolved) {
251
436
  log("resolve ✅ '%s'@'%s -> %O\n%s", what, importer, resolved);
252
437
  // Vite adds param like `?v=667939b3` to cached modules
@@ -308,6 +493,11 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
308
493
  return {
309
494
  name: 'wyw-in-js',
310
495
  enforce: 'post',
496
+ buildStart() {
497
+ Object.keys(metadataLookup).forEach((key) => {
498
+ delete metadataLookup[key];
499
+ });
500
+ },
311
501
  buildEnd() {
312
502
  onDone(process.cwd());
313
503
  },
@@ -431,6 +621,44 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
431
621
  .concat(ctx.modules)
432
622
  .filter((m) => !!m);
433
623
  },
624
+ generateBundle(outputOptions, bundle) {
625
+ Object.entries(metadataLookup).forEach(([fileName, source]) => {
626
+ this.emitFile({
627
+ fileName,
628
+ source,
629
+ type: 'asset',
630
+ });
631
+ });
632
+ if (config.command !== 'build')
633
+ return;
634
+ if (!outputOptions.preserveModules)
635
+ return;
636
+ if (config.build.cssCodeSplit === false)
637
+ return;
638
+ Object.values(bundle).forEach((item) => {
639
+ if (!isOutputChunkLike(item)) {
640
+ return;
641
+ }
642
+ const chunk = item;
643
+ const moduleId = getTrackedModuleIdForChunk(chunk, cssFilesByModuleId);
644
+ if (!moduleId) {
645
+ return;
646
+ }
647
+ const cssFilename = cssFilesByModuleId.get(moduleId);
648
+ if (!cssFilename) {
649
+ return;
650
+ }
651
+ const emittedCssFileName = findWywCssAssetFileName(bundle, cssFilename, config.root);
652
+ if (!emittedCssFileName) {
653
+ return;
654
+ }
655
+ const relativeCssImport = getRelativeImportPath(chunk.fileName, emittedCssFileName);
656
+ if (hasCssLoadStatement(chunk.code, relativeCssImport, outputOptions.format)) {
657
+ return;
658
+ }
659
+ chunk.code = prependCssLoadStatement(chunk.code, relativeCssImport, outputOptions.format);
660
+ });
661
+ },
434
662
  async transform(code, url, transformOptions) {
435
663
  const [id] = url.split('?', 1);
436
664
  // Do not transform ignored and generated files
@@ -438,7 +666,7 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
438
666
  !filter(url) ||
439
667
  id in cssLookup)
440
668
  return;
441
- const log = shared_1.logger.extend('vite').extend((0, transform_1.getFileIdx)(id));
669
+ const log = shared_1.logger.extend('vite').extend(getFileIdx(id));
442
670
  log('transform %s', id);
443
671
  const isSsr = typeof transformOptions === 'boolean'
444
672
  ? transformOptions
@@ -469,16 +697,45 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
469
697
  eventEmitter: emitter,
470
698
  };
471
699
  const asyncResolve = isSsr ? asyncResolveSsr : asyncResolveClient;
472
- const result = await (0, transform_1.transform)(transformServices, code, asyncResolve);
700
+ const result = await transform(transformServices, code, asyncResolve);
701
+ result.diagnostics?.forEach((diagnostic) => {
702
+ this.warn({
703
+ id: diagnostic.filename,
704
+ loc: diagnostic.start
705
+ ? {
706
+ column: diagnostic.start.column,
707
+ file: diagnostic.filename,
708
+ line: diagnostic.start.line,
709
+ }
710
+ : undefined,
711
+ message: `[wyw-in-js] ${diagnostic.severity} [${diagnostic.category}] ${diagnostic.message}`,
712
+ pluginCode: diagnostic.category,
713
+ });
714
+ });
715
+ const relativeId = normalizeToPosix(path_1.default.relative(config.root, id));
716
+ const metadataFilename = replaceModuleExtension(id, '.wyw-in-js.json');
717
+ const metadataRelativePath = toBundleRelativePath(metadataFilename);
718
+ delete metadataLookup[metadataRelativePath];
719
+ if (result.metadata) {
720
+ const cssFile = typeof result.cssText === 'string' && result.cssText !== ''
721
+ ? replaceModuleExtension(relativeId, '.wyw-in-js.css')
722
+ : undefined;
723
+ metadataLookup[metadataRelativePath] = stringifyMetadataManifest(createMetadataManifest(result.metadata, {
724
+ cssFile,
725
+ source: relativeId,
726
+ }));
727
+ }
473
728
  let { cssText, dependencies } = result;
474
729
  // Heads up, there are three cases:
475
730
  // 1. cssText is undefined, it means that file was not transformed
476
731
  // 2. cssText is empty, it means that file was transformed, but it does not contain any styles
477
732
  // 3. cssText is not empty, it means that file was transformed and it contains styles
478
733
  if (typeof cssText === 'undefined') {
734
+ cssFilesByModuleId.delete(id);
479
735
  return;
480
736
  }
481
737
  if (cssText === '') {
738
+ cssFilesByModuleId.delete(id);
482
739
  /* eslint-disable-next-line consistent-return */
483
740
  return {
484
741
  code: result.code,
@@ -486,12 +743,9 @@ function wywInJS({ debug, include, exclude, sourceMap, preserveCssPaths, keepCom
486
743
  };
487
744
  }
488
745
  dependencies ??= [];
489
- const cssFilename = path_1.default
490
- .normalize(`${id.replace(/\.[jt]sx?$/, '')}.wyw-in-js.css`)
491
- .replace(/\\/g, path_1.default.posix.sep);
492
- const cssRelativePath = path_1.default
493
- .relative(config.root, cssFilename)
494
- .replace(/\\/g, path_1.default.posix.sep);
746
+ const cssFilename = normalizeToPosix(replaceModuleExtension(id, '.wyw-in-js.css'));
747
+ cssFilesByModuleId.set(id, cssFilename);
748
+ const cssRelativePath = normalizeToPosix(path_1.default.relative(config.root, cssFilename));
495
749
  const cssId = `/${cssRelativePath}`;
496
750
  if (sourceMap && result.cssSourceMapText) {
497
751
  const map = Buffer.from(result.cssSourceMapText).toString('base64');