webpack 5.101.3 → 5.102.1

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.
Files changed (339) hide show
  1. package/README.md +21 -26
  2. package/lib/APIPlugin.js +30 -36
  3. package/lib/AsyncDependenciesBlock.js +1 -4
  4. package/lib/BannerPlugin.js +0 -1
  5. package/lib/Cache.js +7 -6
  6. package/lib/CacheFacade.js +0 -1
  7. package/lib/Chunk.js +49 -31
  8. package/lib/ChunkGraph.js +37 -27
  9. package/lib/ChunkGroup.js +8 -10
  10. package/lib/ChunkTemplate.js +1 -1
  11. package/lib/CleanPlugin.js +3 -3
  12. package/lib/CodeGenerationResults.js +3 -2
  13. package/lib/CompatibilityPlugin.js +29 -12
  14. package/lib/Compilation.js +209 -196
  15. package/lib/Compiler.js +36 -35
  16. package/lib/ConcatenationScope.js +6 -1
  17. package/lib/ConditionalInitFragment.js +1 -1
  18. package/lib/ConstPlugin.js +6 -5
  19. package/lib/ContextExclusionPlugin.js +0 -1
  20. package/lib/ContextModule.js +25 -21
  21. package/lib/ContextModuleFactory.js +30 -11
  22. package/lib/ContextReplacementPlugin.js +38 -15
  23. package/lib/DefinePlugin.js +5 -9
  24. package/lib/DelegatedModule.js +7 -11
  25. package/lib/DependenciesBlock.js +0 -2
  26. package/lib/Dependency.js +9 -11
  27. package/lib/DependencyTemplates.js +2 -4
  28. package/lib/DllModule.js +1 -7
  29. package/lib/DllReferencePlugin.js +2 -4
  30. package/lib/DynamicEntryPlugin.js +0 -2
  31. package/lib/EntryOptionPlugin.js +0 -5
  32. package/lib/EnvironmentNotSupportAsyncWarning.js +0 -3
  33. package/lib/EvalDevToolModulePlugin.js +4 -3
  34. package/lib/EvalSourceMapDevToolPlugin.js +3 -4
  35. package/lib/ExportsInfo.js +50 -49
  36. package/lib/ExternalModule.js +84 -52
  37. package/lib/ExternalModuleFactoryPlugin.js +27 -7
  38. package/lib/ExternalsPlugin.js +24 -17
  39. package/lib/FileSystemInfo.js +105 -90
  40. package/lib/FlagDependencyUsagePlugin.js +3 -4
  41. package/lib/Generator.js +2 -13
  42. package/lib/GraphHelpers.js +0 -3
  43. package/lib/HookWebpackError.js +0 -2
  44. package/lib/HotModuleReplacementPlugin.js +22 -24
  45. package/lib/HotUpdateChunk.js +0 -3
  46. package/lib/IgnorePlugin.js +5 -2
  47. package/lib/InitFragment.js +41 -29
  48. package/lib/InvalidDependenciesModuleWarning.js +0 -1
  49. package/lib/LibManifestPlugin.js +4 -6
  50. package/lib/LoaderOptionsPlugin.js +1 -10
  51. package/lib/MainTemplate.js +8 -19
  52. package/lib/Module.js +32 -20
  53. package/lib/ModuleFactory.js +1 -1
  54. package/lib/ModuleFilenameHelpers.js +42 -25
  55. package/lib/ModuleGraph.js +30 -16
  56. package/lib/ModuleInfoHeaderPlugin.js +0 -1
  57. package/lib/ModuleTemplate.js +0 -2
  58. package/lib/ModuleTypeConstants.js +11 -1
  59. package/lib/MultiCompiler.js +23 -15
  60. package/lib/MultiWatching.js +6 -10
  61. package/lib/NodeStuffPlugin.js +2 -10
  62. package/lib/NormalModule.js +146 -89
  63. package/lib/NormalModuleFactory.js +132 -42
  64. package/lib/OptionsApply.js +1 -1
  65. package/lib/Parser.js +1 -1
  66. package/lib/ProgressPlugin.js +6 -10
  67. package/lib/ProvidePlugin.js +5 -7
  68. package/lib/RawModule.js +1 -6
  69. package/lib/RecordIdsPlugin.js +10 -6
  70. package/lib/ResolverFactory.js +0 -2
  71. package/lib/RuntimeGlobals.js +5 -0
  72. package/lib/RuntimeModule.js +1 -3
  73. package/lib/RuntimePlugin.js +26 -22
  74. package/lib/RuntimeTemplate.js +22 -12
  75. package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -2
  76. package/lib/SourceMapDevToolPlugin.js +11 -18
  77. package/lib/Stats.js +0 -1
  78. package/lib/Template.js +6 -11
  79. package/lib/TemplatedPathPlugin.js +2 -1
  80. package/lib/WatchIgnorePlugin.js +2 -3
  81. package/lib/Watching.js +15 -15
  82. package/lib/WebpackIsIncludedPlugin.js +0 -2
  83. package/lib/WebpackOptionsApply.js +74 -107
  84. package/lib/asset/AssetBytesGenerator.js +167 -0
  85. package/lib/asset/AssetBytesParser.js +37 -0
  86. package/lib/asset/AssetGenerator.js +22 -37
  87. package/lib/asset/AssetModulesPlugin.js +34 -16
  88. package/lib/asset/AssetParser.js +7 -3
  89. package/lib/asset/AssetSourceGenerator.js +1 -1
  90. package/lib/asset/RawDataUrlModule.js +3 -2
  91. package/lib/async-modules/AsyncModuleHelpers.js +6 -4
  92. package/lib/buildChunkGraph.js +0 -1
  93. package/lib/cache/MemoryCachePlugin.js +0 -2
  94. package/lib/cache/MemoryWithGcCachePlugin.js +0 -2
  95. package/lib/cache/PackFileCacheStrategy.js +14 -1
  96. package/lib/cache/ResolverCachePlugin.js +9 -15
  97. package/lib/cache/getLazyHashedEtag.js +1 -1
  98. package/lib/config/browserslistTargetHandler.js +77 -76
  99. package/lib/config/defaults.js +162 -23
  100. package/lib/config/normalization.js +18 -3
  101. package/lib/config/target.js +1 -1
  102. package/lib/container/ContainerEntryDependency.js +0 -1
  103. package/lib/container/ContainerEntryModule.js +3 -7
  104. package/lib/container/ContainerPlugin.js +1 -2
  105. package/lib/container/ContainerReferencePlugin.js +0 -1
  106. package/lib/container/FallbackDependency.js +2 -1
  107. package/lib/container/FallbackModule.js +6 -7
  108. package/lib/container/ModuleFederationPlugin.js +0 -1
  109. package/lib/container/RemoteModule.js +8 -8
  110. package/lib/container/RemoteRuntimeModule.js +2 -2
  111. package/lib/css/CssGenerator.js +3 -6
  112. package/lib/css/CssLoadingRuntimeModule.js +6 -9
  113. package/lib/css/CssModulesPlugin.js +13 -19
  114. package/lib/css/CssParser.js +3 -3
  115. package/lib/css/walkCssTokens.js +2 -2
  116. package/lib/debug/ProfilingPlugin.js +35 -8
  117. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +12 -17
  118. package/lib/dependencies/AMDPlugin.js +2 -2
  119. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -2
  120. package/lib/dependencies/CachedConstDependency.js +0 -4
  121. package/lib/dependencies/CommonJsExportRequireDependency.js +20 -14
  122. package/lib/dependencies/CommonJsExportsDependency.js +2 -1
  123. package/lib/dependencies/CommonJsExportsParserPlugin.js +20 -5
  124. package/lib/dependencies/CommonJsFullRequireDependency.js +6 -4
  125. package/lib/dependencies/CommonJsImportsParserPlugin.js +16 -7
  126. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  127. package/lib/dependencies/CommonJsSelfReferenceDependency.js +4 -4
  128. package/lib/dependencies/ConstDependency.js +2 -2
  129. package/lib/dependencies/ContextDependency.js +9 -4
  130. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  131. package/lib/dependencies/ContextDependencyTemplateAsId.js +9 -9
  132. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +9 -9
  133. package/lib/dependencies/ContextElementDependency.js +22 -11
  134. package/lib/dependencies/CssIcssImportDependency.js +0 -2
  135. package/lib/dependencies/CssIcssSymbolDependency.js +2 -2
  136. package/lib/dependencies/CssImportDependency.js +0 -8
  137. package/lib/dependencies/CssLocalIdentifierDependency.js +4 -7
  138. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +2 -2
  139. package/lib/dependencies/CssUrlDependency.js +0 -6
  140. package/lib/dependencies/ExportsInfoDependency.js +7 -9
  141. package/lib/dependencies/ExternalModuleDependency.js +0 -3
  142. package/lib/dependencies/ExternalModuleInitFragment.js +1 -1
  143. package/lib/dependencies/HarmonyAcceptDependency.js +1 -1
  144. package/lib/dependencies/HarmonyAcceptImportDependency.js +0 -4
  145. package/lib/dependencies/HarmonyCompatibilityDependency.js +0 -1
  146. package/lib/dependencies/HarmonyDetectionParserPlugin.js +0 -14
  147. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +3 -3
  148. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +4 -1
  149. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +29 -35
  150. package/lib/dependencies/HarmonyImportDependency.js +33 -14
  151. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +20 -23
  152. package/lib/dependencies/HarmonyImportSideEffectDependency.js +0 -4
  153. package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -31
  154. package/lib/dependencies/HarmonyModulesPlugin.js +3 -3
  155. package/lib/dependencies/ImportContextDependency.js +13 -0
  156. package/lib/dependencies/ImportDependency.js +18 -6
  157. package/lib/dependencies/ImportEagerDependency.js +2 -3
  158. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +8 -5
  159. package/lib/dependencies/ImportMetaContextPlugin.js +0 -1
  160. package/lib/dependencies/ImportMetaPlugin.js +3 -2
  161. package/lib/dependencies/ImportParserPlugin.js +288 -45
  162. package/lib/dependencies/ImportWeakDependency.js +2 -3
  163. package/lib/dependencies/JsonExportsDependency.js +0 -1
  164. package/lib/dependencies/LoaderDependency.js +0 -3
  165. package/lib/dependencies/LoaderImportDependency.js +0 -3
  166. package/lib/dependencies/LoaderPlugin.js +11 -5
  167. package/lib/dependencies/ModuleDecoratorDependency.js +2 -4
  168. package/lib/dependencies/ModuleDependency.js +3 -9
  169. package/lib/dependencies/NullDependency.js +2 -0
  170. package/lib/dependencies/ProvidedDependency.js +6 -8
  171. package/lib/dependencies/PureExpressionDependency.js +0 -1
  172. package/lib/dependencies/RequireEnsureDependenciesBlock.js +0 -1
  173. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +1 -2
  174. package/lib/dependencies/RequireIncludeDependency.js +2 -2
  175. package/lib/dependencies/RequireResolveDependency.js +2 -2
  176. package/lib/dependencies/RuntimeRequirementsDependency.js +2 -3
  177. package/lib/dependencies/StaticExportsDependency.js +3 -5
  178. package/lib/dependencies/URLDependency.js +2 -7
  179. package/lib/dependencies/URLPlugin.js +1 -2
  180. package/lib/dependencies/WebAssemblyExportImportedDependency.js +2 -2
  181. package/lib/dependencies/WebAssemblyImportDependency.js +2 -2
  182. package/lib/dependencies/WebpackIsIncludedDependency.js +2 -3
  183. package/lib/dependencies/WorkerDependency.js +2 -3
  184. package/lib/dependencies/WorkerPlugin.js +4 -12
  185. package/lib/dependencies/processExportInfo.js +2 -3
  186. package/lib/esm/ModuleChunkFormatPlugin.js +0 -3
  187. package/lib/esm/ModuleChunkLoadingPlugin.js +2 -1
  188. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +7 -7
  189. package/lib/hmr/LazyCompilationPlugin.js +6 -4
  190. package/lib/hmr/lazyCompilationBackend.js +13 -10
  191. package/lib/ids/DeterministicChunkIdsPlugin.js +0 -1
  192. package/lib/ids/HashedModuleIdsPlugin.js +5 -7
  193. package/lib/ids/IdHelpers.js +1 -1
  194. package/lib/ids/NamedChunkIdsPlugin.js +1 -6
  195. package/lib/ids/NamedModuleIdsPlugin.js +1 -5
  196. package/lib/ids/NaturalChunkIdsPlugin.js +0 -1
  197. package/lib/ids/NaturalModuleIdsPlugin.js +0 -1
  198. package/lib/ids/OccurrenceChunkIdsPlugin.js +0 -1
  199. package/lib/ids/OccurrenceModuleIdsPlugin.js +0 -1
  200. package/lib/ids/SyncModuleIdsPlugin.js +4 -3
  201. package/lib/index.js +8 -7
  202. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -1
  203. package/lib/javascript/BasicEvaluatedExpression.js +13 -6
  204. package/lib/javascript/ChunkFormatHelpers.js +1 -1
  205. package/lib/javascript/CommonJsChunkFormatPlugin.js +0 -1
  206. package/lib/javascript/JavascriptGenerator.js +2 -3
  207. package/lib/javascript/JavascriptModulesPlugin.js +46 -24
  208. package/lib/javascript/JavascriptParser.js +120 -55
  209. package/lib/javascript/JavascriptParserHelpers.js +2 -2
  210. package/lib/javascript/StartupHelpers.js +2 -4
  211. package/lib/json/JsonData.js +1 -1
  212. package/lib/json/JsonGenerator.js +4 -5
  213. package/lib/json/JsonModulesPlugin.js +0 -3
  214. package/lib/json/JsonParser.js +4 -2
  215. package/lib/library/AbstractLibraryPlugin.js +2 -2
  216. package/lib/library/AmdLibraryPlugin.js +0 -1
  217. package/lib/library/AssignLibraryPlugin.js +23 -12
  218. package/lib/library/EnableLibraryPlugin.js +7 -11
  219. package/lib/library/ExportPropertyLibraryPlugin.js +8 -20
  220. package/lib/library/JsonpLibraryPlugin.js +5 -2
  221. package/lib/library/ModuleLibraryPlugin.js +88 -43
  222. package/lib/library/SystemLibraryPlugin.js +15 -6
  223. package/lib/library/UmdLibraryPlugin.js +12 -18
  224. package/lib/logging/Logger.js +12 -10
  225. package/lib/logging/createConsoleLogger.js +15 -14
  226. package/lib/logging/truncateArgs.js +1 -1
  227. package/lib/node/CommonJsChunkLoadingPlugin.js +2 -1
  228. package/lib/node/NodeWatchFileSystem.js +4 -4
  229. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -2
  230. package/lib/node/RequireChunkLoadingRuntimeModule.js +5 -2
  231. package/lib/node/nodeConsole.js +2 -2
  232. package/lib/optimize/AggressiveSplittingPlugin.js +2 -0
  233. package/lib/optimize/ConcatenatedModule.js +142 -100
  234. package/lib/optimize/InnerGraph.js +17 -11
  235. package/lib/optimize/InnerGraphPlugin.js +0 -3
  236. package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
  237. package/lib/optimize/RealContentHashPlugin.js +5 -3
  238. package/lib/optimize/RuntimeChunkPlugin.js +0 -1
  239. package/lib/optimize/SideEffectsFlagPlugin.js +3 -10
  240. package/lib/optimize/SplitChunksPlugin.js +46 -40
  241. package/lib/performance/SizeLimitsPlugin.js +2 -1
  242. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +5 -7
  243. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +0 -2
  244. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +0 -1
  245. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +2 -2
  246. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +2 -2
  247. package/lib/rules/BasicMatcherRulePlugin.js +0 -2
  248. package/lib/rules/ObjectMatcherRulePlugin.js +0 -1
  249. package/lib/rules/RuleSetCompiler.js +8 -6
  250. package/lib/runtime/BaseUriRuntimeModule.js +2 -2
  251. package/lib/runtime/CompatRuntimeModule.js +0 -1
  252. package/lib/runtime/GetChunkFilenameRuntimeModule.js +8 -9
  253. package/lib/runtime/LoadScriptRuntimeModule.js +0 -2
  254. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +1 -1
  255. package/lib/runtime/PublicPathRuntimeModule.js +2 -2
  256. package/lib/runtime/StartupEntrypointRuntimeModule.js +0 -1
  257. package/lib/runtime/SystemContextRuntimeModule.js +0 -2
  258. package/lib/runtime/ToBinaryRuntimeModule.js +64 -0
  259. package/lib/schemes/DataUriPlugin.js +2 -28
  260. package/lib/schemes/FileUriPlugin.js +5 -2
  261. package/lib/schemes/HttpUriPlugin.js +4 -2
  262. package/lib/schemes/VirtualUrlPlugin.js +11 -11
  263. package/lib/serialization/FileMiddleware.js +1 -1
  264. package/lib/serialization/NullPrototypeObjectSerializer.js +5 -3
  265. package/lib/serialization/ObjectMiddleware.js +31 -20
  266. package/lib/serialization/SerializerMiddleware.js +1 -3
  267. package/lib/serialization/types.js +1 -1
  268. package/lib/sharing/ConsumeSharedModule.js +3 -5
  269. package/lib/sharing/ConsumeSharedPlugin.js +2 -4
  270. package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -6
  271. package/lib/sharing/ProvideSharedModule.js +3 -7
  272. package/lib/sharing/SharePlugin.js +0 -2
  273. package/lib/sharing/ShareRuntimeModule.js +4 -1
  274. package/lib/sharing/resolveMatchedConfigs.js +14 -6
  275. package/lib/sharing/utils.js +0 -6
  276. package/lib/stats/DefaultStatsFactoryPlugin.js +179 -95
  277. package/lib/stats/DefaultStatsPresetPlugin.js +15 -9
  278. package/lib/stats/DefaultStatsPrinterPlugin.js +77 -113
  279. package/lib/stats/StatsFactory.js +14 -11
  280. package/lib/url/URLParserPlugin.js +2 -4
  281. package/lib/util/ArrayHelpers.js +4 -4
  282. package/lib/util/AsyncQueue.js +1 -0
  283. package/lib/util/Hash.js +35 -5
  284. package/lib/util/LazySet.js +2 -2
  285. package/lib/util/StackedCacheMap.js +0 -2
  286. package/lib/util/TupleSet.js +9 -4
  287. package/lib/util/URLAbsoluteSpecifier.js +0 -1
  288. package/lib/util/WeakTupleMap.js +1 -1
  289. package/lib/util/chainedImports.js +3 -1
  290. package/lib/util/cleverMerge.js +15 -18
  291. package/lib/util/comparators.js +2 -4
  292. package/lib/util/compileBooleanMatcher.js +11 -9
  293. package/lib/util/concatenate.js +1 -2
  294. package/lib/util/create-schema-validation.js +1 -2
  295. package/lib/util/createHash.js +85 -15
  296. package/lib/util/dataURL.js +39 -0
  297. package/lib/util/deprecation.js +29 -31
  298. package/lib/util/deterministicGrouping.js +34 -30
  299. package/lib/util/extractSourceMap.js +319 -0
  300. package/lib/util/findGraphRoots.js +15 -5
  301. package/lib/util/fs.js +29 -8
  302. package/lib/util/hash/BatchedHash.js +47 -8
  303. package/lib/util/hash/wasm-hash.js +53 -13
  304. package/lib/util/semver.js +9 -8
  305. package/lib/util/smartGrouping.js +41 -26
  306. package/lib/util/traverseDestructuringAssignmentProperties.js +45 -0
  307. package/lib/wasm/EnableWasmLoadingPlugin.js +3 -2
  308. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +5 -1
  309. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +2 -13
  310. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +2 -9
  311. package/lib/wasm-async/AsyncWebAssemblyParser.js +2 -10
  312. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +6 -4
  313. package/lib/wasm-sync/WebAssemblyGenerator.js +1 -3
  314. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +1 -4
  315. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +2 -7
  316. package/lib/wasm-sync/WebAssemblyParser.js +1 -13
  317. package/lib/web/JsonpChunkLoadingPlugin.js +2 -1
  318. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -1
  319. package/lib/web/JsonpTemplatePlugin.js +0 -1
  320. package/lib/webpack.js +21 -8
  321. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +2 -1
  322. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  323. package/package.json +21 -21
  324. package/schemas/WebpackOptions.check.js +1 -1
  325. package/schemas/WebpackOptions.json +93 -96
  326. package/schemas/plugins/BannerPlugin.check.js +1 -1
  327. package/schemas/plugins/BannerPlugin.json +4 -0
  328. package/schemas/plugins/IgnorePlugin.json +1 -1
  329. package/schemas/plugins/ProgressPlugin.json +1 -1
  330. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  331. package/schemas/plugins/SourceMapDevToolPlugin.json +5 -1
  332. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.d.ts +7 -0
  333. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +6 -0
  334. package/schemas/plugins/{HashedModuleIdsPlugin.json → ids/HashedModuleIdsPlugin.json} +15 -2
  335. package/schemas/plugins/schemes/VirtualUrlPlugin.json +3 -3
  336. package/types.d.ts +1699 -706
  337. package/SECURITY.md +0 -9
  338. package/schemas/plugins/HashedModuleIdsPlugin.check.d.ts +0 -7
  339. package/schemas/plugins/HashedModuleIdsPlugin.check.js +0 -6
