UNPKG

dependency-cruiser

Version:

Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

135 lines (119 loc) 4.13 kB
import { extname } from "node:path"; import { createRequire } from "node:module"; import makeAbsolute from "./make-absolute.mjs"; const require = createRequire(import.meta.url); function pryConfigFromTheConfig( pWebpackConfigModule, pEnvironment, pArguments ) { let lReturnValue = pWebpackConfigModule; if (typeof pWebpackConfigModule === "function") { lReturnValue = pWebpackConfigModule(pEnvironment, pArguments); } if (Array.isArray(pWebpackConfigModule)) { lReturnValue = pryConfigFromTheConfig( pWebpackConfigModule[0], pEnvironment, pArguments ); } return lReturnValue; } function suggestModules(pSuggestionList, pWebpackConfigFilename) { let lReturnValue = ""; let lSuggestionList = pSuggestionList; if (pSuggestionList && typeof pSuggestionList === "string") { lSuggestionList = [pSuggestionList]; } if (Array.isArray(lSuggestionList) && lSuggestionList.length > 0) { lReturnValue = lSuggestionList.reduce( (pAll, pCurrent) => `${pAll} - ${pCurrent.module || pCurrent}\n`, `\n Some npm modules that might fix that problem (one of which you'll` + `\n need so '${pWebpackConfigFilename}' works with webpack anyway):\n` ); } return lReturnValue; } function tryRegisterNonNative(pWebpackConfigFilename) { const lConfigExtension = extname(pWebpackConfigFilename); const interpret = require("interpret"); const rechoir = require("rechoir"); try { rechoir.prepare(interpret.extensions, pWebpackConfigFilename); } catch (pError) { throw new Error( `${pError.message}` + `\n${suggestModules( // eslint-disable-next-line security/detect-object-injection interpret.extensions[lConfigExtension], pWebpackConfigFilename )}` ); } } function isNativelySupported(pWebpackConfigFilename) { const lNativelySupportedExtensions = [ ".js", ".cjs", ".mjs", ".json", ".node", ]; const lWebpackConfigExtension = extname(pWebpackConfigFilename); return lNativelySupportedExtensions.includes(lWebpackConfigExtension); } async function attemptImport(pAbsoluteWebpackConfigFileName) { try { if (isNativelySupported(pAbsoluteWebpackConfigFileName)) { const { default: lModule } = await import( `file://${pAbsoluteWebpackConfigFileName}` ); return lModule; } else { tryRegisterNonNative(pAbsoluteWebpackConfigFileName); /* we're using still using require instead of dynamic imports here because * the modules webpack uses for non-native formats monkey-patch on the commonjs * module system. If we'd use a dynamic import, these monkey-patches wouldn't * be used. */ /* eslint node/global-require:0, security/detect-non-literal-require:0, import/no-dynamic-require:0 */ return require(pAbsoluteWebpackConfigFileName); } } catch (pError) { throw new Error( `The webpack config '${pAbsoluteWebpackConfigFileName}' seems to be not quite valid for use:` + `\n\n "${pError}"\n` ); } } /** * Reads the file with name `pWebpackConfigFilename` and (applying the * environment `pEnvironment` and the arguments `pArguments` (which can * either be a string or a keys-values object)) returns the resolve config * from it as an object. * * @param {string} pWebpackConfigFilename * @param {string=} pEnvironment * @param {string|any=} pArguments * @return {any} webpack resolve config as an object * @throws {Error} when the webpack config isn't usable (e.g. because it * doesn't exist, or because it's invalid) */ export default async function extractWebpackResolveConfig( pWebpackConfigFilename, pEnvironment, pArguments ) { let lReturnValue = {}; const lAbsoluteConfigFilename = makeAbsolute(pWebpackConfigFilename); const lWebpackConfig = pryConfigFromTheConfig( await attemptImport(lAbsoluteConfigFilename), pEnvironment, pArguments ); if (lWebpackConfig.resolve) { lReturnValue = lWebpackConfig.resolve; } return lReturnValue; }