@wyw-in-js/webpack-loader 1.1.0 → 2.0.0-alpha.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.
@@ -1,18 +1,16 @@
1
- import { createFileReporter } from '@wyw-in-js/transform';
1
+ import { createFileReporter } from "@wyw-in-js/transform";
2
2
  export const sharedState = {};
3
3
  export class WYWinJSDebugPlugin {
4
- constructor(options) {
5
- const {
6
- emitter,
7
- onDone
8
- } = createFileReporter(options ?? false);
9
- sharedState.emitter = emitter;
10
- this.onDone = onDone;
11
- }
12
- apply(compiler) {
13
- compiler.hooks.shutdown.tap('WYWinJSDebug', () => {
14
- this.onDone(process.cwd());
15
- });
16
- }
4
+ onDone;
5
+ constructor(options) {
6
+ const { emitter, onDone } = createFileReporter(options ?? false);
7
+ sharedState.emitter = emitter;
8
+ this.onDone = onDone;
9
+ }
10
+ apply(compiler) {
11
+ compiler.hooks.shutdown.tap("WYWinJSDebug", () => {
12
+ this.onDone(process.cwd());
13
+ });
14
+ }
17
15
  }
18
- //# sourceMappingURL=WYWinJSDebugPlugin.js.map
16
+ //# sourceMappingURL=WYWinJSDebugPlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WYWinJSDebugPlugin.js","names":["createFileReporter","sharedState","WYWinJSDebugPlugin","constructor","options","emitter","onDone","apply","compiler","hooks","shutdown","tap","process","cwd"],"sources":["../src/WYWinJSDebugPlugin.ts"],"sourcesContent":["import type { Compiler } from 'webpack';\n\nimport type { EventEmitter, IFileReporterOptions } from '@wyw-in-js/transform';\nimport { createFileReporter } from '@wyw-in-js/transform';\n\nexport const sharedState: {\n emitter?: EventEmitter;\n} = {};\n\nexport class WYWinJSDebugPlugin {\n private readonly onDone: (root: string) => void;\n\n constructor(options?: IFileReporterOptions) {\n const { emitter, onDone } = createFileReporter(options ?? false);\n sharedState.emitter = emitter;\n this.onDone = onDone;\n }\n\n apply(compiler: Compiler) {\n compiler.hooks.shutdown.tap('WYWinJSDebug', () => {\n this.onDone(process.cwd());\n });\n }\n}\n"],"mappings":"AAGA,SAASA,kBAAkB,QAAQ,sBAAsB;AAEzD,OAAO,MAAMC,WAEZ,GAAG,CAAC,CAAC;AAEN,OAAO,MAAMC,kBAAkB,CAAC;EAG9BC,WAAWA,CAACC,OAA8B,EAAE;IAC1C,MAAM;MAAEC,OAAO;MAAEC;IAAO,CAAC,GAAGN,kBAAkB,CAACI,OAAO,IAAI,KAAK,CAAC;IAChEH,WAAW,CAACI,OAAO,GAAGA,OAAO;IAC7B,IAAI,CAACC,MAAM,GAAGA,MAAM;EACtB;EAEAC,KAAKA,CAACC,QAAkB,EAAE;IACxBA,QAAQ,CAACC,KAAK,CAACC,QAAQ,CAACC,GAAG,CAAC,cAAc,EAAE,MAAM;MAChD,IAAI,CAACL,MAAM,CAACM,OAAO,CAACC,GAAG,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
1
+ {"mappings":"AAGA,SAAS,0BAA0B;AAEnC,OAAO,MAAM,cAET,EAAE;AAEN,OAAO,MAAM,mBAAmB;CAC9B,AAAiB;CAEjB,YAAY,SAAgC;EAC1C,MAAM,EAAE,SAAS,WAAW,mBAAmB,WAAW,MAAM;AAChE,cAAY,UAAU;AACtB,OAAK,SAAS;;CAGhB,MAAM,UAAoB;AACxB,WAAS,MAAM,SAAS,IAAI,sBAAsB;AAChD,QAAK,OAAO,QAAQ,KAAK,CAAC;IAC1B","names":[],"sources":["../src/WYWinJSDebugPlugin.ts"],"version":3,"sourcesContent":["import type { Compiler } from 'webpack';\n\nimport type { EventEmitter, IFileReporterOptions } from '@wyw-in-js/transform';\nimport { createFileReporter } from '@wyw-in-js/transform';\n\nexport const sharedState: {\n emitter?: EventEmitter;\n} = {};\n\nexport class WYWinJSDebugPlugin {\n private readonly onDone: (root: string) => void;\n\n constructor(options?: IFileReporterOptions) {\n const { emitter, onDone } = createFileReporter(options ?? false);\n sharedState.emitter = emitter;\n this.onDone = onDone;\n }\n\n apply(compiler: Compiler) {\n compiler.hooks.shutdown.tap('WYWinJSDebug', () => {\n this.onDone(process.cwd());\n });\n }\n}\n"],"file":"WYWinJSDebugPlugin.js"}
package/esm/cache.js CHANGED
@@ -1,62 +1,61 @@
1
+ import { createRequire } from "module";
2
+ const nodeRequire = createRequire(import.meta.url);
1
3
  let cacheProviderSeq = 0;