@@ -70,9 +70,11 @@ const getName = (a, b, usedNames) => {
70
70
  return a;
71
71
  };
72
72
 
73
+ /** @typedef {Record<string, number>} Sizes */
74
+
73
75
  /**
74
- * @param {Record<string, number>} total total size
75
- * @param {Record<string, number>} size single size
76
+ * @param {Sizes} total total size
77
+ * @param {Sizes} size single size
76
78
  * @returns {void}
77
79
  */
78
80
  const addSizeTo = (total, size) => {
@@ -82,8 +84,8 @@ const addSizeTo = (total, size) => {
82
84
  };
83
85
 
84
86
  /**
85
- * @param {Record<string, number>} total total size
86
- * @param {Record<string, number>} size single size
87
+ * @param {Sizes} total total size
88
+ * @param {Sizes} size single size
87
89
  * @returns {void}
88
90
  */
89
91
  const subtractSizeFrom = (total, size) => {
@@ -95,7 +97,7 @@ const subtractSizeFrom = (total, size) => {
95
97
  /**
96
98
  * @template T
97
99
  * @param {Iterable<Node<T>>} nodes some nodes
98
- * @returns {Record<string, number>} total size
100
+ * @returns {Sizes} total size
99
101
  */
100
102
  const sumSize = (nodes) => {
101
103
  const sum = Object.create(null);
@@ -106,8 +108,8 @@ const sumSize = (nodes) => {
106
108
  };
107
109
 
108
110
  /**
109
- * @param {Record<string, number>} size size
110
- * @param {Record<string, number>} maxSize minimum size
111
+ * @param {Sizes} size size
112
+ * @param {Sizes} maxSize minimum size
111
113
  * @returns {boolean} true, when size is too big
112
114
  */
113
115
  const isTooBig = (size, maxSize) => {
@@ -121,8 +123,8 @@ const isTooBig = (size, maxSize) => {
121
123
  };
122
124
 
123
125
  /**
124
- * @param {Record<string, number>} size size
125
- * @param {Record<string, number>} minSize minimum size
126
+ * @param {Sizes} size size
127
+ * @param {Sizes} minSize minimum size
126
128
  * @returns {boolean} true, when size is too small
127
129
  */
128
130
  const isTooSmall = (size, minSize) => {
@@ -136,8 +138,8 @@ const isTooSmall = (size, minSize) => {
136
138
  };
137
139
 
138
140
  /**
139
- * @param {Record<string, number>} size size
140
- * @param {Record<string, number>} minSize minimum size
141
+ * @param {Sizes} size size
142
+ * @param {Sizes} minSize minimum size
141
143
  * @returns {Set<string>} set of types that are too small
142
144
  */
143
145
  const getTooSmallTypes = (size, minSize) => {
@@ -166,7 +168,7 @@ const getNumberOfMatchingSizeTypes = (size, types) => {
166
168
  };
167
169
 
168
170
  /**
169
- * @param {Record<string, number>} size size
171
+ * @param {Sizes} size size
170
172
  * @param {Set<string>} types types
171
173
  * @returns {number} selective size sum
172
174
  */
@@ -185,7 +187,7 @@ class Node {
185
187
  /**
186
188
  * @param {T} item item
187
189
  * @param {string} key key
188
- * @param {Record<string, number>} size size
190
+ * @param {Sizes} size size
189
191
  */
190
192
  constructor(item, key, size) {
191
193
  this.item = item;
@@ -194,14 +196,16 @@ class Node {
194
196
  }
195
197
  }
196
198
 
199
+ /** @typedef {number[]} Similarities */
200
+
197
201
  /**
198
202
  * @template T
199
203
  */
200
204
  class Group {
201
205
  /**
202
206
  * @param {Node<T>[]} nodes nodes
203
- * @param {number[] | null} similarities similarities between the nodes (length = nodes.length - 1)
204
- * @param {Record<string, number>=} size size of the group
207
+ * @param {Similarities | null} similarities similarities between the nodes (length = nodes.length - 1)
208
+ * @param {Sizes=} size size of the group
205
209
  */
206
210
  constructor(nodes, similarities, size) {
207
211
  this.nodes = nodes;
@@ -228,7 +232,7 @@ class Group {
228
232
  if (newNodes.length > 0) {
229
233
  newSimilarities.push(
230
234
  lastNode === this.nodes[i - 1]
231
- ? /** @type {number[]} */ (this.similarities)[i - 1]
235
+ ? /** @type {Similarities} */ (this.similarities)[i - 1]
232
236
  : similarity(/** @type {Node<T>} */ (lastNode).key, node.key)
233
237
  );
234
238
  }
@@ -247,11 +251,11 @@ class Group {
247
251
  /**
248
252
  * @template T
249
253
  * @param {Iterable<Node<T>>} nodes nodes
250
- * @returns {number[]} similarities
254
+ * @returns {Similarities} similarities
251
255
  */
252
256
  const getSimilarities = (nodes) => {
253
257
  // calculate similarities between lexically adjacent nodes
254
- /** @type {number[]} */
258
+ /** @type {Similarities} */
255
259
  const similarities = [];
256
260
  let last;
257
261
  for (const node of nodes) {
@@ -268,16 +272,16 @@ const getSimilarities = (nodes) => {
268
272
  * @typedef {object} GroupedItems<T>
269
273
  * @property {string} key
270
274
  * @property {T[]} items
271
- * @property {Record<string, number>} size
275
+ * @property {Sizes} size
272
276
  */
273
277
 
274
278
  /**
275
279
  * @template T
276
280
  * @typedef {object} Options
277
- * @property {Record<string, number>} maxSize maximum size of a group
278
- * @property {Record<string, number>} minSize minimum size of a group (preferred over maximum size)
281
+ * @property {Sizes} maxSize maximum size of a group
282
+ * @property {Sizes} minSize minimum size of a group (preferred over maximum size)
279
283
  * @property {Iterable<T>} items a list of items
280
- * @property {(item: T) => Record<string, number>} getSize function to get size of an item
284
+ * @property {(item: T) => Sizes} getSize function to get size of an item
281
285
  * @property {(item: T) => string} getKey function to get the key of an item
282
286
  */
283
287
 
@@ -320,7 +324,7 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => {
320
324
 
321
325
  /**
322
326
  * @param {Group<T>} group group
323
- * @param {Record<string, number>} consideredSize size of the group to consider
327
+ * @param {Sizes} consideredSize size of the group to consider
324
328
  * @returns {boolean} true, if the group was modified
325
329
  */
326
330
  const removeProblematicNodes = (group, consideredSize = group.size) => {
@@ -455,9 +459,9 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => {
455
459
  // rightSize ^^^^^^^^^^^^^^^
456
460
 
457
461
  while (pos <= right + 1) {
458
- const similarity = /** @type {number[]} */ (group.similarities)[
459
- pos - 1
460
- ];
462
+ const similarity =
463
+ /** @type {Similarities} */
464
+ (group.similarities)[pos - 1];
461
465
  if (
462
466
  similarity < bestSimilarity &&
463
467
  !isTooSmall(leftSize, minSize) &&
@@ -484,22 +488,22 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => {
484
488
  // create two new groups for left and right area
485
489
  // and queue them up
486
490
  const rightNodes = [group.nodes[right + 1]];
487
- /** @type {number[]} */
491
+ /** @type {Similarities} */
488
492
  const rightSimilarities = [];
489
493
  for (let i = right + 2; i < group.nodes.length; i++) {
490
494
  rightSimilarities.push(
491
- /** @type {number[]} */ (group.similarities)[i - 1]
495
+ /** @type {Similarities} */ (group.similarities)[i - 1]
492
496
  );
493
497
  rightNodes.push(group.nodes[i]);
494
498
  }
495
499
  queue.push(new Group(rightNodes, rightSimilarities));
496
500
 
497
501
  const leftNodes = [group.nodes[0]];
498
- /** @type {number[]} */
502
+ /** @type {Similarities} */
499
503
  const leftSimilarities = [];
500
504
  for (let i = 1; i < left; i++) {
501
505
  leftSimilarities.push(
502
- /** @type {number[]} */ (group.similarities)[i - 1]
506
+ /** @type {Similarities} */ (group.similarities)[i - 1]
503
507
  );
504
508
  leftNodes.push(group.nodes[i]);
505
509
  }
@@ -0,0 +1,319 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Natsu @xiaoxiaojx
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const path = require("path");
9
+ const urlUtils = require("url");
10
+ const { isAbsolute, join } = require("./fs");
11
+
12
+ /** @typedef {import("./fs").InputFileSystem} InputFileSystem */
13
+
14
+ /**
15
+ * @typedef {(input: string | Buffer<ArrayBufferLike>, resourcePath: string, fs: InputFileSystem) => Promise<{source: string | Buffer<ArrayBufferLike>, sourceMap: string | RawSourceMap | undefined, fileDependencies: string[]}>} SourceMapExtractorFunction
16
+ */
17
+
18
+ /** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
19
+
20
+ /**
21
+ * @typedef {(resourcePath: string) => Promise<string | Buffer<ArrayBufferLike>>} ReadResource
22
+ */
23
+
24
+ /**
25
+ * @typedef {object} SourceMappingURL
26
+ * @property {string} sourceMappingURL
27
+ * @property {string} replacementString
28
+ */
29
+
30
+ // Matches only the last occurrence of sourceMappingURL
31
+ const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*([^\s'"]*)\s*/;
32
+
33
+ const validProtocolPattern = /^[a-z][a-z0-9+.-]*:/i;
34
+
35
+ const sourceMappingURLRegex = new RegExp(
36
+ "(?:" +
37
+ "/\\*" +
38
+ "(?:\\s*\r?\n(?://)?)?" +
39
+ `(?:${innerRegex.source})` +
40
+ "\\s*" +
41
+ "\\*/" +
42
+ "|" +
43
+ `//(?:${innerRegex.source})` +
44
+ ")" +
45
+ "\\s*"
46
+ );
47
+
48
+ /**
49
+ * Extract source mapping URL from code comments
50
+ * @param {string} code source code content
51
+ * @returns {SourceMappingURL} source mapping information
52
+ */
53
+ function getSourceMappingURL(code) {
54
+ const lines = code.split(/^/m);
55
+ let match;
56
+
57
+ for (let i = lines.length - 1; i >= 0; i--) {
58
+ match = lines[i].match(sourceMappingURLRegex);
59
+ if (match) {
60
+ break;
61
+ }
62
+ }
63
+
64
+ const sourceMappingURL = match ? match[1] || match[2] || "" : "";
65
+
66
+ return {
67
+ sourceMappingURL: sourceMappingURL
68
+ ? decodeURI(sourceMappingURL)
69
+ : sourceMappingURL,
70
+ replacementString: match ? match[0] : ""
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Get absolute path for source file
76
+ * @param {string} context context directory
77
+ * @param {string} request file request
78
+ * @param {string} sourceRoot source root directory
79
+ * @returns {string} absolute path
80
+ */
81
+ function getAbsolutePath(context, request, sourceRoot) {
82
+ if (sourceRoot) {
83
+ if (isAbsolute(sourceRoot)) {
84
+ return join(undefined, sourceRoot, request);
85
+ }
86
+
87
+ return join(undefined, join(undefined, context, sourceRoot), request);
88
+ }
89
+
90
+ return join(undefined, context, request);
91
+ }
92
+
93
+ /**
94
+ * Check if value is a URL
95
+ * @param {string} value string to check
96
+ * @returns {boolean} true if value is a URL
97
+ */
98
+ function isURL(value) {
99
+ return validProtocolPattern.test(value) && !path.win32.isAbsolute(value);
100
+ }
101
+
102
+ /**
103
+ * Fetch from multiple possible file paths
104
+ * @param {ReadResource} readResource read resource function
105
+ * @param {string[]} possibleRequests array of possible file paths
106
+ * @param {string} errorsAccumulator accumulated error messages
107
+ * @returns {Promise<{path: string, data?: string}>} source content promise
108
+ */
109
+ async function fetchPathsFromURL(
110
+ readResource,
111
+ possibleRequests,
112
+ errorsAccumulator = ""
113
+ ) {
114
+ let result;
115
+
116
+ try {
117
+ result = await readResource(possibleRequests[0]);
118
+ } catch (error) {
119
+ errorsAccumulator += `${/** @type {Error} */ (error).message}\n\n`;
120
+
121
+ const [, ...tailPossibleRequests] = possibleRequests;
122
+
123
+ if (tailPossibleRequests.length === 0) {
124
+ /** @type {Error} */ (error).message = errorsAccumulator;
125
+
126
+ throw error;
127
+ }
128
+
129
+ return fetchPathsFromURL(
130
+ readResource,
131
+ tailPossibleRequests,
132
+ errorsAccumulator
133
+ );
134
+ }
135
+
136
+ return {
137
+ path: possibleRequests[0],
138
+ data: result.toString("utf8")
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Fetch source content from URL
144
+ * @param {ReadResource} readResource The read resource function
145
+ * @param {string} context context directory
146
+ * @param {string} url source URL
147
+ * @param {string=} sourceRoot source root directory
148
+ * @param {boolean=} skipReading whether to skip reading file content
149
+ * @returns {Promise<{sourceURL: string, sourceContent?: string | Buffer<ArrayBufferLike>}>} source content promise
150
+ */
151
+ async function fetchFromURL(
152
+ readResource,
153
+ context,
154
+ url,
155
+ sourceRoot,
156
+ skipReading = false
157
+ ) {
158
+ // 1. It's an absolute url and it is not `windows` path like `C:\dir\file`
159
+ if (isURL(url)) {
160
+ // eslint-disable-next-line n/no-deprecated-api
161
+ const { protocol } = urlUtils.parse(url);
162
+ if (protocol === "data:") {
163
+ const sourceContent = skipReading ? "" : await readResource(url);
164
+
165
+ return { sourceURL: "", sourceContent };
166
+ }
167
+
168
+ if (protocol === "file:") {
169
+ const pathFromURL = urlUtils.fileURLToPath(url);
170
+ const sourceURL = path.normalize(pathFromURL);
171
+ const sourceContent = skipReading ? "" : await readResource(sourceURL);
172
+
173
+ return { sourceURL, sourceContent };
174
+ }
175
+
176
+ const sourceContent = skipReading ? "" : await readResource(url);
177
+ return { sourceURL: url, sourceContent };
178
+ }
179
+
180
+ // 3. Absolute path
181
+ if (isAbsolute(url)) {
182
+ let sourceURL = path.normalize(url);
183
+
184
+ let sourceContent;
185
+
186
+ if (!skipReading) {
187
+ const possibleRequests = [sourceURL];
188
+
189
+ if (url.startsWith("/")) {
190
+ possibleRequests.push(
191
+ getAbsolutePath(context, sourceURL.slice(1), sourceRoot || "")
192
+ );
193
+ }
194
+
195
+ const result = await fetchPathsFromURL(readResource, possibleRequests);
196
+
197
+ sourceURL = result.path;
198
+ sourceContent = result.data;
199
+ }
200
+
201
+ return { sourceURL, sourceContent };
202
+ }
203
+
204
+ // 4. Relative path
205
+ const sourceURL = getAbsolutePath(context, url, sourceRoot || "");
206
+ let sourceContent;
207
+
208
+ if (!skipReading) {
209
+ sourceContent = await readResource(sourceURL);
210
+ }
211
+
212
+ return { sourceURL, sourceContent };
213
+ }
214
+
215
+ /**
216
+ * Extract source map from code content
217
+ * @param {string | Buffer<ArrayBufferLike>} stringOrBuffer The input code content as string or buffer
218
+ * @param {string} resourcePath The path to the resource file
219
+ * @param {ReadResource} readResource The read resource function
220
+ * @returns {Promise<{source: string | Buffer<ArrayBufferLike>, sourceMap: string | RawSourceMap | undefined}>} Promise resolving to extracted source map information
221
+ */
222
+ async function extractSourceMap(stringOrBuffer, resourcePath, readResource) {
223
+ const input =
224
+ typeof stringOrBuffer === "string"
225
+ ? stringOrBuffer
226
+ : stringOrBuffer.toString("utf8");
227
+ const inputSourceMap = undefined;
228
+ const output = {
229
+ source: stringOrBuffer,
230
+ sourceMap: inputSourceMap
231
+ };
232
+ const { sourceMappingURL, replacementString } = getSourceMappingURL(input);
233
+
234
+ if (!sourceMappingURL) {
235
+ return output;
236
+ }
237
+
238
+ const baseContext = path.dirname(resourcePath);
239
+
240
+ const { sourceURL, sourceContent } = await fetchFromURL(
241
+ readResource,
242
+ baseContext,
243
+ sourceMappingURL
244
+ );
245
+
246
+ if (!sourceContent) {
247
+ return output;
248
+ }
249
+
250
+ /** @type {RawSourceMap} */
251
+ const map = JSON.parse(
252
+ sourceContent.toString("utf8").replace(/^\)\]\}'/, "")
253
+ );
254
+
255
+ const context = sourceURL ? path.dirname(sourceURL) : baseContext;
256
+
257
+ const resolvedSources = await Promise.all(
258
+ map.sources.map(
259
+ async (/** @type {string} */ source, /** @type {number} */ i) => {
260
+ const originalSourceContent =
261
+ map.sourcesContent &&
262
+ typeof map.sourcesContent[i] !== "undefined" &&
263
+ map.sourcesContent[i] !== null
264
+ ? map.sourcesContent[i]
265
+ : undefined;
266
+ const skipReading = typeof originalSourceContent !== "undefined";
267
+ // We do not skipReading here, because we need absolute paths in sources.
268
+ // This is necessary so that for sourceMaps with the same file structure in sources, name collisions do not occur.
269
+ // https://github.com/webpack-contrib/source-map-loader/issues/51
270
+ let { sourceURL, sourceContent } = await fetchFromURL(
271
+ readResource,
272
+ context,
273
+ source,
274
+ map.sourceRoot,
275
+ skipReading
276
+ );
277
+
278
+ if (skipReading) {
279
+ sourceContent = originalSourceContent;
280
+ }
281
+
282
+ // Return original value of `source` when error happens
283
+ return { sourceURL, sourceContent };
284
+ }
285
+ )
286
+ );
287
+
288
+ /** @type {RawSourceMap} */
289
+ const newMap = { ...map };
290
+
291
+ newMap.sources = [];
292
+ newMap.sourcesContent = [];
293
+
294
+ delete newMap.sourceRoot;
295
+
296
+ for (const source of resolvedSources) {
297
+ const { sourceURL, sourceContent } = source;
298
+
299
+ newMap.sources.push(sourceURL || "");
300
+ newMap.sourcesContent.push(
301
+ sourceContent ? sourceContent.toString("utf8") : ""
302
+ );
303
+ }
304
+
305
+ const sourcesContentIsEmpty =
306
+ newMap.sourcesContent.filter(Boolean).length === 0;
307
+
308
+ if (sourcesContentIsEmpty) {
309
+ delete newMap.sourcesContent;
310
+ }
311
+
312
+ return {
313
+ source: input.replace(replacementString, ""),
314
+ sourceMap: /** @type {RawSourceMap} */ (newMap)
315
+ };
316
+ }
317
+
318
+ module.exports = extractSourceMap;
319
+ module.exports.getSourceMappingURL = getSourceMappingURL;
@@ -11,6 +11,16 @@ const DONE_MARKER = 2;
11
11
  const DONE_MAYBE_ROOT_CYCLE_MARKER = 3;
12
12
  const DONE_AND_ROOT_MARKER = 4;
13
13
 
14
+ /**
15
+ * @template T
16
+ * @typedef {Set<Node<T>>} Nodes
17
+ */
18
+
19
+ /**
20
+ * @template T
21
+ * @typedef {Set<Cycle<T>>} Cycles
22
+ */
23
+
14
24
  /**
15
25
  * @template T
16
26
  */
@@ -20,7 +30,7 @@ class Node {
20
30
  */
21
31
  constructor(item) {
22
32
  this.item = item;
23
- /** @type {Set<Node<T>>} */
33
+ /** @type {Nodes<T>} */
24
34
  this.dependencies = new Set();
25
35
  this.marker = NO_MARKER;
26
36
  /** @type {Cycle<T> | undefined} */
@@ -34,7 +44,7 @@ class Node {
34
44
  */
35
45
  class Cycle {
36
46
  constructor() {
37
- /** @type {Set<Node<T>>} */
47
+ /** @type {Nodes<T>} */
38
48
  this.nodes = new Set();
39
49
  }
40
50
  }
@@ -75,13 +85,13 @@ module.exports = (items, getDependencies) => {
75
85
 
76
86
  // Set of current root modules
77
87
  // items will be removed if a new reference to it has been found
78
- /** @type {Set<Node<T>>} */
88
+ /** @type {Nodes<T>} */
79
89
  const roots = new Set();
80
90
 
81
91
  // Set of current cycles without references to it
82
92
  // cycles will be removed if a new reference to it has been found
83
93
  // that is not part of the cycle
84
- /** @type {Set<Cycle<T>>} */
94
+ /** @type {Cycles<T>} */
85
95
  const rootCycles = new Set();
86
96
 
87
97
  // For all non-marked nodes
@@ -201,7 +211,7 @@ module.exports = (items, getDependencies) => {
201
211
  // inside of the cycle
202
212
  for (const cycle of rootCycles) {
203
213
  let max = 0;
204
- /** @type {Set<Node<T>>} */
214
+ /** @type {Nodes<T>} */
205
215
  const cycleRoots = new Set();
206
216
  const nodes = cycle.nodes;
207
217
  for (const node of nodes) {
package/lib/util/fs.js CHANGED
@@ -85,17 +85,17 @@ const path = require("path");
85
85
 
86
86
  /** @typedef {Map<string, FileSystemInfoEntry | "ignore">} TimeInfoEntries */
87
87
 
88
+ /** @typedef {Set<string>} Changes */
89
+ /** @typedef {Set<string>} Removals */
90
+
88
91
  /**
89
92
  * @typedef {object} WatcherInfo
90
- * @property {Set<string> | null} changes get current aggregated changes that have not yet send to callback
91
- * @property {Set<string> | null} removals get current aggregated removals that have not yet send to callback
93
+ * @property {Changes | null} changes get current aggregated changes that have not yet send to callback
94
+ * @property {Removals | null} removals get current aggregated removals that have not yet send to callback
92
95
  * @property {TimeInfoEntries} fileTimeInfoEntries get info about files
93
96
  * @property {TimeInfoEntries} contextTimeInfoEntries get info about directories
94
97
  */
95
98
 
96
- /** @typedef {Set<string>} Changes */
97
- /** @typedef {Set<string>} Removals */
98
-
99
99
  // TODO webpack 6 deprecate missing getInfo
100
100
  /**
101
101
  * @typedef {object} Watcher
@@ -345,16 +345,29 @@ const path = require("path");
345
345
  * @typedef {(pathLike: PathLike, callback: NoParamCallback) => void} Unlink
346
346
  */
347
347
 
348
+ /**
349
+ * @typedef {FSImplementation & { read: (...args: EXPECTED_ANY[]) => EXPECTED_ANY }} CreateReadStreamFSImplementation
350
+ */
351
+
352
+ /**
353
+ * @typedef {StreamOptions & { fs?: CreateReadStreamFSImplementation | null | undefined, end?: number | undefined }} ReadStreamOptions
354
+ */
355
+
356
+ /**
357
+ * @typedef {(path: PathLike, options?: BufferEncoding | ReadStreamOptions) => NodeJS.ReadableStream} CreateReadStream
358
+ */
359
+
348
360
  /**
349
361
  * @typedef {object} OutputFileSystem
350
- * @property {WriteFile} writeFile
351
362
  * @property {Mkdir} mkdir
352
363
  * @property {Readdir=} readdir
353
364
  * @property {Rmdir=} rmdir
365
+ * @property {WriteFile} writeFile
354
366
  * @property {Unlink=} unlink
355
367
  * @property {Stat} stat
356
368
  * @property {LStat=} lstat
357
369
  * @property {ReadFile} readFile
370
+ * @property {CreateReadStream=} createReadStream
358
371
  * @property {((path1: string, path2: string) => string)=} join
359
372
  * @property {((from: string, to: string) => string)=} relative
360
373
  * @property {((dirname: string) => string)=} dirname
@@ -396,7 +409,7 @@ const path = require("path");
396
409
  */
397
410
 
398
411
  /**
399
- * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined }} WriteStreamOptions
412
+ * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined, flush?: boolean | undefined }} WriteStreamOptions
400
413
  */
401
414
 
402
415
  /**
@@ -461,7 +474,7 @@ const path = require("path");
461
474
  /** @typedef {InputFileSystem & OutputFileSystem & IntermediateFileSystemExtras} IntermediateFileSystem */
462
475
 
463
476
  /**
464
- * @param {InputFileSystem|OutputFileSystem|undefined} fs a file system
477
+ * @param {InputFileSystem | OutputFileSystem|undefined} fs a file system
465
478
  * @param {string} rootPath the root path
466
479
  * @param {string} targetPath the target path
467
480
  * @returns {string} location of targetPath relative to rootPath
@@ -649,7 +662,15 @@ const lstatReadlinkAbsolute = (fs, p, callback) => {
649
662
  doReadLink();
650
663
  };
651
664
 
665
+ /**
666
+ * @param {string} pathname a path
667
+ * @returns {boolean} is absolute
668
+ */
669
+ const isAbsolute = (pathname) =>
670
+ path.posix.isAbsolute(pathname) || path.win32.isAbsolute(pathname);
671
+
652
672
  module.exports.dirname = dirname;
673
+ module.exports.isAbsolute = isAbsolute;
653
674
  module.exports.join = join;
654
675
  module.exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute;
655
676
  module.exports.mkdirp = mkdirp;