webpack: Generalize debug-require-webpack-plugin interface.

Now the caller simply imports the debug ‘require’ function as a
module, deciding for itself how to expose it and with what name (in
our case, we expose it as ‘require’ with expose-loader).  Also, remove
a stray console.log.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
Anders Kaseorg 2020-02-24 23:18:50 -08:00 committed by Tim Abbott
parent 60b5d372f9
commit b474fa0e37
4 changed files with 44 additions and 24 deletions

View File

@ -1,5 +1,6 @@
import "core-js/features/promise";
import "core-js/features/symbol";
import "../../../tools/debug-require";
import "jquery/dist/jquery.js";
import "underscore/underscore.js";
import "../page_params.js";

View File

@ -9,6 +9,7 @@ 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")
@ -36,18 +37,34 @@ export default class DebugRequirePlugin {
});
});
compiler.hooks.beforeCompile.tapPromise(
"DebugRequirePlugin",
async ({ normalModuleFactory }: any) => {
const resolver = normalModuleFactory.getResolver("normal");
debugRequirePath = await new Promise((resolve, reject) =>
resolver.resolve(
{},
__dirname,
"./debug-require.js",
{},
(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(
(mod: any) => {
const { resource, rawRequest, id } = mod;
({ resource, rawRequest, id }: any) => {
if (resource === debugRequirePath) {
debugRequireId = id;
}
for (const name of resolved.get(resource) || []) {
if (name === "./static/js/debug.js") {
console.log(name, id, mod);
}
ids.push([
rawRequest.slice(0, rawRequest.lastIndexOf("!") + 1) + name,
id,
@ -57,28 +74,18 @@ export default class DebugRequirePlugin {
},
() => true
);
if (debugRequireId === undefined) {
return source;
}
ids.sort();
const {
outputOptions: { globalObject },
requireFn,
} = compilation.mainTemplate;
const { requireFn } = compilation.mainTemplate;
return Template.asString([
source,
`function debugRequire(request) {`,
Template.indent(`return ${requireFn}(debugRequire.ids[request]);`),
"};",
`debugRequire.ids = ${JSON.stringify(
Object.fromEntries(ids),
null,
"\t"
)};`,
`if (typeof ${globalObject} !== "undefined") {`,
Template.indent(
`${globalObject}.require = ${globalObject}.require || debugRequire;`
),
"}",
`${requireFn}(${JSON.stringify(
debugRequireId
)}).initialize(${JSON.stringify(Object.fromEntries(ids), null, "\t")});`,
]);
}
);

11
tools/debug-require.js Normal file
View File

@ -0,0 +1,11 @@
/* global __webpack_require__ */
function debugRequire(request) {
return __webpack_require__(debugRequire.ids[request]);
}
debugRequire.initialize = function (ids) {
debugRequire.ids = ids;
};
module.exports = debugRequire;

View File

@ -219,6 +219,7 @@ export default (env?: string): webpack.Configuration[] => {
// Use the unminified versions of jquery and underscore so that
// Good error messages show up in production and development in the source maps
const exposeOptions = [
{ path: "./debug-require.js", name: "require" },
{ path: "blueimp-md5/js/md5.js" },
{ path: "clipboard/dist/clipboard.js", name: "ClipboardJS" },
{ path: "xdate/src/xdate.js", name: "XDate" },