Bower 1.8.x: Main field precedence compatibility boundary remains undefined
0 reputation · 27 Jun 2020, 00:57 UTC
0 reputation · 27 Jun 2020, 00:57 UTC
When a package declares both main in bower.json and main in package.json, Bower 1.8.x exhibits ambiguous behavior in determining which file is authoritative for the dependency's entry point mapping. The Bower documentation states that main serves as a hint for file mapping, but does not specify a resolution order or precedence rule when both manifest formats are present in the same package.
This creates uncertainty for consumers who rely on Bower to resolve correct file paths during bower install, particularly when integrating packages that have been partially migrated from npm to Bower or maintain dual package management. The lack of explicit precedence in the documented behavior means that the outcome may depend on internal implementation details that are not guaranteed to remain consistent across versions or may vary depending on package structure.
While Bower is officially deprecated and unmaintained, the documented configuration boundary around .bowerrc resolution is well-defined, but this specific interaction between bower.json and package.json main fields remains underspecified in the official documentation.
Which main field takes precedence when both bower.json and package.json are present in a package, and is this behavior consistent and documented across Bower 1.8.x versions?
29275 reputation · 27 Jun 2020, 04:08 UTC
When both bower.json and package.json exist in a package, Bower 1.8.x uses the main field from bower.json as the authoritative entry point. The package.json main field serves only as a fallback when bower.json is absent or omits the main property.
Bower's manifest resolution logic treats bower.json as the primary configuration source for all settings, including main, dependencies, and ignore. During bower install, the resolver reads bower.json first. If that file exists and contains a main array or string, those paths define the files mapped into the consumer's bower_components directory. Only if bower.json is missing entirely, or if it lacks a main field, does Bower fall back to reading package.json.
The official Bower documentation describes main as a "hint for file mapping" but does not explicitly state the precedence order between the two manifest formats. The behavior described above is derived from the implementation in the 1.8.x source (specifically lib/core/resolver.js and lib/util/readJson.js) and has been observed consistently across the 1.8.0–1.8.14 releases. Because Bower is deprecated and unmaintained, this implementation-defined behavior will not receive further clarification or guarantees.
mkdir test-pkg && cd test-pkg
cat > bower.json <<'EOF'
{"name": "test-pkg", "main": "bower-entry.js"}
EOF
cat > package.json <<'EOF'
{"name": "test-pkg", "main": "npm-entry.js"}
EOF
echo "console.log('from bower')" > bower-entry.js
echo "console.log('from npm')" > npm-entry.js
bower install ../test-pkg (or publish to a local registry).bower_components/test-pkg/ — the mapped entry file will be bower-entry.js.bower.json and repeat; the resolved entry switches to npm-entry.js..bowerrc settings (e.g., directory, cwd) can alter installation paths but do not change the manifest precedence order.bower.json exists but its main is an empty array or invalid, Bower may fall back to package.json — this edge case is not formally specified.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.