# @stackline/resolve-url-loader 1.0.0 Canonical documentation: https://alexandro.net/docs/vanilla/resolve-url-loader/ Repository: https://github.com/alexandroit/stackline-resolve-url-loader Registry: https://www.npmjs.com/package/@stackline/resolve-url-loader License: MIT Runtime: Node.js >=12 inside a webpack loader process Browser support: none Compatibility baseline: resolve-url-loader@5.0.0, source commit e2695cde68f325f617825e168173df92236efb93 Direct production dependencies: loader-utils@2.0.4, postcss@8.5.26, regex-parser@2.3.1, source-map@0.6.1 Exact installed production graph: big.js@5.2.2, emojis-list@3.0.0, json5@2.2.3, loader-utils@2.0.4, nanoid@3.3.18, picocolors@1.1.1, postcss@8.5.26, regex-parser@2.3.1, source-map@0.6.1, source-map-js@1.2.1 ## Purpose @stackline/resolve-url-loader rewrites relative CSS url() values using original Sass source positions carried by an incoming source map. It solves the case where assets are colocated with imported Sass partials but webpack would otherwise resolve the unchanged relative URL beside the root generated CSS. This is a Node.js webpack loader. It is not a browser library, browser bundle, standalone PostCSS plugin, Vite plugin, CSS command, network fetcher, URL sanitizer, or filesystem containment mechanism. ## Install and loader order Scoped dependency: npm install @stackline/resolve-url-loader Compatibility alias: "resolve-url-loader": "npm:@stackline/resolve-url-loader@1.0.0" Webpack evaluates a use array right to left. Configure css-loader, then @stackline/resolve-url-loader, then sass-loader in source order so Sass executes first and URL rebasing executes immediately after it. Enable source maps in sass-loader, this loader, and the webpack build. Top-level devtool alone cannot recover missing upstream Sass source information. ## CommonJS root require('@stackline/resolve-url-loader') returns the callable webpack loader. It has exactly five enumerable helper properties, in this order: 1. asGenerator 2. createJoinImplementation 3. createJoinFunction 4. defaultJoinGenerator 5. defaultJoin This means there are six callable public values total: the loader itself plus five attached helper properties. It does not mean there are six helper properties. ## Loader contract The loader accepts CSS content and an object, JSON-string, null, or undefined source map from webpack. It reads resourcePath, context, fs, options, diagnostic methods, cacheable(), and async() from its bound loader context. It emits source-relative map sources on webpack 4 and project-relative map sources on webpack 5. Options are sourceMap, silent, removeCR, root, debug, and join. sourceMap defaults to loader.sourceMap. silent defaults false. removeCR defaults from the host EOL. root defaults false and opts into absolute-URL handling when it is a string. debug is false, true for console logging, or a logging function. join defaults to defaultJoin. Removed options engine, keepQuery, absolute, attempts, includeRoot, and fail retain deprecation diagnostics but do not regain their removed behavior. Relative filesystem URLs are processed. Absolute paths are processed only with a string root. Query strings and fragments are retained. HTTP(S), data, module-relative tilde paths, empty URLs, and other non-file forms pass through. ## Join helpers asGenerator(generator) normalizes an Array or zero-argument-next Iterator to unique [base, uri] tuples. Array strings and partial tuples receive null/original URI defaults. createJoinImplementation(generator) creates an attempt producer. It consumes at most 100,000 iterator steps, validates tuples and base directories through webpack's filesystem, normalizes joined paths, records fallbacks, and stops at the first existing regular file. createJoinFunction(name, implementation) creates a two-argument outer function (options, loader). That returns a one-argument inner function (item). Attempt records require base, uri, joined, isSuccess, and isFallback. The first success wins, otherwise the first fallback wins, otherwise the result is null. Non-null results must be absolute paths. Debug output is deduplicated. defaultJoinGenerator checks relative bases in this order: the source-map position at the URL substring, declaration value, declaration property, and selector. An absolute item uses only options.root. defaultJoin composes the default generator, implementation, and function wrappers. ## Join shapes A JoinItem contains uri, query, isAbsolute, and bases. bases has subString, value, property, and selector absolute directory candidates. A JoinAttempt contains base, uri, joined, isSuccess, and isFallback. The built-in implementation marks its recorded attempts as fallbacks and marks an attempt successful only when joined is an existing regular file. ## Historical deep entries The package intentionally has no restrictive exports map. These eight upstream JavaScript entries remain addressable, with or without .js: - lib/engine/postcss - lib/file-protocol - lib/join-function - lib/join-function/debug - lib/join-function/fs-utils - lib/log-to-test-harness - lib/position-algerbra - lib/value-processor The spelling position-algerbra is historical and preserved. First-party declarations are additive beside these entries. The vendored lib/vendor/adjust-sourcemap-loader files are implementation/provenance material, not a newly promised deep API. ## ESM and TypeScript index.mjs provides the CommonJS loader as its default and the same five helpers as named exports. Statically discoverable CommonJS properties also support Node ESM interop at the package root. CommonJS export-equals declarations, an ESM declaration facade, and deep-entry declarations are supplied. TypeScript 3.9 and the current compiler are tested. ## Preserved behavior The contract preserves callable CommonJS shape and helper order, webpack 4/5 map formats, object and JSON-string maps, option validation, warnings and error categories, root-relative opt-in, query/hash retention, custom join arity, iterator laziness and bound, fallback order, deduplicated diagnostics, ordinary POSIX and Windows paths, and all eight packed upstream lib entries. ## Intentional Windows correction Some source maps contain file:///D:/project/src/file.scss. Removing only file:// leaves /D:/project/src/file.scss, which fails Windows absolute path and base validation. On Windows hosts only, the maintained file protocol helper removes the extra slash when the remaining string starts with a drive-letter segment: file:///D:/project/src/file.scss -> D:/project/src/file.scss POSIX file URLs retain their root, including a drive-looking filename: file:///srv/project/src/file.scss -> /srv/project/src/file.scss file:///D:/literal-posix-name -> /D:/literal-posix-name ## Vendored provenance The exact adjust-sourcemap-loader@4.0.0 source-map process and codec sources from upstream commit 5f173eef are vendored beneath lib/vendor/adjust-sourcemap-loader. Their unmodified MIT license is retained. Vendoring prevents unrelated external releases from changing path codec behavior beneath an otherwise unchanged webpack configuration. The package itself derives from MIT-licensed resolve-url-loader@5.0.0 at commit e2695cde68f325f617825e168173df92236efb93. It is independently maintained and is not affiliated with or endorsed by Ben Holloway or the upstream project. ## Limits and security boundary Source maps and CSS are build inputs. Bound their size and build duration when they are not fully trusted. Custom joins execute trusted configuration code with access to webpack's loader context and filesystem. The loader does not fetch remote resources, sanitize CSS or URLs, confine filesystem reads to a root, add image-set() support, or promise automatic search beyond the selected join strategy. Report suspected vulnerabilities privately at: https://github.com/alexandroit/stackline-resolve-url-loader/security/advisories/new ## References README: https://alexandro.net/docs/vanilla/resolve-url-loader/README.md API: https://alexandro.net/docs/vanilla/resolve-url-loader/API.md Changelog: https://alexandro.net/docs/vanilla/resolve-url-loader/CHANGELOG.md Compatibility: https://alexandro.net/docs/vanilla/resolve-url-loader/COMPATIBILITY_CONTRACT.md Contributing: https://alexandro.net/docs/vanilla/resolve-url-loader/CONTRIBUTING.md Migration: https://alexandro.net/docs/vanilla/resolve-url-loader/MIGRATION.md Publishing: https://alexandro.net/docs/vanilla/resolve-url-loader/PUBLISHING.md Security: https://alexandro.net/docs/vanilla/resolve-url-loader/SECURITY.md Licenses: https://alexandro.net/docs/vanilla/resolve-url-loader/THIRD_PARTY_LICENSES.md Verification: https://alexandro.net/docs/vanilla/resolve-url-loader/VERIFICATION.md CommonJS example: https://alexandro.net/docs/vanilla/resolve-url-loader/examples/commonjs.cjs ESM example: https://alexandro.net/docs/vanilla/resolve-url-loader/examples/esm.mjs Metadata: https://alexandro.net/docs/vanilla/resolve-url-loader/package-meta.json