mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-30 19:43:47 +00:00 
			
		
		
		
	TypeScript type-only imports will probably become important eventually for reducing our circular import problem. https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export Signed-off-by: Anders Kaseorg <anders@zulip.com>
		
			
				
	
	
		
			101 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // This plugin exposes a version of require() to the browser console to assist
 | |
| // debugging.  It also exposes the list of modules it knows about as the keys
 | |
| // of the require.ids object.
 | |
| 
 | |
| import path from "path";
 | |
| 
 | |
| import type webpack from "webpack";
 | |
| import {Template} from "webpack";
 | |
| 
 | |
| export default class DebugRequirePlugin {
 | |
|     apply(compiler: webpack.Compiler): void {
 | |
|         const resolved = new Map();
 | |
|         const nameSymbol = Symbol("DebugRequirePluginName");
 | |
|         let debugRequirePath: string | undefined;
 | |
| 
 | |
|         (compiler as any).resolverFactory.hooks.resolver
 | |
|             .for("normal")
 | |
|             .tap("DebugRequirePlugin", (resolver: any) => {
 | |
|                 resolver.getHook("beforeRawModule").tap("DebugRequirePlugin", (req: any) => {
 | |
|                     req[nameSymbol] = req[nameSymbol] || req.request;
 | |
|                 });
 | |
| 
 | |
|                 resolver.getHook("beforeRelative").tap("DebugRequirePlugin", (req: any) => {
 | |
|                     const inPath = path.relative(compiler.context, req.path);
 | |
|                     if (!inPath.startsWith("../")) {
 | |
|                         req[nameSymbol] = req[nameSymbol] || "./" + inPath;
 | |
|                     }
 | |
|                 });
 | |
| 
 | |
|                 resolver.getHook("beforeResolved").tap("DebugRequirePlugin", (req: any) => {
 | |
|                     if (req[nameSymbol]) {
 | |
|                         const names = resolved.get(req.path);
 | |
|                         if (names) {
 | |
|                             names.add(req[nameSymbol]);
 | |
|                         } else {
 | |
|                             resolved.set(req.path, new Set([req[nameSymbol]]));
 | |
|                         }
 | |
|                     }
 | |
|                 });
 | |
|             });
 | |
| 
 | |
|         compiler.hooks.beforeCompile.tapPromise(
 | |
|             "DebugRequirePlugin",
 | |
|             async ({normalModuleFactory}: any) => {
 | |
|                 const resolver = normalModuleFactory.getResolver("normal");
 | |
|                 debugRequirePath = await new Promise((resolve, reject) =>
 | |
|                     resolver.resolve(
 | |
|                         {},
 | |
|                         __dirname,
 | |
|                         "./debug-require",
 | |
|                         {},
 | |
|                         (err?: Error, result?: string) => (err ? reject(err) : resolve(result)),
 | |
|                     ),
 | |
|                 );
 | |
|             },
 | |
|         );
 | |
| 
 | |
|         compiler.hooks.compilation.tap("DebugRequirePlugin", (compilation: any) => {
 | |
|             compilation.mainTemplate.hooks.beforeStartup.tap(
 | |
|                 "DebugRequirePlugin",
 | |
|                 (source: string, chunk: webpack.compilation.Chunk) => {
 | |
|                     const ids: [string, string | number][] = [];
 | |
|                     let debugRequireId;
 | |
|                     chunk.hasModuleInGraph(
 | |
|                         ({resource, rawRequest, id}: any) => {
 | |
|                             if (resource === debugRequirePath) {
 | |
|                                 debugRequireId = id;
 | |
|                             }
 | |
|                             for (const name of resolved.get(resource) || []) {
 | |
|                                 ids.push([
 | |
|                                     rawRequest.slice(0, rawRequest.lastIndexOf("!") + 1) + name,
 | |
|                                     id,
 | |
|                                 ]);
 | |
|                             }
 | |
|                             return false;
 | |
|                         },
 | |
|                         () => true,
 | |
|                     );
 | |
| 
 | |
|                     if (debugRequireId === undefined) {
 | |
|                         return source;
 | |
|                     }
 | |
| 
 | |
|                     ids.sort();
 | |
|                     const {requireFn} = compilation.mainTemplate;
 | |
|                     return Template.asString([
 | |
|                         source,
 | |
|                         `${requireFn}(${JSON.stringify(
 | |
|                             debugRequireId,
 | |
|                         )}).initialize(${JSON.stringify(
 | |
|                             Object.fromEntries(ids),
 | |
|                             null,
 | |
|                             "\t",
 | |
|                         )}, modules);`,
 | |
|                     ]);
 | |
|                 },
 | |
|             );
 | |
|         });
 | |
|     }
 | |
| }
 |