sprockets 4.0.0.beta6 → 4.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d2caeaadba82b93fec24d508ff3dc84fa5f48db942cc968c732d5f2eb0fd0c0
4
- data.tar.gz: 5cc1d606e6ded78d675802867b00978e45a881642dd7cf3c6fcb8e2e2da8c799
3
+ metadata.gz: 603199dd1236b7db51572143c09ce33649d81ecd2151d73d01d539b05fb14caa
4
+ data.tar.gz: 84e1bf98ebe75d603c8e4ab0c813de0626812226c8315cccdc408bd46ac7e630
5
5
  SHA512:
6
- metadata.gz: dbe7fe89fb3d28046ea2ec42bd2f65d955d31752f713adc27f29049d206067dabaa0ed4e8021597cf6a6ef6969d65f9c392abd407091ea9544e53c11cec0fbcd
7
- data.tar.gz: '08ead7193ee03944662ab0f748282b339a083f04fb77179e1232b06feacdc4565ec9fc7f7d9a6815ac29eaca87c9b40e985fc144798a01dde4ee9a37df3c2c92'
6
+ metadata.gz: 6ca211b8b2f1eadd44b4b199e9ffb88f12efcc844b11d86abd3dd7eb78abdb8fc7a24405d95eb6f53b89686cee97417ca47257fbafbe76d35193c4ac2bf5ba35
7
+ data.tar.gz: dd22ed98ff05afe2820a24ca7bfb305ba7c1361a4854ecc69b467653297dffc6c872d17d66095561b0b4ef64f9bcee72999a150afa6b721fd0b0b77ada344d70
@@ -4,6 +4,12 @@ Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprocket
4
4
 
5
5
  ## Master
6
6
 