2
4
  const cacheProviderIds = new WeakMap();
3
5
  const cacheProvidersById = new Map();
4
- export const registerCacheProvider = cacheProvider => {
5
- const knownId = cacheProviderIds.get(cacheProvider);
6
- if (knownId) {
7
- return knownId;
8
- }
9
- cacheProviderSeq += 1;
10
- const id = `${cacheProviderSeq}`;
11
- cacheProviderIds.set(cacheProvider, id);
12
- cacheProvidersById.set(id, cacheProvider);
13
- return id;
6
+ export const registerCacheProvider = (cacheProvider) => {
7
+ const knownId = cacheProviderIds.get(cacheProvider);
8
+ if (knownId) {
9
+ return knownId;
10
+ }
11
+ cacheProviderSeq += 1;
12
+ const id = `${cacheProviderSeq}`;
13
+ cacheProviderIds.set(cacheProvider, id);
14
+ cacheProvidersById.set(id, cacheProvider);
15
+ return id;
14
16
  };
15
-
16
17
  // memory cache, which is the default cache implementation in WYW-in-JS
17
-
18
18
  class MemoryCache {
19
- cache = new Map();
20
- dependenciesCache = new Map();
21
- get(key) {
22
- return Promise.resolve(this.cache.get(key) ?? '');
23
- }
24
- getDependencies(key) {
25
- return Promise.resolve(this.dependenciesCache.get(key) ?? []);
26
- }
27
- set(key, value) {
28
- this.cache.set(key, value);
29
- return Promise.resolve();
30
- }
31
- setDependencies(key, value) {
32
- this.dependenciesCache.set(key, value);
33
- return Promise.resolve();
34
- }
19
+ cache = new Map();
20
+ dependenciesCache = new Map();
21
+ get(key) {
22
+ return Promise.resolve(this.cache.get(key) ?? "");
23
+ }
24
+ getDependencies(key) {
25
+ return Promise.resolve(this.dependenciesCache.get(key) ?? []);
26
+ }
27
+ set(key, value) {
28
+ this.cache.set(key, value);
29
+ return Promise.resolve();
30
+ }
31
+ setDependencies(key, value) {
32
+ this.dependenciesCache.set(key, value);
33
+ return Promise.resolve();
34
+ }
35
35
  }
36
36
  export const memoryCache = new MemoryCache();
37
-
38
37
  /**
39
- * return cache instance from `options.cacheProvider`
40
- * @param cacheProvider string | ICache | undefined
41
- * @returns ICache instance
42
- */
38
+ * return cache instance from `options.cacheProvider`
39
+ * @param cacheProvider string | ICache | undefined
40
+ * @returns ICache instance
41
+ */
43
42
  export const getCacheInstance = async (cacheProvider, cacheProviderId) => {
44
- if (cacheProviderId) {
45
- const cacheProviderInstance = cacheProvidersById.get(cacheProviderId);
46
- if (!cacheProviderInstance) {
47
- throw new Error(`Invalid cache provider id: ${cacheProviderId}`);
48
- }
49
- return cacheProviderInstance;
50
- }
51
- if (!cacheProvider) {
52
- return memoryCache;
53
- }
54
- if (typeof cacheProvider === 'string') {
55
- return require(cacheProvider);
56
- }
57
- if (typeof cacheProvider === 'object' && 'get' in cacheProvider && 'set' in cacheProvider) {
58
- return cacheProvider;
59
- }
60
- throw new Error(`Invalid cache provider: ${cacheProvider}`);
43
+ if (cacheProviderId) {
44
+ const cacheProviderInstance = cacheProvidersById.get(cacheProviderId);
45
+ if (!cacheProviderInstance) {
46
+ throw new Error(`Invalid cache provider id: ${cacheProviderId}`);
47
+ }
48
+ return cacheProviderInstance;
49
+ }
50
+ if (!cacheProvider) {
51
+ return memoryCache;
52
+ }
53
+ if (typeof cacheProvider === "string") {
54
+ return nodeRequire(cacheProvider);
55
+ }
56
+ if (typeof cacheProvider === "object" && "get" in cacheProvider && "set" in cacheProvider) {
57
+ return cacheProvider;
58
+ }
59
+ throw new Error(`Invalid cache provider: ${cacheProvider}`);
61
60
  };
62
- //# sourceMappingURL=cache.js.map
61
+ //# sourceMappingURL=cache.js.map
package/esm/cache.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","names":["cacheProviderSeq","cacheProviderIds","WeakMap","cacheProvidersById","Map","registerCacheProvider","cacheProvider","knownId","get","id","set","MemoryCache","cache","dependenciesCache","key","Promise","resolve","getDependencies","value","setDependencies","memoryCache","getCacheInstance","cacheProviderId","cacheProviderInstance","Error","require"],"sources":["../src/cache.ts"],"sourcesContent":["export interface ICache {\n get: (key: string) => Promise<string>;\n getDependencies?: (key: string) => Promise<string[]>;\n set: (key: string, value: string) => Promise<void>;\n setDependencies?: (key: string, value: string[]) => Promise<void>;\n}\n\nlet cacheProviderSeq = 0;\nconst cacheProviderIds = new WeakMap<ICache, string>();\nconst cacheProvidersById = new Map<string, ICache>();\n\nexport const registerCacheProvider = (cacheProvider: ICache): string => {\n const knownId = cacheProviderIds.get(cacheProvider);\n if (knownId) {\n return knownId;\n }\n\n cacheProviderSeq += 1;\n const id = `${cacheProviderSeq}`;\n cacheProviderIds.set(cacheProvider, id);\n cacheProvidersById.set(id, cacheProvider);\n return id;\n};\n\n// memory cache, which is the default cache implementation in WYW-in-JS\n\nclass MemoryCache implements ICache {\n private cache: Map<string, string> = new Map();\n\n private dependenciesCache: Map<string, string[]> = new Map();\n\n public get(key: string): Promise<string> {\n return Promise.resolve(this.cache.get(key) ?? '');\n }\n\n public getDependencies(key: string): Promise<string[]> {\n return Promise.resolve(this.dependenciesCache.get(key) ?? []);\n }\n\n public set(key: string, value: string): Promise<void> {\n this.cache.set(key, value);\n return Promise.resolve();\n }\n\n public setDependencies(key: string, value: string[]): Promise<void> {\n this.dependenciesCache.set(key, value);\n return Promise.resolve();\n }\n}\n\nexport const memoryCache = new MemoryCache();\n\n/**\n * return cache instance from `options.cacheProvider`\n * @param cacheProvider string | ICache | undefined\n * @returns ICache instance\n */\nexport const getCacheInstance = async (\n cacheProvider: string | ICache | undefined,\n cacheProviderId?: string | undefined\n): Promise<ICache> => {\n if (cacheProviderId) {\n const cacheProviderInstance = cacheProvidersById.get(cacheProviderId);\n if (!cacheProviderInstance) {\n throw new Error(`Invalid cache provider id: ${cacheProviderId}`);\n }\n\n return cacheProviderInstance;\n }\n\n if (!cacheProvider) {\n return memoryCache;\n }\n if (typeof cacheProvider === 'string') {\n return require(cacheProvider);\n }\n if (\n typeof cacheProvider === 'object' &&\n 'get' in cacheProvider &&\n 'set' in cacheProvider\n ) {\n return cacheProvider;\n }\n throw new Error(`Invalid cache provider: ${cacheProvider}`);\n};\n"],"mappings":"AAOA,IAAIA,gBAAgB,GAAG,CAAC;AACxB,MAAMC,gBAAgB,GAAG,IAAIC,OAAO,CAAiB,CAAC;AACtD,MAAMC,kBAAkB,GAAG,IAAIC,GAAG,CAAiB,CAAC;AAEpD,OAAO,MAAMC,qBAAqB,GAAIC,aAAqB,IAAa;EACtE,MAAMC,OAAO,GAAGN,gBAAgB,CAACO,GAAG,CAACF,aAAa,CAAC;EACnD,IAAIC,OAAO,EAAE;IACX,OAAOA,OAAO;EAChB;EAEAP,gBAAgB,IAAI,CAAC;EACrB,MAAMS,EAAE,GAAG,GAAGT,gBAAgB,EAAE;EAChCC,gBAAgB,CAACS,GAAG,CAACJ,aAAa,EAAEG,EAAE,CAAC;EACvCN,kBAAkB,CAACO,GAAG,CAACD,EAAE,EAAEH,aAAa,CAAC;EACzC,OAAOG,EAAE;AACX,CAAC;;AAED;;AAEA,MAAME,WAAW,CAAmB;EAC1BC,KAAK,GAAwB,IAAIR,GAAG,CAAC,CAAC;EAEtCS,iBAAiB,GAA0B,IAAIT,GAAG,CAAC,CAAC;EAErDI,GAAGA,CAACM,GAAW,EAAmB;IACvC,OAAOC,OAAO,CAACC,OAAO,CAAC,IAAI,CAACJ,KAAK,CAACJ,GAAG,CAACM,GAAG,CAAC,IAAI,EAAE,CAAC;EACnD;EAEOG,eAAeA,CAACH,GAAW,EAAqB;IACrD,OAAOC,OAAO,CAACC,OAAO,CAAC,IAAI,CAACH,iBAAiB,CAACL,GAAG,CAACM,GAAG,CAAC,IAAI,EAAE,CAAC;EAC/D;EAEOJ,GAAGA,CAACI,GAAW,EAAEI,KAAa,EAAiB;IACpD,IAAI,CAACN,KAAK,CAACF,GAAG,CAACI,GAAG,EAAEI,KAAK,CAAC;IAC1B,OAAOH,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;EAEOG,eAAeA,CAACL,GAAW,EAAEI,KAAe,EAAiB;IAClE,IAAI,CAACL,iBAAiB,CAACH,GAAG,CAACI,GAAG,EAAEI,KAAK,CAAC;IACtC,OAAOH,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF;AAEA,OAAO,MAAMI,WAAW,GAAG,IAAIT,WAAW,CAAC,CAAC;;AAE5C;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMU,gBAAgB,GAAG,MAAAA,CAC9Bf,aAA0C,EAC1CgB,eAAoC,KAChB;EACpB,IAAIA,eAAe,EAAE;IACnB,MAAMC,qBAAqB,GAAGpB,kBAAkB,CAACK,GAAG,CAACc,eAAe,CAAC;IACrE,IAAI,CAACC,qBAAqB,EAAE;MAC1B,MAAM,IAAIC,KAAK,CAAC,8BAA8BF,eAAe,EAAE,CAAC;IAClE;IAEA,OAAOC,qBAAqB;EAC9B;EAEA,IAAI,CAACjB,aAAa,EAAE;IAClB,OAAOc,WAAW;EACpB;EACA,IAAI,OAAOd,aAAa,KAAK,QAAQ,EAAE;IACrC,OAAOmB,OAAO,CAACnB,aAAa,CAAC;EAC/B;EACA,IACE,OAAOA,aAAa,KAAK,QAAQ,IACjC,KAAK,IAAIA,aAAa,IACtB,KAAK,IAAIA,aAAa,EACtB;IACA,OAAOA,aAAa;EACtB;EACA,MAAM,IAAIkB,KAAK,CAAC,2BAA2BlB,aAAa,EAAE,CAAC;AAC7D,CAAC","ignoreList":[]}
1
+ {"mappings":"AAAA,SAAS,qBAAqB;AAE9B,MAAM,cAAc,cAAc,OAAO,KAAK,IAAI;AASlD,IAAI,mBAAmB;AACvB,MAAM,mBAAmB,IAAI,SAAyB;AACtD,MAAM,qBAAqB,IAAI,KAAqB;AAEpD,OAAO,MAAM,yBAAyB,kBAAkC;CACtE,MAAM,UAAU,iBAAiB,IAAI,cAAc;AACnD,KAAI,SAAS;AACX,SAAO;;AAGT,qBAAoB;CACpB,MAAM,KAAK,GAAG;AACd,kBAAiB,IAAI,eAAe,GAAG;AACvC,oBAAmB,IAAI,IAAI,cAAc;AACzC,QAAO;;;AAKT,MAAM,YAA8B;CAClC,AAAQ,QAA6B,IAAI,KAAK;CAE9C,AAAQ,oBAA2C,IAAI,KAAK;CAE5D,AAAO,IAAI,KAA8B;AACvC,SAAO,QAAQ,QAAQ,KAAK,MAAM,IAAI,IAAI,IAAI,GAAG;;CAGnD,AAAO,gBAAgB,KAAgC;AACrD,SAAO,QAAQ,QAAQ,KAAK,kBAAkB,IAAI,IAAI,IAAI,EAAE,CAAC;;CAG/D,AAAO,IAAI,KAAa,OAA8B;AACpD,OAAK,MAAM,IAAI,KAAK,MAAM;AAC1B,SAAO,QAAQ,SAAS;;CAG1B,AAAO,gBAAgB,KAAa,OAAgC;AAClE,OAAK,kBAAkB,IAAI,KAAK,MAAM;AACtC,SAAO,QAAQ,SAAS;;;AAI5B,OAAO,MAAM,cAAc,IAAI,aAAa;;;;;;AAO5C,OAAO,MAAM,mBAAmB,OAC9B,eACA,oBACoB;AACpB,KAAI,iBAAiB;EACnB,MAAM,wBAAwB,mBAAmB,IAAI,gBAAgB;AACrE,MAAI,CAAC,uBAAuB;AAC1B,SAAM,IAAI,MAAM,8BAA8B,kBAAkB;;AAGlE,SAAO;;AAGT,KAAI,CAAC,eAAe;AAClB,SAAO;;AAET,KAAI,OAAO,kBAAkB,UAAU;AACrC,SAAO,YAAY,cAAc;;AAEnC,KACE,OAAO,kBAAkB,YACzB,SAAS,iBACT,SAAS,eACT;AACA,SAAO;;AAET,OAAM,IAAI,MAAM,2BAA2B,gBAAgB","names":[],"sources":["../src/cache.ts"],"version":3,"sourcesContent":["import { createRequire } from 'module';\n\nconst nodeRequire = createRequire(import.meta.url);\n\nexport interface ICache {\n get: (key: string) => Promise<string>;\n getDependencies?: (key: string) => Promise<string[]>;\n set: (key: string, value: string) => Promise<void>;\n setDependencies?: (key: string, value: string[]) => Promise<void>;\n}\n\nlet cacheProviderSeq = 0;\nconst cacheProviderIds = new WeakMap<ICache, string>();\nconst cacheProvidersById = new Map<string, ICache>();\n\nexport const registerCacheProvider = (cacheProvider: ICache): string => {\n const knownId = cacheProviderIds.get(cacheProvider);\n if (knownId) {\n return knownId;\n }\n\n cacheProviderSeq += 1;\n const id = `${cacheProviderSeq}`;\n cacheProviderIds.set(cacheProvider, id);\n cacheProvidersById.set(id, cacheProvider);\n return id;\n};\n\n// memory cache, which is the default cache implementation in WYW-in-JS\n\nclass MemoryCache implements ICache {\n private cache: Map<string, string> = new Map();\n\n private dependenciesCache: Map<string, string[]> = new Map();\n\n public get(key: string): Promise<string> {\n return Promise.resolve(this.cache.get(key) ?? '');\n }\n\n public getDependencies(key: string): Promise<string[]> {\n return Promise.resolve(this.dependenciesCache.get(key) ?? []);\n }\n\n public set(key: string, value: string): Promise<void> {\n this.cache.set(key, value);\n return Promise.resolve();\n }\n\n public setDependencies(key: string, value: string[]): Promise<void> {\n this.dependenciesCache.set(key, value);\n return Promise.resolve();\n }\n}\n\nexport const memoryCache = new MemoryCache();\n\n/**\n * return cache instance from `options.cacheProvider`\n * @param cacheProvider string | ICache | undefined\n * @returns ICache instance\n */\nexport const getCacheInstance = async (\n cacheProvider: string | ICache | undefined,\n cacheProviderId?: string | undefined\n): Promise<ICache> => {\n if (cacheProviderId) {\n const cacheProviderInstance = cacheProvidersById.get(cacheProviderId);\n if (!cacheProviderInstance) {\n throw new Error(`Invalid cache provider id: ${cacheProviderId}`);\n }\n\n return cacheProviderInstance;\n }\n\n if (!cacheProvider) {\n return memoryCache;\n }\n if (typeof cacheProvider === 'string') {\n return nodeRequire(cacheProvider);\n }\n if (\n typeof cacheProvider === 'object' &&\n 'get' in cacheProvider &&\n 'set' in cacheProvider\n ) {\n return cacheProvider;\n }\n throw new Error(`Invalid cache provider: ${cacheProvider}`);\n};\n"],"file":"cache.js"}
package/esm/index.js CHANGED
@@ -1,183 +1,231 @@
1
1
  /**
2
- * This file contains a Webpack loader for WYW-in-JS.
3
- * It uses the transform.ts function to generate class names from source code,
4
- * returns transformed code without template literals and attaches generated source maps
5
- */
6
-
7
- import path from 'path';
8
- import crypto from 'crypto';
9
- import { logger } from '@wyw-in-js/shared';
10
- import { transform, TransformCacheCollection } from '@wyw-in-js/transform';
11
- import { sharedState } from './WYWinJSDebugPlugin';
12
- import { getCacheInstance, registerCacheProvider } from './cache';
13
- export { WYWinJSDebugPlugin } from './WYWinJSDebugPlugin';
14
- const outputCssLoader = require.resolve('./outputCssLoader');
15
- const stripQueryAndHash = request => {
16
- const queryIdx = request.indexOf('?');
17
- const hashIdx = request.indexOf('#');
18
- if (queryIdx === -1) {
19
- return hashIdx === -1 ? request : request.slice(0, hashIdx);
20
- }
21
- if (hashIdx === -1) return request.slice(0, queryIdx);
22
- return request.slice(0, Math.min(queryIdx, hashIdx));
2
+ * This file contains a Webpack loader for WYW-in-JS.
3
+ * It uses the transform.ts function to generate class names from source code,
4
+ * returns transformed code without template literals and attaches generated source maps
5
+ */
6
+ import path from "path";
7
+ import crypto from "crypto";
8
+ import { fileURLToPath } from "url";
9
+ import { logger } from "@wyw-in-js/shared";
10
+ import { disposeEvalBroker, transform, TransformCacheCollection } from "@wyw-in-js/transform";
11
+ import { sharedState } from "./WYWinJSDebugPlugin.js";
12
+ import { getCacheInstance, registerCacheProvider } from "./cache.js";
13
+ export { WYWinJSDebugPlugin } from "./WYWinJSDebugPlugin.js";
14
+ const outputCssLoader = fileURLToPath(new URL("./outputCssLoader.js", import.meta.url));
15
+ const stripQueryAndHash = (request) => {
16
+ const queryIdx = request.indexOf("?");
17
+ const hashIdx = request.indexOf("#");
18
+ if (queryIdx === -1) {
19
+ return hashIdx === -1 ? request : request.slice(0, hashIdx);
20
+ }
21
+ if (hashIdx === -1) return request.slice(0, queryIdx);
22
+ return request.slice(0, Math.min(queryIdx, hashIdx));
23
23
  };
24
- const hashText = text => crypto.createHash('sha256').update(text).digest('hex').slice(0, 12);
25
- const cache = new TransformCacheCollection();
26
- const resolvers = {};
24
+ const hashText = (text) => crypto.createHash("sha256").update(text).digest("hex").slice(0, 12);
25
+ const COMPILER_SCOPE_NAME = "WYWinJSResolverScope";
26
+ let compilerScopeId = 0;
27
+ const compilerStates = new WeakMap();
27
28
  const getResolverKey = (importer, stack) => {
28
- const root = stack.length ? stack[stack.length - 1] : importer;
29
- return stripQueryAndHash(root);
29
+ const root = stack.length ? stack[stack.length - 1] : importer;
30
+ return stripQueryAndHash(root);
30
31
  };
31
- const getActiveResolvers = key => {
32
- const entries = resolvers[key];
33
- return entries?.length ? entries : [];
32
+ const createResolverScope = () => {
33
+ const resolvers = new Map();
34
+ compilerScopeId += 1;
35
+ const key = `webpack:${compilerScopeId}`;
36
+ return {
37
+ asyncResolve: (what, importer, stack = [importer]) => {
38
+ const resolverKeys = [getResolverKey(importer, stack), stripQueryAndHash(importer)].filter((candidate, idx, all) => all.indexOf(candidate) === idx);
39
+ const selectedResolvers = resolverKeys.map((resolverKey) => resolvers.get(resolverKey)).filter((resolver) => Boolean(resolver));
40
+ if (selectedResolvers.length === 0) {
41
+ throw new Error("No resolver found");
42
+ }
43
+ // Root and importer resolver side effects both matter for dependency
44
+ // tracking, so keep them aligned and verify they agree on the answer.
45
+ return Promise.all(selectedResolvers.map((resolver) => resolver(what, importer, stack))).then((results) => {
46
+ const firstResult = results[0];
47
+ if (results.some((result) => result !== firstResult)) {
48
+ throw new Error("Resolvers returned different results");
49
+ }
50
+ return firstResult;
51
+ });
52
+ },
53
+ cache: new TransformCacheCollection(),
54
+ dispose: () => {
55
+ resolvers.clear();
56
+ },
57
+ key,
58
+ replaceResolver: (resourcePath, resolver) => {
59
+ resolvers.set(stripQueryAndHash(resourcePath), resolver);
60
+ }
61
+ };
34
62
  };
35
- const createAsyncResolve = resourcePath => {
36
- const currentResolverKey = stripQueryAndHash(resourcePath);
37
- return (what, importer, stack = [importer]) => {
38
- const rootResolverKey = getResolverKey(importer, stack);
39
- const rootResolvers = getActiveResolvers(rootResolverKey);
40
- const resolver = rootResolvers.length > 0 ? rootResolvers : getActiveResolvers(currentResolverKey);
41
- if (resolver.length === 0) {
42
- throw new Error('No resolver found');
43
- }
44
-
45
- // Every resolver should return the same result, but we need to call all of them
46
- // to ensure that all side effects are executed (e.g. adding dependencies)
47
- return Promise.all(resolver.map(r => r(what, importer, stack))).then(results => {
48
- const firstResult = results[0];
49
- if (results.some(r => r !== firstResult)) {
50
- throw new Error('Resolvers returned different results');
51
- }
52
- return firstResult;
53
- });
54
- };
63
+ const disposeCompilerState = (state) => {
64
+ state.clearResolvers();
65
+ disposeEvalBroker(state.cache);
66
+ };
67
+ const getCompilerState = (compiler) => {
68
+ const cached = compilerStates.get(compiler);
69
+ if (cached) {
70
+ return cached;
71
+ }
72
+ // Resolver identity must stay stable across files within one compiler or we
73
+ // churn both the shared transform cache salt and the eval broker/runner.
74
+ const scope = createResolverScope();
75
+ const state = {
76
+ ...scope,
77
+ clearResolvers: scope.dispose,
78
+ dispose: () => disposeCompilerState(state),
79
+ hooksInstalled: false
80
+ };
81
+ const installHooks = () => {
82
+ if (state.hooksInstalled) return;
83
+ state.hooksInstalled = true;
84
+ compiler.hooks.done?.tap(COMPILER_SCOPE_NAME, () => {
85
+ state.clearResolvers();
86
+ });
87
+ compiler.hooks.failed?.tap(COMPILER_SCOPE_NAME, () => {
88
+ state.clearResolvers();
89
+ });
90
+ compiler.hooks.watchClose?.tap(COMPILER_SCOPE_NAME, () => {
91
+ state.dispose();
92
+ compilerStates.delete(compiler);
93
+ });
94
+ compiler.hooks.shutdown?.tap(COMPILER_SCOPE_NAME, () => {
95
+ state.dispose();
96
+ compilerStates.delete(compiler);
97
+ });
98
+ };
99
+ installHooks();
100
+ compilerStates.set(compiler, state);
101
+ return state;
102
+ };
103
+ const createInvocationScope = () => {
104
+ const scope = createResolverScope();
105
+ return {
106
+ ...scope,
107
+ dispose: () => {
108
+ scope.dispose();
109
+ disposeEvalBroker(scope.cache);
110
+ }
111
+ };
55
112
  };
56
- function addResolver(resourcePath, resolver) {
57
- if (!resolvers[resourcePath]) {
58
- resolvers[resourcePath] = [];
59
- }
60
- resolvers[resourcePath].push(resolver);
61
- return () => {
62
- resolvers[resourcePath] = resolvers[resourcePath].filter(r => r !== resolver);
63
- };
64
- }
65
113
  const webpack5Loader = function webpack5LoaderPlugin(content, inputSourceMap) {
66
- function convertSourceMap(value, filename) {
67
- if (typeof value === 'string' || !value) {
68
- return undefined;
69
- }
70
- return {
71
- ...value,
72
- file: value.file ?? filename,
73
- mappings: value.mappings ?? '',
74
- names: value.names ?? [],
75
- sources: value.sources ?? [],
76
- version: value.version ?? 3
77
- };
78
- }
79
-
80
- // tell Webpack this loader is async
81
- this.async();
82
- const resolveOptions = {
83
- dependencyType: 'esm'
84
- };
85
- const resolveModule = this.getResolve(resolveOptions);
86
- const isPromiseLike = value => typeof value?.then === 'function';
87
- const resolveModuleAsync = (context, request) => new Promise((resolve, reject) => {
88
- let settled = false;
89
- const finish = (err, result) => {
90
- if (settled) return;
91
- settled = true;
92
- if (err) {
93
- reject(err);
94
- return;
95
- }
96
- if (typeof result === 'string') {
97
- resolve(result);
98
- return;
99
- }
100
- reject(new Error(`Cannot resolve ${request}`));
101
- };
102
- try {
103
- const maybePromise = resolveModule(context, request, finish);
104
- if (isPromiseLike(maybePromise)) {
105
- maybePromise.then(result => finish(null, result), err => finish(err, null));
106
- }
107
- } catch (err) {
108
- finish(err, null);
109
- }
110
- });
111
- const removeResolver = addResolver(this.resourcePath, (what, importer) => {
112
- const importerPath = stripQueryAndHash(importer);
113
- const context = path.isAbsolute(importerPath) ? path.dirname(importerPath) : path.join(process.cwd(), path.dirname(importerPath));
114
- return resolveModuleAsync(context, what).then(result => {
115
- const filePath = stripQueryAndHash(result);
116
- if (path.isAbsolute(filePath)) {
117
- this.addDependency(filePath);
118
- }
119
- return result;
120
- });
121
- });
122
- const asyncResolve = createAsyncResolve(this.resourcePath);
123
- logger('loader %s', this.resourcePath);
124
- const {
125
- sourceMap = undefined,
126
- preprocessor = undefined,
127
- keepComments = undefined,
128
- prefixer = undefined,
129
- extension = '.wyw-in-js.css',
130
- cssImport = 'require',
131
- cacheProvider,
132
- ...rest
133
- } = this.getOptions() || {};
134
- const outputFileName = this.resourcePath.replace(/\.[^.]+$/, extension);
135
- const transformServices = {
136
- options: {
137
- filename: this.resourcePath,
138
- inputSourceMap: convertSourceMap(inputSourceMap, this.resourcePath),
139
- pluginOptions: rest,
140
- prefixer,
141
- keepComments,
142
- preprocessor,
143
- root: process.cwd()
144
- },
145
- cache,
146
- emitWarning: message => this.emitWarning(new Error(message)),
147
- eventEmitter: sharedState.emitter
148
- };
149
- transform(transformServices, content.toString(), asyncResolve).then(async result => {
150
- try {
151
- if (result.cssText) {
152
- let {
153
- cssText
154
- } = result;
155
- if (sourceMap) {
156
- cssText += `/*# sourceMappingURL=data:application/json;base64,${Buffer.from(result.cssSourceMapText || '').toString('base64')}*/`;
157
- }
158
- await Promise.all(result.dependencies?.map(dep => asyncResolve(dep, this.resourcePath)) ?? []);
159
- const cacheInstance = await getCacheInstance(cacheProvider);
160
- const cacheProviderId = cacheProvider && typeof cacheProvider === 'object' ? registerCacheProvider(cacheInstance) : '';
161
- await cacheInstance.set(this.resourcePath, cssText);
162
- await cacheInstance.setDependencies?.(this.resourcePath, this.getDependencies());
163
- const wywQuery = [`wyw=${encodeURIComponent(extension.replace(/^\./, ''))}`];
164
- if (this.hot) {
165
- wywQuery.push(`v=${encodeURIComponent(hashText(cssText))}`);
166
- }
167
- const resourcePathWithQuery = `${this.resourcePath}?${wywQuery.join('&')}`;
168
- const request = `${outputFileName}!=!${outputCssLoader}?cacheProvider=${encodeURIComponent(typeof cacheProvider === 'string' ? cacheProvider : '')}&cacheProviderId=${encodeURIComponent(cacheProviderId)}!${resourcePathWithQuery}`;
169
- const stringifiedRequest = JSON.stringify(this.utils.contextify(this.context || this.rootContext, request));
170
- const importCss = cssImport === 'import' ? `import ${stringifiedRequest};` : `require(${stringifiedRequest});`;
171
- this.callback(null, `${result.code}\n\n${importCss}`, result.sourceMap ?? undefined);
172
- return;
173
- }
174
- this.callback(null, result.code, result.sourceMap ?? undefined);
175
- } catch (err) {
176
- this.callback(err);
177
- }
178
- }, err => {
179
- this.callback(err);
180
- }).catch(err => this.callback(err)).finally(removeResolver);
114
+ function convertSourceMap(value, filename) {
115
+ if (typeof value === "string" || !value) {
116
+ return undefined;
117
+ }
118
+ return {
119
+ ...value,
120
+ file: value.file ?? filename,
121
+ mappings: value.mappings ?? "",
122
+ names: value.names ?? [],
123
+ sources: value.sources ?? [],
124
+ version: value.version ?? 3
125
+ };
126
+ }
127
+ // tell Webpack this loader is async
128
+ this.async();
129
+ const resolveOptions = { dependencyType: "esm" };
130
+ const resolveModule = this.getResolve(resolveOptions);
131
+ const isPromiseLike = (value) => typeof value?.then === "function";
132
+ const resolveModuleAsync = (context, request) => new Promise((resolve, reject) => {
133
+ let settled = false;
134
+ const finish = (err, result) => {
135
+ if (settled) return;
136
+ settled = true;
137
+ if (err) {
138
+ reject(err);
139
+ return;
140
+ }
141
+ if (typeof result === "string") {
142
+ resolve(result);
143
+ return;
144
+ }
145
+ reject(new Error(`Cannot resolve ${request}`));
146
+ };
147
+ try {
148
+ const maybePromise = resolveModule(context, request, finish);
149
+ if (isPromiseLike(maybePromise)) {
150
+ maybePromise.then((result) => finish(null, result), (err) => finish(err, null));
151
+ }
152
+ } catch (err) {
153
+ finish(err, null);
154
+ }
155
+ });
156
+ const { _compiler: compiler } = this;
157
+ const compilerState = compiler ? getCompilerState(compiler) : createInvocationScope();
158
+ compilerState.replaceResolver(this.resourcePath, (what, importer) => {
159
+ const importerPath = stripQueryAndHash(importer);
160
+ const context = path.isAbsolute(importerPath) ? path.dirname(importerPath) : path.join(process.cwd(), path.dirname(importerPath));
161
+ return resolveModuleAsync(context, what).then((result) => {
162
+ const filePath = stripQueryAndHash(result);
163
+ if (path.isAbsolute(filePath)) {
164
+ this.addDependency(filePath);
165
+ }
166
+ return result;
167
+ });
168
+ });
169
+ const { asyncResolve, cache: transformCache, key: asyncResolveKey } = compilerState;
170
+ logger("loader %s", this.resourcePath);
171
+ const { sourceMap = undefined, preprocessor = undefined, keepComments = undefined, prefixer = undefined, extension = ".wyw-in-js.css", cssImport = "require", cacheProvider, ...rest } = this.getOptions() || {};
172
+ const outputFileName = this.resourcePath.replace(/\.[^.]+$/, extension);
173
+ const transformServices = {
174
+ options: {
175
+ filename: this.resourcePath,
176
+ inputSourceMap: convertSourceMap(inputSourceMap, this.resourcePath),
177
+ pluginOptions: rest,
178
+ prefixer,
179
+ keepComments,
180
+ preprocessor,
181
+ root: process.cwd()
182
+ },
183
+ asyncResolveKey,
184
+ cache: transformCache,
185
+ emitWarning: (message) => {
186
+ const warning = new Error(message);
187
+ // Remove the stack so webpack's ModuleWarning doesn't copy it into
188
+ // `details`, which causes the message to render twice (once from
189
+ // .message, once from .details containing "Error: <same message>").
190
+ delete warning.stack;
191
+ this.emitWarning(warning);
192
+ },
193
+ eventEmitter: sharedState.emitter
194
+ };
195
+ transform(transformServices, content.toString(), asyncResolve).then(async (result) => {
196
+ try {
197
+ if (result.cssText) {
198
+ let { cssText } = result;
199
+ if (sourceMap) {
200
+ cssText += `/*# sourceMappingURL=data:application/json;base64,${Buffer.from(result.cssSourceMapText || "").toString("base64")}*/`;
201
+ }
202
+ await Promise.all(result.dependencies?.map((dep) => asyncResolve(dep, this.resourcePath)) ?? []);
203
+ const cacheInstance = await getCacheInstance(cacheProvider);
204
+ const cacheProviderId = cacheProvider && typeof cacheProvider === "object" ? registerCacheProvider(cacheInstance) : "";
205
+ await cacheInstance.set(this.resourcePath, cssText);
206
+ await cacheInstance.setDependencies?.(this.resourcePath, this.getDependencies());
207
+ const wywQuery = [`wyw=${encodeURIComponent(extension.replace(/^\./, ""))}`];
208
+ if (this.hot) {
209
+ wywQuery.push(`v=${encodeURIComponent(hashText(cssText))}`);
210
+ }
211
+ const resourcePathWithQuery = `${this.resourcePath}?${wywQuery.join("&")}`;
212
+ const request = `${outputFileName}!=!${outputCssLoader}?cacheProvider=${encodeURIComponent(typeof cacheProvider === "string" ? cacheProvider : "")}&cacheProviderId=${encodeURIComponent(cacheProviderId)}!${resourcePathWithQuery}`;
213
+ const stringifiedRequest = JSON.stringify(this.utils.contextify(this.context || this.rootContext, request));
214
+ const importCss = cssImport === "import" ? `import ${stringifiedRequest};` : `require(${stringifiedRequest});`;
215
+ this.callback(null, `${result.code}\n\n${importCss}`, result.sourceMap ?? undefined);
216
+ return;
217
+ }
218
+ this.callback(null, result.code, result.sourceMap ?? undefined);
219
+ } catch (err) {
220
+ this.callback(err);
221
+ }
222
+ }, (err) => {
223
+ this.callback(err);
224
+ }).catch((err) => this.callback(err)).finally(() => {
225
+ if (!compiler) {
226
+ compilerState.dispose();
227
+ }
228
+ });
181
229
  };
182
230
  export default webpack5Loader;
183
- //# sourceMappingURL=index.js.map
231
+ //# sourceMappingURL=index.js.map