Skip to content

Commit af0947f

Browse files
authored
Merge pull request #644 from jrochkind/upgrading_doc_change
Enhancments to UPGRADING doc
2 parents d5aa63a + 24df294 commit af0947f

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

UPGRADING.md

+51-13
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@ Make sure that you're running the latest Sprockets 3 release. This document is a
44

55
This upgrading guide touches on:
66

7+
- Upgrading as a Rails dependency
78
- Source Maps
89
- Manifest.js
10+
- In a Rails app, possible backwards incompatible changes in how top-level targets are determined.
911
- ES6 support
1012
- Deprecated processor interface in 3.x is removed in 4.x
1113

14+
## Upgrading as a Rails Dependency
15+
16+
Your Rails app Gemfile may have a line requiring sass-rails 5.0:
17+
18+
gem 'sass-rails', '~> 5.0'
19+
# or
20+
gem 'sass-rails', '~> 5'
21+
22+
These will prevent upgrade to sprockets 4, if you'd like to upgrade to sprockets 4 change to:
23+
24+
gem 'sass-rails', '>= 5'
25+
26+
And then run `bundle update sass-rails sprockets` to get sass-rails 6.x and sprockets 4.x.
27+
1228
## Source Maps
1329

1430
Read more about [What is a source map](https://schneems.com/2017/11/14/wtf-is-a-source-map/).
@@ -25,36 +41,56 @@ How do you know if source maps are working correctly? Try adding a syntax error
2541

2642
## Manifest.js
2743

28-
Previously, if you wanted Rails to serve a non-standard named asset (any CSS not called `application.css` or JS not called `application.js`) you would have to add those files to a precompile list. For example, if you needed a marketing page with its own CSS you might add something like this:
44+
When compiling assets with Sprockets, Sprockets needs to decide which top-level targets to compile, usually `application.css`, `application.js`, and images.
45+
46+
If you are using sprockets prior to 4.0, Rails will compile `application.css`, `application.js`; and *any* files found in your assets directory(ies) that are _not_ recognized as JS or CSS, but do have a filename extension. That latter was meant to apply to all your images usually in `./app/assets/images/`, but could have targetted other files as well.
47+
48+
If you wanted to specify additional assets to deliver that were not included by this logic, for instance for a marketing page with its own CSS, you might add something like this:
2949

3050

3151
```ruby
32-
# In your Rails configuration
52+
# In your Rails configuration, prior to Sprockets 4
3353
config.assets.precompile += ["marketing.css"]
3454
```
3555

36-
Sprockets 3 introduced the concept of a "manifest" file that could list all assets you want to make available using the `link` directive. In this case, to compile the `marketing.css` you would set precompile to:
56+
If you are using Sprockets 4, Rails changes it's default logic for determining top-level targets. It will now use _only_ a file at `./app/assets/config/manifest.js` for specifying top-level targets; this file may already exist in your Rails app (although Rails only starts automatically using it once you are using sprockets 4), if not you should create it.
3757

38-
```ruby
39-
config.assets.precompile = ["manifest.js"]
58+
The `manifest.js` file is meant to specify what files to use as a top-level target using sprockets methods `link`, `link_directory`, and `link_tree`.
59+
60+
The default `manifest.js` created by `rails new` for the past few Rails versions looks like:
61+
62+
```js
63+
//= link_tree ../images
64+
//= link_directory ../javascripts .js
65+
//= link_directory ../stylesheets .css
4066
```
4167

42-
Then you will `link` to that css file in your `manifest.js` file. In Sprockets the `link` directive declares that your file has a dependency on the thing you are linking, so it guarantees it will be compiled. Here's our example manifest file:
68+
This says to include the contents of all file found in the `./app/assets/images` directory or any subdirectories. And any files recognized as CSS directly at `./app/assets/stylesheets` or as JS at `./app/assets/javascripts` (not including subdirectories). (The JS line is not generated in Rails 6.0 apps, since Rails 6.0 apps do not manage JS with sprockets).
69+
70+
Since the default logic for determining top-level targets changed, you might find some files that were currently compiled by sprockets for delivery to browser no longer are. You will have to edit the `manifest.js` to specify those files.
71+
72+
You may also find that some files that were *not* previously compiled as top-level targets now are. For instance, if your existing app has any js files directly at `./app/assets/javascripts` or css/scss files `./app/assets/stylesheets`, Rails with Sprockets 4 will now compile them as top-level targets. Since they were not previously treated as such, you probably don't mean them to be; if they are .scss partials referencing variables meant to be defined in other files, it may even result in an error message that looks like `Undefined variable: $some_variable`.
73+
74+
To correct this, you can move these files to some _subdirectory_ of `./app/assets/stylesheets` or `javascripts`; or you can change the `manifest.js` to be more like how Rails with Sprockets 3 works, linking only the specific `application` files as top-level targets:
4375

4476
```js
45-
// app/assets/config/manifest.js
46-
//
77+
//= link_tree ../images
4778
//= link application.css
48-
//= link marketing.css
49-
//
5079
//= link application.js
80+
//
81+
// maybe another non-standard file?
82+
//= link marketing.css
5183
```
5284

53-
**Caution**: the "link" directive should have an explicit content type or file extension.
85+
**Caution**: the "link" directive should always have an explicit content type or file extension.
86+
87+
Now you'll be able to use a `<%= stylesheet_link_tag "application" %>` or `<%= stylesheet_link_tag "marketing" %>` in your code.
5488

55-
Now you'll be able to use a `<%= stylesheet_link_tag "marketing" %>` in your code. This is a standard way to let Sprockets know what files need to be compiled.
89+
If you have additional non-standard files you need to be top-level targets, instead of using `config.assets.precompile`, you can use `link`, `link_directory`, and `link_tree` directives in the `manifest.js`.
5690

57-
Some assets will be compiled when they are referenced from inside of another asset. For example, the `asset_url` erb helper will automatically link assets:
91+
Existing `config.assets.precompile` settings will still work for string values (although it is discouraged), but if you were previously using regexp or proc values, they won't work at all with Sprockets 4, and if you try you'll get an exception raised that looks like `NoMethodError: undefined method 'start_with?'`
92+
93+
Some assets will be compiled as top-level assets when they are referenced from inside of another asset. For example, the `asset_url` erb helper will automatically link assets:
5894

5995
``` css
6096
.logo {
@@ -66,6 +102,8 @@ When you do this Sprockets will "link" `logo.png` behind the scenes. This lets S
66102

67103
One benefit of using a `manifest.js` file for this type of configuration is that now Sprockets is using Sprockets to understand what files need to be generated instead of a non-portable framework-specific interface.
68104

105+
For more information on `link`, `link_tree`, and `link_directory` see the [README](./README.md).
106+
69107
## ES6 Support
70108

71109
Sprockets 4 ships with a Babel processor. This allows you to transpile ECMAScript6 to JavaScript just like you would transpile CoffeeScript to JavaScript. To use this, modify your Gemfile:

0 commit comments

Comments
 (0)