source: frontend/node_modules/enhanced-resolve/lib/MainFieldPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const DescriptionFileUtils = require("./DescriptionFileUtils");
9
10/** @typedef {import("./Resolver")} Resolver */
11/** @typedef {import("./Resolver").JsonObject} JsonObject */
12/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
13/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
14
15/** @typedef {{ name: string | string[], forceRelative: boolean }} MainFieldOptions */
16
17const alreadyTriedMainField = Symbol("alreadyTriedMainField");
18
19// Sentinel cached for description files where the main field resolves to a
20// value we cannot use (missing, non-string, ".", "./"). Cheaper to store and
21// check than to re-walk the description file on every resolve.
22const NO_MAIN = Symbol("NoMain");
23
24module.exports = class MainFieldPlugin {
25 /**
26 * @param {string | ResolveStepHook} source source
27 * @param {MainFieldOptions} options options
28 * @param {string | ResolveStepHook} target target
29 */
30 constructor(source, options, target) {
31 this.source = source;
32 this.options = options;
33 this.target = target;
34 // Cache the resolved `mainModule` per description-file content. The
35 // options (`name`, `forceRelative`) are fixed for this plugin
36 // instance, so caching against content alone is safe. Stores either
37 // the ready-to-use request string or the `NO_MAIN` sentinel.
38 /** @type {WeakMap<JsonObject, string | typeof NO_MAIN>} */
39 this._mainModuleCache = new WeakMap();
40 }
41
42 /**
43 * @param {Resolver} resolver the resolver
44 * @returns {void}
45 */
46 apply(resolver) {
47 const target = resolver.ensureHook(this.target);
48 resolver
49 .getHook(this.source)
50 .tapAsync("MainFieldPlugin", (request, resolveContext, callback) => {
51 if (
52 request.path !== request.descriptionFileRoot ||
53 /** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
54 (request)[alreadyTriedMainField] === request.descriptionFilePath ||
55 !request.descriptionFilePath
56 ) {
57 return callback();
58 }
59 const descFileData = /** @type {JsonObject} */ (
60 request.descriptionFileData
61 );
62 let mainModule = this._mainModuleCache.get(descFileData);
63 if (mainModule === undefined) {
64 let raw =
65 /** @type {string | null | undefined} */
66 (DescriptionFileUtils.getField(descFileData, this.options.name));
67 if (!raw || typeof raw !== "string" || raw === "." || raw === "./") {
68 this._mainModuleCache.set(descFileData, NO_MAIN);
69 return callback();
70 }
71 if (this.options.forceRelative && !/^\.\.?\//.test(raw)) {
72 raw = `./${raw}`;
73 }
74 mainModule = raw;
75 this._mainModuleCache.set(descFileData, mainModule);
76 } else if (mainModule === NO_MAIN) {
77 return callback();
78 }
79 const filename = resolver.basename(request.descriptionFilePath);
80 /** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
81 const obj = {
82 ...request,
83 request: mainModule,
84 module: false,
85 directory: mainModule.endsWith("/"),
86 [alreadyTriedMainField]: request.descriptionFilePath,
87 };
88 return resolver.doResolve(
89 target,
90 obj,
91 `use ${mainModule} from ${this.options.name} in ${filename}`,
92 resolveContext,
93 callback,
94 );
95 });
96 }
97};
Note: See TracBrowser for help on using the repository browser.