7
+ ## 4.0.0.beta7
8
+
9
+ - Fix a year long bug that caused `Sprockets::FileNotFound` errors when the asset was present [#547]
10
+ - Raise an error when two assets such as foo.js and foo.js.erb would produce the same output artifact (foo.js) [#549 #530]
11
+ - Process `*.jst.eco.erb` files with ERBProcessor
12
+
7
13
  ## 4.0.0.beta6
8
14
 
9
15
  - Fix source map line offsets [#515]
data/README.md CHANGED
@@ -5,7 +5,6 @@ It features declarative dependency management for JavaScript and CSS
5
5
  assets, as well as a powerful preprocessor pipeline that allows you to
6
6
  write assets in languages like CoffeeScript, Sass and SCSS.
7
7
 
8
-
9
8
  ## Installation
10
9
 
11
10
  Install Sprockets from RubyGems:
@@ -17,480 +16,607 @@ $ gem install sprockets
17
16
  Or include it in your project's `Gemfile` with Bundler:
18
17
 
19
18
  ``` ruby
20
- gem 'sprockets', '~> 3.0'
19
+ gem 'sprockets', '~> 4.0'
21
20
  ```
22
21
 
23
- ## Using Sprockets
22
+ ## Upgrading to Sprockets 4.x
23
+
24
+ These are the major features in Sprockets 4.x
25
+
26
+ - Source Maps
27
+ - Manifest.js
28
+ - ES6 support
29
+ - Deprecated processor interface in 3.x is removed in 4.x
24
30
 
25
- For most people interested in using Sprockets, you will want to see [End User Asset Generation](guides/end_user_asset_generation.md) guide. This contains information about Sprockets' directive syntax and default processing behavior.
31
+ Read more about them by referencing [Upgrading document](UPGRADING.md)
32
+
33
+ ## Guides
34
+
35
+ For most people interested in using Sprockets, you will want to see the README below.
26
36
 
27
37
  If you are a framework developer that is using Sprockets, see [Building an Asset Processing Framework](guides/building_an_asset_processing_framework.md).
28
38
 
29
39
  If you are a library developer who is extending the functionality of Sprockets, see [Extending Sprockets](guides/extending_sprockets.md).
30
40
 
31
- Below is a disjointed mix of documentation for all three of these roles. Eventually they will be moved to an appropriate guide, but for now, the recommended way to consume this documentation is to view the appropriate guide first and then supplement with docs from the README.
41
+ If you want to work on Sprockets or better understand how it works read [How Sprockets Works](guides/how_sprockets_works.md)
32
42
 
33
- ## Behavior
43
+ ## Behavior Overview
34
44
 
35
- ### Index files are proxies for folders
45
+ You can interact with Sprockets primarily through directives and file extensions. This section covers how to use each of these things, and the defaults that ship with Sprockets.
36
46
 
37
- In Sprockets, index files such as `index.js` or `index.css` inside of a folder will generate a file with the folder's name. So if you have a file named `foo/index.js`, it will compile down to `foo.js`. This is similar to Node.js's behavior of using [folders as modules](https://nodejs.org/api/modules.html#modules_folders_as_modules). It is also somewhat similar to the way that a file in `public/my_folder/index.html` can be reached by a request to `/my_folder`. This means that you cannot directly use an index file. For example this would not work:
47
+ Since you are likely using Sprockets through another framework (such as the [the Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)), there will be configuration options you can toggle that will change behavior such as what directories or files get compiled. For that documentation you should see your framework's documentation.
38
48
 
39
- ```
40
- <%= asset_path("foo/index.js") %>
41
- ```
49
+ #### Accessing Assets
42
50
 
43
- Instead you would need to use:
51
+ Assets in Sprockets are always referenced by their *logical path*.
44
52
 
45
- ```
46
- <%= asset_path("foo.js") %>
47
- ```
53
+ The logical path is the path of the asset source file relative to its
54
+ containing directory in the load path. For example, if your load path
55
+ contains the directory `app/assets/javascripts`:
56
+
57
+ <table>
58
+ <tr>
59
+ <th>Logical path</th>
60
+ <th>Source file on disk</th>
61
+ </tr>
62
+ <tr>
63
+ <td>application.js</td>
64
+ <td>app/assets/javascripts/application.js</td>
65
+ </tr>
66
+ <tr>
67
+ <td>models/project.js</td>
68
+ <td>app/assets/javascripts/models/project.js</td>
69
+ </tr>
70
+ <tr>
71
+ <td>hello.js</td>
72
+ <td>app/assets/javascripts/hello.coffee</td>
73
+ </tr>
74
+ </table>
48
75
 
49
- Why would you want to use this behavior? It is common behavior where you might want to include an entire directory of files in a top level javascript. You can do this in Sprockets using `require_tree .`
76
+ > Note: For assets that are compiled or transpiled, you want to specify the extension that you want, not the extension on disk. For example we specified `hello.js` even if the file on disk is a coffeescript file, since the asset it will generate is javascript.
50
77
 
51
- ```
52
- //= require_tree .
53
- ```
78
+ ### Directives
54
79
 
55
- This has the problem that files are required alphabetically. If your directory has `jquery-ui.js` and `jquery.min.js`, then Sprockets will require `jquery-ui.js` before `jquery` is required, which won't work (because jquery-ui depends on jquery). Previously the only way to get the correct ordering would be to rename your files, something like `0-jquery-ui.js`. Instead of doing that you can use an index file.
80
+ Directives are special comments in your asset file and the main way of interacting with processors. What kind of interactions? You can use these directives to tell Sprockets to load other files, or specify dependencies on other assets.
56
81
 
57
- For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
82
+ For example, let's say you have custom JavaScript that you've written. You put this javascript in a file called `beta.js`. The javascript makes heavy use of jQuery, so you need to load that before your code executes. You could add a `require` directive to the top of `beta.js`:
58
83
 
59
- ```
60
- //= require foo.js
84
+ ```js
85
+ //= require jquery
86
+
87
+ $().ready({
88
+ // my custom code here
89
+ })
61
90
  ```
62
91
 
63
- Then create a file `foo/index.js` that requires all the files in that folder in any order you want:
92
+ The directive processor understands comment blocks in three formats:
64
93
 
94
+ ``` css
95
+ /* Multi-line comment blocks (CSS, SCSS, JavaScript)
96
+ *= require foo
97
+ */
65
98
  ```
66
- //= require ./foo.min.js
67
- //= require ./foo-ui.js
99
+
100
+ ``` js
101
+ // Single-line comment blocks (SCSS, JavaScript)
102
+ //= require foo
68
103
  ```
69
104
 
70
- Now, your `application.js` will correctly load the `foo.min.js` before `foo-ui.js`. If you used `require_tree` it would not work correctly.
105
+ ``` coffee
106
+ # Single-line comment blocks (CoffeeScript)
107
+ #= require foo
108
+ ```
71
109
 
72
- ## Understanding the Sprockets Environment
110
+ > Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.
73
111
 
74
- You'll need an instance of the `Sprockets::Environment` class to
75
- access and serve assets from your application. Under Rails 4.0 and
76
- later, `YourApp::Application.assets` is a preconfigured
77
- `Sprockets::Environment` instance. For Rack-based applications, create
78
- an instance in `config.ru`.
112
+ Here is a list of the available directives:
79
113
 
80
- The Sprockets `Environment` has methods for retrieving and serving
81
- assets, manipulating the load path, and registering processors. It is
82
- also a Rack application that can be mounted at a URL to serve assets
83
- over HTTP.
114
+ - [`require`](#require) - Add the contents of a file to current
115
+ - [`require_self`](#require_self) - Change order of where current contents are concatenated to current
116
+ - [`require_directory`](#require_directory) - Add contents of each file in a folder to current
117
+ - [`require_tree`](#require_tree) - Add contents of all files in all directories in a path to current
118
+ - [`link`](#link) - Make target file compile and be publically available without adding contents to current
119
+ - [`link_directory`](#link_directory) - Make target directory compile and be publically available without adding contents to current
120
+ - [`link_tree`](#link_tree) - Make target tree compile and be publically available without adding contents to current
121
+ - [`depend_on`](#depend_on) - Recompile current file if target has changed
122
+ - [`stub`](#stub) - Ignore target file
84
123
 
85
- ### The Load Path
124
+ You can see what each of these does below.
86
125
 
87
- The *load path* is an ordered list of directories that Sprockets uses
88
- to search for assets.
126
+ ### Specifying Processors through File Extensions
89
127
 
90
- In the simplest case, a Sprockets environment's load path will consist
91
- of a single directory containing your application's asset source
92
- files. When mounted, the environment will serve assets from this
93
- directory as if they were static files in your public root.
128
+ Sprockets uses the filename extensions to determine what processors to run on your file and in what order. For example if you have a file:
94
129
 
95
- The power of the load path is that it lets you organize your source
96
- files into multiple directories -- even directories that live outside
97
- your application -- and combine those directories into a single
98
- virtual filesystem. That means you can easily bundle JavaScript, CSS
99
- and images into a Ruby library or [Bower](http://bower.io) package and import them into your application.
130
+ ```
131
+ application.scss
132
+ ```
100
133
 
101
- #### Manipulating the Load Path
134
+ Then Sprockets will by default run the sass processor (which implements scss). The output file will be converted to css.
102
135
 
103
- To add a directory to your environment's load path, use the
104
- `append_path` and `prepend_path` methods. Directories at the beginning
105
- of the load path have precedence over subsequent directories.
136
+ You can specify multiple processors by specifying multiple file extensions. For example you can use Ruby's [ERB template language](#invoking-ruby-with-erb) to embed content in your doc before running the sass processor. To accomplish this you would need to name your file
106
137
 
107
- ``` ruby
108
- environment = Sprockets::Environment.new
109
- environment.append_path 'app/assets/javascripts'
110
- environment.append_path 'lib/assets/javascripts'
111
- environment.append_path 'vendor/assets/bower_components'
138
+ ```
139
+ application.scss.erb
112
140
  ```
113
141
 
114
- In general, you should append to the path by default and reserve
115
- prepending for cases where you need to override existing assets.
142
+ Processors are run from right to left (tail to head), so in the above example the processor associated with `erb` will be run before the processor associated with `scss` extension.
116
143
 
117
- ### Accessing Assets
144
+ For a description of the processors that Sprockets has by default see the "default processors" section below. Other libraries may register additional processors.
118
145
 
119
- Once you've set up your environment's load path, you can mount the
120
- environment as a Rack server and request assets via HTTP. You can also
121
- access assets programmatically from within your application.
146
+ When "asking" for a compiled file, you always ask for the extension you want. For example if you're using Rails, to get the contents of `application.scss.erb` you would use
122
147
 
123
- #### Logical Paths
148
+ ```
149
+ asset_path("application.css")
150
+ ```
124
151
 
125
- Assets in Sprockets are always referenced by their *logical path*.
152
+ Sprockets understands that `application.scss.erb` will compile down to a `application.css`. Ask for what you need, not what you have.
126
153
 
127
- The logical path is the path of the asset source file relative to its
128
- containing directory in the load path. For example, if your load path
129
- contains the directory `app/assets/javascripts`:
154
+ If this isn't working like you expect, make sure you didn't typo an extension, and make sure the file is on a "load path" (see framework docs for adding new load paths).
130
155
 
131
- <table>
132
- <tr>
133
- <th>Asset source file</th>
134
- <th>Logical path</th>
135
- </tr>
136
- <tr>
137
- <td>app/assets/javascripts/application.js</td>
138
- <td>application.js</td>
139
- </tr>
140
- <tr>
141
- <td>app/assets/javascripts/models/project.js</td>
142
- <td>models/project.js</td>
143
- </tr>
144
- </table>
156
+ ## File Order Processing
145
157
 
146
- In this way, all directories in the load path are merged to create a
147
- virtual filesystem whose entries are logical paths.
158
+ By default files are processed in alphabetical order. This behavior can impact your asset compilation when one asset needs to be loaded before another.
148
159
 
149
- #### Serving Assets Over HTTP
160
+ For example if you have an `application.js` and it loads another directory
150
161
 
151
- When you mount an environment, all of its assets are accessible as
152
- logical paths underneath the *mount point*. For example, if you mount
153
- your environment at `/assets` and request the URL
154
- `/assets/application.js`, Sprockets will search your load path for the
155
- file named `application.js` and serve it.
162
+ ```js
163
+ //= require_directory my_javascript
164
+ ```
156
165
 
157
- Under Rails 4.0 and later, your Sprockets environment is automatically
158
- mounted at `/assets`. If you are using Sprockets with a Rack
159
- application, you will need to mount the environment yourself. A good
160
- way to do this is with the `map` method in `config.ru`:
166
+ The files in that directory will be loaded in alphabetical order. If the directory looks like this:
161
167
 
162
- ``` ruby
163
- require 'sprockets'
164
- map '/assets' do
165
- environment = Sprockets::Environment.new
166
- environment.append_path 'app/assets/javascripts'
167
- environment.append_path 'app/assets/stylesheets'
168
- run environment
169
- end
168
+ ```sh
169
+ $ ls -1 my_javascript/
170
170
 
171
- map '/' do
172
- run YourRackApp
173
- end
171
+ alpha.js
172
+ beta.js
173
+ jquery.js
174
174
  ```
175
175
 
176
- #### Accessing Assets Programmatically
176
+ Then `alpha.js` will be loaded before either of the other two. This can be a problem if `alpha.js` uses jquery. For this reason it is not recommend to use `require_directory` with files that are ordering dependent. You can either require individual files manually:
177
177
 
178
- You can use the `find_asset` method (aliased as `[]`) to retrieve an
179
- asset from a Sprockets environment. Pass it a logical path and you'll
180
- get a `Sprockets::Asset` instance back:
178
+ ```js
179
+ //= require jquery
180
+ //= require alpha
181
+ //= require beta
182
+ ```
181
183
 
182
- ``` ruby
183
- environment['application.js']
184
- # => #<Sprockets::Asset ...>
184
+ Or you can use index files to proxy your folders.
185
+
186
+ ### Index files are proxies for folders
187
+
188
+ In Sprockets index files such as `index.js` or `index.css` files inside of a folder will generate a file with the folder's name. So if you have a `foo/index.js` file it will compile down to `foo.js`. This is similar to NPM's behavior of using [folders as modules](https://nodejs.org/api/modules.html#modules_folders_as_modules). It is also somewhat similar to the way that a file in `public/my_folder/index.html` can be reached by a request to `/my_folder`. This means that you cannot directly use an index file. For example this would not work:
189
+
190
+ ```erb
191
+ <%= asset_path("foo/index.js") %>
185
192
  ```
186
193
 
187
- Call `to_s` on the resulting asset to access its contents, `length` to
188
- get its length in bytes, `mtime` to query its last-modified time, and
189
- `filename` to get its full path on the filesystem.
194
+ Instead you would need to use:
190
195
 
196
+ ```erb
197
+ <%= asset_path("foo.js") %>
198
+ ```
191
199
 
192
- ## Using Processors
200
+ Why would you want to use this behavior? It is common behavior where you might want to include an entire directory of files in a top level JavaScript. You can do this in Sprockets using `require_tree .`
193
201
 
194
- Asset source files can be written in another format, like SCSS or CoffeeScript,
195
- and automatically compiled to CSS or JavaScript by Sprockets. Processors that
196
- convert a file from one format to another are called *transformers*.
202
+ ```js
203
+ //= require_tree .
204
+ ```
197
205
 
198
- ### Minifying Assets
206
+ This has the problem that files are required alphabetically. If your directory has `jquery-ui.js` and `jquery.min.js` then Sprockets will require `jquery-ui.js` before `jquery` is required which won't work (because jquery-ui depends on jquery). Previously the only way to get the correct ordering would be to rename your files, something like `0-jquery-ui.js`. Instead of doing that you can use an index file.
199
207
 
200
- Several JavaScript and CSS minifiers are available through shorthand.
208
+ For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
201
209
 
202
- ``` ruby
203
- environment.js_compressor = :uglify
204
- environment.css_compressor = :scss
210
+ ```js
211
+ //= require foo.js
205
212
  ```
206
213
 
207
- If you are using Sprockets directly with a Rack app, don't forget to add
208
- the `uglifier` and `sass` gems to your Gemfile when using above options.
214
+ Then create a file `foo/index.js` that requires all the files in that folder in any order you want using relative references:
209
215
 
210
- ### Styling with Sass and SCSS
216
+ ```js
217
+ //= require ./foo.min.js
218
+ //= require ./foo-ui.js
219
+ ```
211
220
 
212
- [Sass](http://sass-lang.com/) is a language that compiles to CSS and
213
- adds features like nested rules, variables, mixins and selector
214
- inheritance.
221
+ Now in your `application.js` will correctly load the `foo.min.js` before `foo-ui.js`. If you used `require_tree` it would not work correctly.
215
222
 
216
- If the `sass` gem is available to your application, you can use Sass
217
- to write CSS assets in Sprockets.
223
+ ## Cache
218
224
 
219
- Sprockets supports both Sass syntaxes. For the original
220
- whitespace-sensitive syntax, use the extension `.sass`. For the
221
- new SCSS syntax, use the extension `.scss`.
225
+ Compiling assets is slow. It requires a lot of disk use to pull assets off of hard drives, a lot of RAM to manipulate those files in memory, and a lot of CPU for compilation operations. Because of this Sprockets has a cache to speed up asset compilation times. That's the good news. The bad news, is that sprockets has a cache and if you've found a bug it's likely going to involve the cache.
222
226
 
223
- ### Scripting with CoffeeScript
227
+ By default Sprockets uses the file system to cache assets. It makes sense that Sprockets does not want to generate assets that already exist on disk in `public/assets`, what might not be as intuitive is that Sprockets needs to cache "partial" assets.
224
228
 
225
- [CoffeeScript](http://jashkenas.github.io/coffeescript/) is a
226
- language that compiles to the "good parts" of JavaScript, featuring a
227
- cleaner syntax with array comprehensions, classes, and function
228
- binding.
229
+ For example if you have an `application.js` and it is made up of `a.js`, `b.js`, all the way to `z.js`
229
230
 
230
- If the `coffee-script` gem is available to your application, you can
231
- use CoffeeScript to write JavaScript assets in Sprockets. Note that
232
- the CoffeeScript compiler is written in JavaScript, and you will need
233
- an [ExecJS](https://github.com/rails/execjs)-supported runtime
234
- on your system to invoke it.
231
+ ```js
232
+ //= require a.js
233
+ //= require b.js
234
+ # ...
235
+ //= require z.js
236
+ ```
235
237
 
236
- To write JavaScript assets with CoffeeScript, use the extension
237
- `.coffee`.
238
+ The first time this file is compiled the `application.js` output will be written to disk, but also intermediary compiled files for `a.js` etc. will be written to the cache directory (usually `tmp/cache/assets`).
238
239
 
239
- ### JavaScript Templating with EJS and Eco
240
+ So, if `b.js` changes it will get recompiled. However instead of having to recompile the other files from `a.js` to `z.js` since they did not change, we can use the prior intermediary files stored in the cached values . If these files were expensive to generate, then this "partial" asset cache strategy can save a lot of time.
240
241
 
241
- Sprockets supports *JavaScript templates* for client-side rendering of
242
- strings or markup. JavaScript templates have the special format
243
- extension `.jst` and are compiled to JavaScript functions.
242
+ Directives such as `require`, `link`, and `depend_on` tell Sprockets what assets need to be re-compiled when a file changes. Files are considered "fresh" based on their mtime on disk and a combination of cache keys.
244
243
 
245
- When loaded, a JavaScript template function can be accessed by its
246
- logical path as a property on the global `JST` object. Invoke a
247
- template function to render the template as a string. The resulting
248
- string can then be inserted into the DOM.
244
+ On Rails you can force a "clean" install by clearing the `public/assets` and `tmp/cache/assets` directories.
249
245
 
250
- ```
251
- <!-- templates/hello.jst.ejs -->
252
- <div>Hello, <span><%= name %></span>!</div>
253
246
 
254
- // application.js
255
- //= require templates/hello
256
- $("#hello").html(JST["templates/hello"]({ name: "Sam" }));
247
+ ## Default Directives
248
+
249
+ Directives take a path or a path to a file. Paths for directive can be relative to the current file, for example:
250
+
251
+ ```js
252
+ //= require ../foo.js
257
253
  ```
258
254
 
259
- Sprockets supports two JavaScript template languages:
260
- [EJS](https://github.com/sstephenson/ruby-ejs), for embedded
261
- JavaScript, and [Eco](https://github.com/sstephenson/ruby-eco), for
262
- embedded CoffeeScript. Both languages use the familiar `<% … %>`
263
- syntax for embedding logic in templates.
255
+ This would load the file up one directory and named `foo.js`. However this isn't required if `foo.js` is on one of Sprocket's load paths. You can simply use
264
256
 
265
- If the `ejs` gem is available to your application, you can use EJS
266
- templates in Sprockets. EJS templates have the extension `.jst.ejs`.
257
+ ```js
258
+ //= require foo.js
259
+ ```
267
260
 
268
- If the `eco` gem is available to your application, you can use [Eco
269
- templates](https://github.com/sstephenson/eco) in Sprockets. Eco
270
- templates have the extension `.jst.eco`. Note that the `eco` gem
271
- depends on the CoffeeScript compiler, so the same caveats apply as
272
- outlined above for the CoffeeScript engine.
261
+ Without any prepended dots and sprockets will search for the asset. If the asset is on a sub-path of the load path, you can specify it without using a relative path as well:
273
262
 
274
- ### Invoking Ruby with ERB
263
+ ```js
264
+ //= require sub/path/foo.js
265
+ ```
275
266
 
276
- Sprockets provides an ERB engine for preprocessing assets using
277
- embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
278
- filename to enable the ERB engine.
267
+ You can also use an absolute path, but this is discouraged unless you know the directory structure of every machine you plan on running code on.
279
268
 
280
- Ruby code embedded in an asset is evaluated in the context of a
281
- `Sprockets::Context` instance for the given asset. Common uses for ERB
282
- include:
269
+ Below is a section for each of the built in directive types supported by Sprockets.
283
270
 
284
- - embedding another asset as a Base64-encoded `data:` URI with the
285
- `asset_data_uri` helper
286
- - inserting the URL to another asset, such as with the `asset_path`
287
- helper provided by the Sprockets Rails plugin
288
- - embedding other application resources, such as a localized string
289
- database, in a JavaScript asset via JSON
290
- - embedding version constants loaded from another file
271
+ ### require
291
272
 
292
- See the [Helper Methods](lib/sprockets/context.rb) section for more information about
293
- interacting with `Sprockets::Context` instances via ERB.
273
+ `require` *path* inserts the contents of the asset source file
274
+ specified by *path*. If the file is required multiple times, it will
275
+ appear in the bundle only once.
294
276
 
277
+ **Example:**
295
278
 
296
- ## Managing and Bundling Dependencies
279
+ If you've got an `a.js`:
297
280
 
298
- You can create *asset bundles* -- ordered concatenations of asset
299
- source files -- by specifying dependencies in a special comment syntax
300
- at the top of each source file.
281
+ ```js
282
+ var a = "A";
283
+ ```
301
284
 
302
- Sprockets reads these comments, called *directives*, and processes
303
- them to recursively build a dependency graph. When you request an
304
- asset with dependencies, the dependencies will be included in order at
305
- the top of the file.
285
+ and a `b.js`;
306
286
 
307
- ### The Directive Processor
287
+ ```js
288
+ var b = "B";
289
+ ```
308
290
 
309
- Sprockets runs the *directive processor* on each CSS and JavaScript
310
- source file. The directive processor scans for comment lines beginning
311
- with `=` in comment blocks at the top of the file.
291
+ Then you could require both of these in an `application.js`
312
292
 
313
- ``` js
314
- //= require jquery
315
- //= require jquery-ui
316
- //= require backbone
317
- //= require_tree .
293
+ ```js
294
+ //= require a.js
295
+ //= require b.js
318
296
  ```
319
297
 
320
- The first word immediately following `=` specifies the directive
321
- name. Any words following the directive name are treated as
322
- arguments. Arguments may be placed in single or double quotes if they
323
- contain spaces, similar to commands in the Unix shell.
298
+ Which would generate one concatenated file:
324
299
 
325
- **Note**: Non-directive comment lines will be preserved in the final
326
- asset, but directive comments are stripped after
327
- processing. Sprockets will not look for directives in comment blocks
328
- that occur after the first line of code.
300
+ ```js
301
+ var a = "A";
302
+ var b = "B";
303
+ ```
329
304
 
330
- #### Supported Comment Types
305
+ ### require_self
331
306
 
332
- The directive processor understands comment blocks in three formats:
307
+ `require_self` tells Sprockets to insert the body of the current
308
+ source file before any subsequent `require` directives.
333
309
 
334
- ``` css
335
- /* Multi-line comment blocks (CSS, SCSS, JavaScript)
336
- *= require foo
337
- */
338
- ```
310
+ **Example:**
339
311
 
340
- ``` js
341
- // Single-line comment blocks (SCSS, JavaScript)
342
- //= require foo
343
- ```
312
+ If you've got an `a.js`:
344
313
 
345
- ``` coffee
346
- # Single-line comment blocks (CoffeeScript)
347
- #= require foo
314
+ ```js
315
+ var a = "A";
348
316
  ```
349
317
 
350
- ### Sprockets Directives
318
+ And an `application.js`
351
319
 
352
- You can use the following directives to declare dependencies in asset
353
- source files.
320
+ ```js
321
+ //= require_self
322
+ //= require 'a.js'
354
323
 
355
- For directives that take a *path* argument, you may specify either a
356
- logical path or a relative path. Relative paths begin with `./` and
357
- reference files relative to the location of the current file.
324
+ var app_name = "Sprockets";
325
+ ```
358
326
 
359
- #### The `require` Directive
327
+ Then this will take the contents of `application.js` (that come after the last require) and put them at the beginning of the file:
360
328
 
361
- `require` *path* inserts the contents of the asset source file
362
- specified by *path*. If the same file is required multiple times
363
- with different path expressions, it will appear in the bundle only once.
329
+ ```js
330
+ var app_name = "Sprockets";
331
+ var a = "A";
332
+ ```
364
333
 
365
- #### The `require_directory` Directive
334
+ ### require_directory
366
335
 
367
336
  `require_directory` *path* requires all source files of the same
368
337
  format in the directory specified by *path*. Files are required in
369
338
  alphabetical order.
370
339
 
371
- #### The `require_tree` Directive
340
+ **Example:**
341
+
342
+ If we've got a directory called `alphabet` with an `a.js` and `b.js` files like before, then our `application.js`
343
+
344
+ ```js
345
+ //= require_directory alphabet
346
+ ```
347
+
348
+ Would produce:
349
+
350
+ ```js
351
+ var a = "A";
352
+ var b = "B";
353
+ ```
354
+
355
+ You can also see [Index files are proxies for folders](#index-files-are-proxies-for-folders) for another method of organizing folders that will give you more control.
356
+
357
+ ### require_tree
372
358
 
373
359
  `require_tree` *path* works like `require_directory`, but operates
374
360
  recursively to require all files in all subdirectories of the
375
361
  directory specified by *path*.
376
362
 
377
- #### The `require_self` Directive
378
-
379
- `require_self` tells Sprockets to insert the body of the current
380
- source file before any subsequent `require` directives.
381
-
382
- #### The `link` Directive
363
+ ### link
383
364
 
384
365
  `link` *path* declares a dependency on the target *path* and adds it to a list
385
366
  of subdependencies to automatically be compiled when the asset is written out to
386
367
  disk.
387
368
 
388
- For an example, in a CSS file you might reference an external image that always
389
- needs to be compiled along with the css file.
390
-
391
- ``` css
392
- /*= link "logo.png" */
393
- .logo {
394
- background-image: url(logo.png)
395
- }
396
- ```
369
+ Example:
397
370
 
398
- However, if you use a `asset-path` or `asset-url` SCSS helper, these links will
399
- automatically be defined for you.
371
+ If you've got a `manifest.js` file and you want to explicitly make sure an `admin.js` file is
372
+ generated and made available to the public you can link it like this:
400
373
 
401
- ``` css
402
- .logo {
403
- background-image: asset-url("logo.png")
404
- }
374
+ ```
375
+ //= link admin.js
405
376
  ```
406
377
 
407
- #### The `link_directory` Directive
378
+ ### link_directory
408
379
 
409
380
  `link_directory` *path* links all the files inside the directory specified by the *path*
410
381
 
411
- #### The `link_tree` Directive
382
+ ### link_tree
412
383
 
413
384
  `link_tree` *path* works like `link_directory`, but operates
414
385
  recursively to link all files in all subdirectories of the
415
386
  directory specified by *path*.
416
387
 
417
- #### The `depend_on` Directive
388
+ Example:
389
+
390
+ You can specify a file extension so any extra files will be ignored:
391
+
392
+ ```js
393
+ //= link_tree path/to/folder .js
394
+ ```
395
+
396
+ > Note: There is an intentional space between the path and the extension
397
+
398
+ ### depend_on
418
399
 
419
400
  `depend_on` *path* declares a dependency on the given *path* without
420
401
  including it in the bundle. This is useful when you need to expire an
421
402
  asset's cache in response to a change in another file.
422
403
 
423
- #### The `depend_on_asset` Directive
404
+ **Example:**
405
+
406
+ If you have a file such as `bar.data` and you're using data from that file in another file, then
407
+ you need to tell sprockets that it needs to re-compile the file if `bar.data` changes:
408
+
409
+ ```js
410
+ //= depend_on "bar.data"
411
+
412
+ var bar = '<%= File.read("bar.data") %>'
413
+ ```
414
+
415
+ ### depend_on_asset
424
416
 
425
417
  `depend_on_asset` *path* works like `depend_on`, but operates
426
418
  recursively reading the file and following the directives found. This is automatically implied if you use `link`, so consider if it just makes sense using `link` instead of `depend_on_asset`.
427
419
 
428
- #### The `stub` Directive
420
+ ### stub
429
421
 
430
422
  `stub` *path* excludes that asset and its dependencies from the asset bundle.
431
423
  The *path* must be a valid asset and may or may not already be part
432
424
  of the bundle. `stub` should only be used at the top level bundle, not
433
425
  within any subdependencies.
434
426
 
435
- ## Processor Interface
427
+ ### Invoking Ruby with ERB
436
428
 
437
- Sprockets 2.x was originally designed around [Tilt](https://github.com/rtomayko/tilt)'s engine interface. However, starting with 3.x, a new interface has been introduced deprecating Tilt.
429
+ Sprockets provides an ERB engine for preprocessing assets using
430
+ embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
431
+ filename to enable the ERB engine.
438
432
 
439
- Similar to Rack, a processor is any "callable" (an object that responds to `call`). This may be a simple Proc or a full class that defines a `def self.call(input)` method. The `call` method accepts an `input` Hash and returns a Hash of metadata.
433
+ For example if you have an `app/application/javascripts/app_name.js.erb`
434
+ you could have this in the template
440
435
 
441
- Also see [`Sprockets::ProcessorUtils`](https://github.com/rails/sprockets/blob/master/lib/sprockets/processor_utils.rb) for public helper methods.
436
+ ```js
437
+ var app_name = "<%= ENV['APP_NAME'] %>";
438
+ ```
442
439
 
443
- ### Input Hash
440
+ Generated files are cached. If you're using an `ENV` var then
441
+ when you change then ENV var the asset will be forced to
442
+ recompile. This behavior is only true for environment variables,
443
+ if you are pulling a value from somewhere else, such as a database,
444
+ must manually invalidate the cache to see the change.
444
445
 
445
- The `input` Hash defines the following public fields.
446
+ If you're using Rails, there are helpers you can use such as `asset_url`
447
+ that will cause a recompile if the value changes.
446
448
 
447
- * `:data` - String asset contents.
448
- * `:environment` - Current `Sprockets::Environment` instance.
449
- * `:cache` - A `Sprockets::Cache` instance. See [`Sprockets::Cache#fetch`](https://github.com/rails/sprockets/blob/master/lib/sprockets/cache.rb).
450
- * `:uri` - String Asset URI.
451
- * `:load_path` - String current load path for filename.
452
- * `:name` - String logical path for filename.
453
- * `:content_type` - String content type of the output asset.
454
- * `:metadata` - Hash of processor metadata.
449
+ For example if you have this in your `application.css`
455
450
 
456
- ``` ruby
457
- def self.call(input)
458
- input[:cache].fetch("my:cache:key:v1") do
459
- # Remove all semicolons from source
460
- input[:data].gsub(";", "")
461
- end
462
- end
451
+ ``` css
452
+ .logo {
453
+ background: url(<%= asset_url("logo.png") %>)
454
+ }
455
+ ```
456
+
457
+ When you modify the `logo.png` on disk, it will force `application.css` to be
458
+ recompiled so that the fingerprint will be correct in the generated asset.
459
+
460
+ You can manually make sprockets depend on any other file that is generated
461
+ by sprockets by using the `depend_on` directive. Rails implements the above
462
+ feature by auto calling `depend_on` on the original asset when the `asset_url`
463
+ is used inside of an asset.
464
+
465
+ ### Styling with Sass and SCSS
466
+
467
+ [Sass](http://sass-lang.com/) is a language that compiles to CSS and
468
+ adds features like nested rules, variables, mixins and selector
469
+ inheritance.
470
+
471
+ If the `sass` gem is available to your application, you can use Sass
472
+ to write CSS assets in Sprockets.
473
+
474
+ Sprockets supports both Sass syntaxes. For the original
475
+ whitespace-sensitive syntax, use the extension `.sass`. For the
476
+ new SCSS syntax, use the extension `.scss`.
477
+
478
+ In Rails if you have `app/application/stylesheets/foo.scss` it can
479
+ be referenced with `<%= asset_path("foo.css") %>`. When referencing
480
+ an asset in Rails, always specify the extension you want. Sprockets will
481
+ convert `foo.scss` to `foo.css`.
482
+
483
+ ### Scripting with CoffeeScript
484
+
485
+ [CoffeeScript](http://jashkenas.github.io/coffeescript/) is a
486
+ language that compiles to the "good parts" of JavaScript, featuring a
487
+ cleaner syntax with array comprehensions, classes, and function
488
+ binding.
489
+
490
+ If the `coffee-script` gem is available to your application, you can
491
+ use CoffeeScript to write JavaScript assets in Sprockets. Note that
492
+ the CoffeeScript compiler is written in JavaScript, and you will need
493
+ an [ExecJS](https://github.com/rails/execjs)-supported runtime
494
+ on your system to invoke it.
495
+
496
+ To write JavaScript assets with CoffeeScript, use the extension
497
+ `.coffee`.
498
+
499
+ In Rails if you have `app/application/javascripts/foo.coffee` it can
500
+ be referenced with `<%= asset_path("foo.js") %>`. When referencing
501
+ an asset in Rails, always specify the extension you want. Sprockets will
502
+ convert `foo.coffee` to `foo.js`.
503
+
504
+
505
+ ## ES6 Support
506
+
507
+ 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:
508
+
509
+ ```ruby
510
+ gem 'babel-transpiler'
511
+ ```
512
+
513
+ Any asset with the extension `es6` will be treated as an ES6 file:
514
+
515
+ ```es6
516
+ // app/assets/javascript/application.es6
517
+
518
+ var square = (n) => n * n
519
+
520
+ console.log(square);
463
521
  ```
464
522
 
465
- ### return Hash
523
+ Start a Rails server in development mode and visit `localhost:3000/assets/application.js`, and this asset will be transpiled to JavaScript:
466
524
 
467
- The processor should return metadata `Hash`. With the exception of the `:data` key, the processor can store arbitrary valid JSON values in this Hash. The data will be stored and exposed on `Asset#metadata`.
525
+ ```js
526
+ var square = function square(n) {
527
+ return n * n;
528
+ };
468
529
 
469
- The returned `:data` replaces the assets `input[:data]` to the next processor in the chain. Returning a `String` is shorthand for returning `{ data: str }`. And returning `nil` is shorthand for a no-op where the input data is not transformed, `{ data: input[:data] }`.
530
+ console.log(square);
531
+ ```
470
532
 
471
- ### metadata
472
533
 
473
- The metadata Hash provides an open format for processors to extend the pipeline processor. Internally, built-in processors use it for passing data to each other.
534
+ ### JavaScript Templating with EJS and Eco
474
535
 
475
- * `:required` - A `Set` of String Asset URIs that the Bundle processor should concatenate together.
476
- * `:stubbed` - A `Set` of String Asset URIs that will be omitted from the `:required` set.
477
- * `:links` - A `Set` of String Asset URIs that should be compiled along with this asset.
478
- * `:dependencies` - A `Set` of String Cache URIs that should be monitored for caching.
479
- * `:map` - An `Array` of source maps for the asset.
480
- * `:charset` - The mime charset for an asset.
536
+ Sprockets supports *JavaScript templates* for client-side rendering of
537
+ strings or markup. JavaScript templates have the special format
538
+ extension `.jst` and are compiled to JavaScript functions.
539
+
540
+ When loaded, a JavaScript template function can be accessed by its
541
+ logical path as a property on the global `JST` object. Invoke a
542
+ template function to render the template as a string. The resulting
543
+ string can then be inserted into the DOM.
544
+
545
+ ```
546
+ <!-- templates/hello.jst.ejs -->
547
+ <div>Hello, <span><%= name %></span>!</div>
548
+
549
+ // application.js
550
+ //= require templates/hello
551
+ $("#hello").html(JST["templates/hello"]({ name: "Sam" }));
552
+ ```
553
+
554
+ Sprockets supports two JavaScript template languages:
555
+ [EJS](https://github.com/sstephenson/ruby-ejs), for embedded
556
+ JavaScript, and [Eco](https://github.com/sstephenson/ruby-eco), for
557
+ embedded CoffeeScript. Both languages use the familiar `<% … %>`
558
+ syntax for embedding logic in templates.
559
+
560
+ If the `ejs` gem is available to your application, you can use EJS
561
+ templates in Sprockets. EJS templates have the extension `.jst.ejs`.
562
+
563
+ If the `eco` gem is available to your application, you can use [Eco
564
+ templates](https://github.com/sstephenson/eco) in Sprockets. Eco
565
+ templates have the extension `.jst.eco`. Note that the `eco` gem
566
+ depends on the CoffeeScript compiler, so the same caveats apply as
567
+ outlined above for the CoffeeScript engine.
568
+
569
+ ### Minifying Assets
570
+
571
+ Several JavaScript and CSS minifiers are available through shorthand.
572
+
573
+ In Rails you will specify them with:
574
+
575
+ ```ruby
576
+ config.assets.js_compressor = :uglify
577
+ config.assets.css_compressor = :scss
578
+ ```
579
+
580
+ If you're not using Rails, configure this directly on the "environment".
481
581
 
482
582
  ``` ruby
483
- def self.call(input)
484
- # Any metadata may start off as nil, so initialize it the value
485
- required = Set.new(input[:metadata][:required])
583
+ environment.js_compressor = :uglify
584
+ environment.css_compressor = :scss
585
+ ```
586
+
587
+ If you are using Sprockets directly with a Rack app, don't forget to add
588
+ the `uglifier` and `sass` gems to your Gemfile when using above options.
589
+
590
+ ### Gzip
591
+
592
+ By default when Sprockets generates a compiled asset file it will also produce a gzipped copy of that file. Sprockets only gzips non-binary files such as CSS, javascript, and SVG files.
593
+
594
+ For example if Sprockets is generating
595
+
596
+ ```
597
+ application-12345.css
598
+ ```
599
+
600
+ Then it will also generate a compressed copy in
601
+
602
+ ```
603
+ application-12345.css.gz
604
+ ```
605
+
606
+ This behavior can be disabled, refer to your framework specific documentation.
607
+
608
+ ### Serving Assets
486
609
 
487
- # Manually add "foo.js" asset uri to our bundle
488
- required << input[:environment].resolve("foo.js")
610
+ In production you should generate your assets to a directory on disk and serve them either via Nginx or a feature like Rail's `config.public_file_server.enabled = true`.
489
611
 
490
- { required: required }
491
- end
612
+ On Rails you can generate assets by running:
613
+
614
+ ```term
615
+ $ RAILS_ENV=production rake assets:precompile
492
616
  ```
493
617
 
618
+ In development Rails will serve assets from `Sprockets::Server`.
619
+
494
620
  ## Contributing to Sprockets
495
621
 
496
622
  Sprockets is the work of hundreds of contributors. You're encouraged to submit pull requests, propose