Directory-level asset linking in Sprockets manifests
The link_directory
directive provides precise control over asset compilation by processing files at a specific directory level without recursing into subdirectories. By "link", we mean they are specified as compilation targets to be written out to disk, and made available to be served to user-agents. Files in subdirectories will not be linked (Compare to link_tree).
This selective approach enables Rails developers to maintain organized asset hierarchies while controlling exactly which files become publicly available assets, making it particularly valuable for applications with complex directory structures where not all subdirectories should be processed.
How link_directory works
The path argument to linkdirectory is not a logical path (it does not use the asset load paths), but is a path relative to the file the linkdirectory directive is found in, and can use .. to navigate. This relative path approach provides flexibility in organizing manifest files and asset directories.
Single-level processing means only files directly in the specified directory become compilation targets. For a directory structure like:
app/assets/stylesheets/
├── application.css
├── components.css
└── admin/
└── dashboard.css
The directive //= link_directory ../stylesheets .css
would compile application.css
and components.css
but ignore admin/dashboard.css
.
File type filtering enables selective processing through optional second arguments. linkdirectory can take an optional second argument with an extension or content-type, with the two arguments separated by a space: `//= linkdirectory ../stylesheets text/cssor
//= linkdirectory ../morestylesheets .css`.
Common Rails usage patterns
JavaScript compilation often uses link_directory
when you want individual JavaScript files without bundling. //= link_directory ../javascripts .js
includes any file recognized as JS directly at ./app/assets/javascripts, creating separate compiled assets for each file.
Stylesheet organization benefits from link_directory
when maintaining separate CSS files. For CSS and JS, we use link_directory for the path from the config manifest file to the javascript "file". We compile .coffee and .scss down to .js and .css, respectively, so we denote that after the path.
Selective asset exposure helps when subdirectories contain partial files or internal assets that shouldn't be publicly accessible. Using link_directory
instead of link_tree
prevents accidental exposure of development-only or partial files.
Comparison with link_tree
Processing depth represents the fundamental difference:
- link_directory: Processes only immediate directory contents
- link_tree: Recursively processes all subdirectories
Use case scenarios differ based on asset organization:
- Choose
link_directory
when subdirectories contain partials, components, or internal files - Choose
link_tree
when all files in the directory hierarchy should be publicly accessible
Control granularity varies between the directives:
-
link_directory
provides precise control over which directory levels are processed -
link_tree
processes everything in the directory hierarchy
Manifest.js integration
The default manifest.js created by rails new looks like: //= link_directory ../javascripts .js
and //= link_directory ../stylesheets .css
. This default configuration assumes Rails applications organize assets with main files at the root level and supporting files in subdirectories.
Sprockets 4 requirements make the manifest.js file mandatory for asset compilation. The latest version(s) of sprockets require what's called a manifest.js file, replacing the older config.assets.precompile
array configuration approach.
Directory structure assumptions in default Rails configurations expect:
- Main application files directly in
app/assets/javascripts/
andapp/assets/stylesheets/
- Supporting files, partials, or components in subdirectories
- Images and fonts in tree structures processed by
link_tree
Practical examples and troubleshooting
File extension handling requires attention to compiled output types. When working with preprocessed files like SCSS or CoffeeScript, specify the target extension: //= link_directory ../stylesheets .css
compiles SCSS files to CSS output.
Path resolution issues commonly occur with incorrect relative paths. The first argument to linkdirectory and linktree is a file path relative to the manifest.js itself (does not use "asset load path"), requiring careful navigation from the manifest file location.
Migration from Sprockets 3 may require adjusting directory structures. You might find some files that were currently compiled by sprockets for delivery to browser no longer are, necessitating either file reorganization or manifest.js directive updates.
Performance and deployment considerations
Individual file serving through link_directory
aligns with HTTP/2 performance characteristics, where multiple small files can be delivered efficiently through multiplexing.
Asset fingerprinting applies to each linked file independently, enabling granular cache invalidation strategies. Changed files invalidate only their specific cached versions.
Production compilation processes link_directory
directives during rails assets:precompile
, generating fingerprinted assets in the public/assets/
directory for web server delivery.
The link_directory
directive serves as a precise tool for Rails asset management, enabling controlled compilation of directory contents while maintaining organized asset hierarchies and preventing unintended exposure of internal or partial files.