sprockets 2.2.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +68 -0
  3. data/README.md +482 -255
  4. data/bin/sprockets +20 -7
  5. data/lib/rake/sprocketstask.rb +28 -15
  6. data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  7. data/lib/sprockets/asset.rb +142 -207
  8. data/lib/sprockets/autoload/babel.rb +8 -0
  9. data/lib/sprockets/autoload/closure.rb +8 -0
  10. data/lib/sprockets/autoload/coffee_script.rb +8 -0
  11. data/lib/sprockets/autoload/eco.rb +8 -0
  12. data/lib/sprockets/autoload/ejs.rb +8 -0
  13. data/lib/sprockets/autoload/jsminc.rb +8 -0
  14. data/lib/sprockets/autoload/sass.rb +8 -0
  15. data/lib/sprockets/autoload/sassc.rb +8 -0
  16. data/lib/sprockets/autoload/uglifier.rb +8 -0
  17. data/lib/sprockets/autoload/yui.rb +8 -0
  18. data/lib/sprockets/autoload/zopfli.rb +7 -0
  19. data/lib/sprockets/autoload.rb +16 -0
  20. data/lib/sprockets/babel_processor.rb +66 -0
  21. data/lib/sprockets/base.rb +89 -249
  22. data/lib/sprockets/bower.rb +61 -0
  23. data/lib/sprockets/bundle.rb +105 -0
  24. data/lib/sprockets/cache/file_store.rb +190 -14
  25. data/lib/sprockets/cache/memory_store.rb +75 -0
  26. data/lib/sprockets/cache/null_store.rb +54 -0
  27. data/lib/sprockets/cache.rb +271 -0
  28. data/lib/sprockets/cached_environment.rb +64 -0
  29. data/lib/sprockets/closure_compressor.rb +48 -0
  30. data/lib/sprockets/coffee_script_processor.rb +39 -0
  31. data/lib/sprockets/compressing.rb +134 -0
  32. data/lib/sprockets/configuration.rb +79 -0
  33. data/lib/sprockets/context.rb +204 -135
  34. data/lib/sprockets/dependencies.rb +74 -0
  35. data/lib/sprockets/digest_utils.rb +200 -0
  36. data/lib/sprockets/directive_processor.rb +224 -216
  37. data/lib/sprockets/eco_processor.rb +33 -0
  38. data/lib/sprockets/ejs_processor.rb +32 -0
  39. data/lib/sprockets/encoding_utils.rb +262 -0
  40. data/lib/sprockets/environment.rb +23 -68
  41. data/lib/sprockets/erb_processor.rb +37 -0
  42. data/lib/sprockets/errors.rb +6 -13
  43. data/lib/sprockets/exporters/base.rb +72 -0
  44. data/lib/sprockets/exporters/file_exporter.rb +24 -0
  45. data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
  46. data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
  47. data/lib/sprockets/exporting.rb +73 -0
  48. data/lib/sprockets/file_reader.rb +16 -0
  49. data/lib/sprockets/http_utils.rb +135 -0
  50. data/lib/sprockets/jsminc_compressor.rb +32 -0
  51. data/lib/sprockets/jst_processor.rb +36 -19
  52. data/lib/sprockets/loader.rb +343 -0
  53. data/lib/sprockets/manifest.rb +231 -96
  54. data/lib/sprockets/manifest_utils.rb +48 -0
  55. data/lib/sprockets/mime.rb +80 -32
  56. data/lib/sprockets/npm.rb +52 -0
  57. data/lib/sprockets/path_dependency_utils.rb +77 -0
  58. data/lib/sprockets/path_digest_utils.rb +48 -0
  59. data/lib/sprockets/path_utils.rb +367 -0
  60. data/lib/sprockets/paths.rb +82 -0
  61. data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  62. data/lib/sprockets/processing.rb +140 -192
  63. data/lib/sprockets/processor_utils.rb +169 -0
  64. data/lib/sprockets/resolve.rb +295 -0
  65. data/lib/sprockets/sass_cache_store.rb +30 -0
  66. data/lib/sprockets/sass_compressor.rb +63 -0
  67. data/lib/sprockets/sass_functions.rb +3 -0
  68. data/lib/sprockets/sass_importer.rb +3 -0
  69. data/lib/sprockets/sass_processor.rb +313 -0
  70. data/lib/sprockets/sassc_compressor.rb +56 -0
  71. data/lib/sprockets/sassc_processor.rb +297 -0
  72. data/lib/sprockets/server.rb +138 -90
  73. data/lib/sprockets/source_map_processor.rb +66 -0
  74. data/lib/sprockets/source_map_utils.rb +483 -0
  75. data/lib/sprockets/transformers.rb +173 -0
  76. data/lib/sprockets/uglifier_compressor.rb +66 -0
  77. data/lib/sprockets/unloaded_asset.rb +139 -0
  78. data/lib/sprockets/uri_tar.rb +99 -0
  79. data/lib/sprockets/uri_utils.rb +191 -0
  80. data/lib/sprockets/utils/gzip.rb +99 -0
  81. data/lib/sprockets/utils.rb +186 -53
  82. data/lib/sprockets/version.rb +2 -1
  83. data/lib/sprockets/yui_compressor.rb +56 -0
  84. data/lib/sprockets.rb +217 -52
  85. metadata +250 -59
  86. data/LICENSE +0 -21
  87. data/lib/sprockets/asset_attributes.rb +0 -126
  88. data/lib/sprockets/bundled_asset.rb +0 -79
  89. data/lib/sprockets/caching.rb +0 -96
  90. data/lib/sprockets/charset_normalizer.rb +0 -41
  91. data/lib/sprockets/eco_template.rb +0 -38
  92. data/lib/sprockets/ejs_template.rb +0 -37
  93. data/lib/sprockets/engines.rb +0 -74
  94. data/lib/sprockets/index.rb +0 -99
  95. data/lib/sprockets/processed_asset.rb +0 -152
  96. data/lib/sprockets/processor.rb +0 -32
  97. data/lib/sprockets/safety_colons.rb +0 -28
  98. data/lib/sprockets/static_asset.rb +0 -57
  99. data/lib/sprockets/trail.rb +0 -90
data/README.md CHANGED
@@ -3,68 +3,50 @@
3
3
  Sprockets is a Ruby library for compiling and serving web assets.
4
4
  It features declarative dependency management for JavaScript and CSS
5
5
  assets, as well as a powerful preprocessor pipeline that allows you to
6
- write assets in languages like CoffeeScript, Sass, SCSS and LESS.
6
+ write assets in languages like CoffeeScript, Sass and SCSS.
7
7
 
8
- # Installation #
8
+ ## Installation
9
9
 
10
10
  Install Sprockets from RubyGems:
11
11
 
12
- $ gem install sprockets
12
+ ``` sh
13
+ $ gem install sprockets
14
+ ```
13
15
 
14
16
  Or include it in your project's `Gemfile` with Bundler:
15
17
 
16
- gem 'sprockets', '~> 2.0'
18
+ ``` ruby
19
+ gem 'sprockets', '~> 4.0'
20
+ ```
17
21
 
18
- # Understanding the Sprockets Environment #
22
+ ## Upgrading to Sprockets 4.x
19
23
 
20
- You'll need an instance of the `Sprockets::Environment` class to
21
- access and serve assets from your application. Under Rails 3.1 and
22
- later, `YourApp::Application.assets` is a preconfigured
23
- `Sprockets::Environment` instance. For Rack-based applications, create
24
- an instance in `config.ru`.
24
+ These are the major features in Sprockets 4.x
25
25
 
26
- The Sprockets `Environment` has methods for retrieving and serving
27
- assets, manipulating the load path, and registering processors. It is
28
- also a Rack application that can be mounted at a URL to serve assets
29
- over HTTP.
26
+ - Source Maps
27
+ - Manifest.js
28
+ - ES6 support
29
+ - Deprecated processor interface in 3.x is removed in 4.x
30
30
 
31
- ## The Load Path ##
31
+ Read more about them by referencing [Upgrading document](UPGRADING.md)
32
32
 
33
- The *load path* is an ordered list of directories that Sprockets uses
34
- to search for assets.
33
+ ## Guides
35
34
 
36
- In the simplest case, a Sprockets environment's load path will consist
37
- of a single directory containing your application's asset source
38
- files. When mounted, the environment will serve assets from this
39
- directory as if they were static files in your public root.
35
+ For most people interested in using Sprockets, you will want to see the README below.
40
36
 
41
- The power of the load path is that it lets you organize your source
42
- files into multiple directories -- even directories that live outside
43
- your application -- and combine those directories into a single
44
- virtual filesystem. That means you can easily bundle JavaScript, CSS
45
- and images into a Ruby library and import them into your application.
37
+ If you are a framework developer that is using Sprockets, see [Building an Asset Processing Framework](guides/building_an_asset_processing_framework.md).
46
38
 
47
- ### Manipulating the Load Path ###
39
+ If you are a library developer who is extending the functionality of Sprockets, see [Extending Sprockets](guides/extending_sprockets.md).
48
40
 
49
- To add a directory to your environment's load path, use the
50
- `append_path` and `prepend_path` methods. Directories at the beginning
51
- of the load path have precedence over subsequent directories.
41
+ If you want to work on Sprockets or better understand how it works read [How Sprockets Works](guides/how_sprockets_works.md)
52
42
 
53
- environment = Sprockets::Environment.new
54
- environment.append_path 'app/assets/javascripts'
55
- environment.append_path 'lib/assets/javascripts'
56
- environment.append_path 'vendor/assets/jquery'
43
+ ## Behavior Overview
57
44
 
58
- In general, you should append to the path by default and reserve
59
- prepending for cases where you need to override existing assets.
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.
60
46
 
61
- ## Accessing Assets ##
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.
62
48
 
63
- Once you've set up your environment's load path, you can mount the
64
- environment as a Rack server and request assets via HTTP. You can also
65
- access assets programmatically from within your application.
66
-
67
- ### Logical Paths ###
49
+ #### Accessing Assets
68
50
 
69
51
  Assets in Sprockets are always referenced by their *logical path*.
70
52
 
@@ -74,332 +56,577 @@ contains the directory `app/assets/javascripts`:
74
56
 
75
57
  <table>
76
58
  <tr>
77
- <th>Asset source file</th>
78
59
  <th>Logical path</th>
60
+ <th>Source file on disk</th>
79
61
  </tr>
80
62
  <tr>
81
- <td>app/assets/javascripts/application.js</td>
82
63
  <td>application.js</td>
64
+ <td>app/assets/javascripts/application.js</td>
83
65
  </tr>
84
66
  <tr>
85
- <td>app/assets/javascripts/models/project.js</td>
86
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>
87
73
  </tr>
88
74
  </table>
89
75
 
90
- In this way, all directories in the load path are merged to create a
91
- virtual filesystem whose entries are logical paths.
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.
92
77
 
93
- ### Serving Assets Over HTTP ###
78
+ ### Directives
94
79
 
95
- When you mount an environment, all of its assets are accessible as
96
- logical paths underneath the *mount point*. For example, if you mount
97
- your environment at `/assets` and request the URL
98
- `/assets/application.js`, Sprockets will search your load path for the
99
- file named `application.js` and serve it.
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.
100
81
 
101
- Under Rails 3.1 and later, your Sprockets environment is automatically
102
- mounted at `/assets`. If you are using Sprockets with a Rack
103
- application, you will need to mount the environment yourself. A good
104
- way to do this is with the `map` method in `config.ru`:
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`:
105
83
 
106
- require 'sprockets'
107
- map '/assets' do
108
- environment = Sprockets::Environment.new
109
- environment.append_path 'app/assets/javascripts'
110
- environment.append_path 'app/assets/stylesheets'
111
- run environment
112
- end
84
+ ```js
85
+ //= require jquery
113
86
 
114
- map '/' do
115
- run YourRackApp
116
- end
87
+ $().ready({
88
+ // my custom code here
89
+ })
90
+ ```
117
91
 
118
- ### Accessing Assets Programmatically ###
92
+ The directive processor understands comment blocks in three formats:
119
93
 
120
- You can use the `find_asset` method (aliased as `[]`) to retrieve an
121
- asset from a Sprockets environment. Pass it a logical path and you'll
122
- get a `Sprockets::BundledAsset` instance back:
94
+ ``` css
95
+ /* Multi-line comment blocks (CSS, SCSS, JavaScript)
96
+ *= require foo
97
+ */
98
+ ```
123
99
 
124
- environment['application.js']
125
- # => #<Sprockets::BundledAsset ...>
100
+ ``` js
101
+ // Single-line comment blocks (SCSS, JavaScript)
102
+ //= require foo
103
+ ```
126
104
 
127
- Call `to_s` on the resulting asset to access its contents, `length` to
128
- get its length in bytes, `mtime` to query its last-modified time, and
129
- `pathname` to get its full path on the filesystem.
105
+ ``` coffee
106
+ # Single-line comment blocks (CoffeeScript)
107
+ #= require foo
108
+ ```
130
109
 
131
- # Using Engines #
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.
132
111
 
133
- Asset source files can be written in another language, like SCSS or
134
- CoffeeScript, and automatically compiled to CSS or JavaScript by
135
- Sprockets. Compilers for these languages are called *engines*.
112
+ Here is a list of the available directives:
136
113
 
137
- Engines are specified by additional extensions on the asset source
138
- filename. For example, a CSS file written in SCSS might have the name
139
- `layout.css.scss`, while a JavaScript file written in CoffeeScript
140
- might have the name `dialog.js.coffee`.
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
141
123
 
142
- ## Styling with Sass and SCSS ##
124
+ You can see what each of these does below.
143
125
 
144
- [Sass](http://sass-lang.com/) is a language that compiles to CSS and
145
- adds features like nested rules, variables, mixins and selector
146
- inheritance.
126
+ ### Specifying Processors through File Extensions
147
127
 
148
- If the `sass` gem is available to your application, you can use Sass
149
- to write CSS assets in Sprockets.
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:
150
129
 
151
- Sprockets supports both Sass syntaxes. For the original
152
- whitespace-sensitive syntax, use the extension `.css.sass`. For the
153
- new SCSS syntax, use the extension `.css.scss`.
130
+ ```
131
+ application.scss
132
+ ```
154
133
 
155
- ## Styling with LESS ##
134
+ Then Sprockets will by default run the sass processor (which implements scss). The output file will be converted to css.
156
135
 
157
- [LESS](http://lesscss.org/) extends CSS with dynamic behavior such as
158
- variables, mixins, operations and functions.
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
159
137
 
160
- If the `less` gem is available to your application, you can use LESS
161
- to write CSS assets in Sprockets. Note that the LESS compiler is
162
- written in JavaScript, and at the time of this writing, the `less` gem
163
- depends on `therubyracer` which embeds the V8 JavaScript runtime in
164
- Ruby.
138
+ ```
139
+ application.scss.erb
140
+ ```
165
141
 
166
- To write CSS assets with LESS, use the extension `.css.less`.
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.
167
143
 
168
- ## Scripting with CoffeeScript ##
144
+ For a description of the processors that Sprockets has by default see the "default processors" section below. Other libraries may register additional processors.
169
145
 
170
- [CoffeeScript](http://jashkenas.github.com/coffee-script/) is a
171
- language that compiles to the "good parts" of JavaScript, featuring a
172
- cleaner syntax with array comprehensions, classes, and function
173
- binding.
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
174
147
 
175
- If the `coffee-script` gem is available to your application, you can
176
- use CoffeeScript to write JavaScript assets in Sprockets. Note that
177
- the CoffeeScript compiler is written in JavaScript, and you will need
178
- an [ExecJS](https://github.com/sstephenson/execjs)-supported runtime
179
- on your system to invoke it.
148
+ ```
149
+ asset_path("application.css")
150
+ ```
180
151
 
181
- To write JavaScript assets with CoffeeScript, use the extension
182
- `.js.coffee`.
152
+ Sprockets understands that `application.scss.erb` will compile down to a `application.css`. Ask for what you need, not what you have.
183
153
 
184
- ## JavaScript Templating with EJS and Eco ##
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).
185
155
 
186
- Sprockets supports *JavaScript templates* for client-side rendering of
187
- strings or markup. JavaScript templates have the special format
188
- extension `.jst` and are compiled to JavaScript functions.
156
+ ## File Order Processing
189
157
 
190
- When loaded, a JavaScript template function can be accessed by its
191
- logical path as a property on the global `JST` object. Invoke a
192
- template function to render the template as a string. The resulting
193
- string can then be inserted into the DOM.
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.
194
159
 
195
- <!-- templates/hello.jst.ejs -->
196
- <div>Hello, <span><%= name %></span>!</div>
160
+ For example if you have an `application.js` and it loads another directory
197
161
 
198
- // application.js
199
- //= require templates/hello
200
- $("#hello").html(JST["templates/hello"]({ name: "Sam" }));
162
+ ```js
163
+ //= require_directory my_javascript
164
+ ```
201
165
 
202
- Sprockets supports two JavaScript template languages:
203
- [EJS](https://github.com/sstephenson/ruby-ejs), for embedded
204
- JavaScript, and [Eco](https://github.com/sstephenson/ruby-eco), for
205
- embedded CoffeeScript. Both languages use the familiar `<% … %>`
206
- syntax for embedding logic in templates.
166
+ The files in that directory will be loaded in alphabetical order. If the directory looks like this:
207
167
 
208
- If the `ejs` gem is available to your application, you can use EJS
209
- templates in Sprockets. EJS templates have the extension `.jst.ejs`.
168
+ ```sh
169
+ $ ls -1 my_javascript/
210
170
 
211
- If the `eco` gem is available to your application, you can use [Eco
212
- templates](https://github.com/sstephenson/eco) in Sprockets. Eco
213
- templates have the extension `.jst.eco`. Note that the `eco` gem
214
- depends on the CoffeeScript compiler, so the same caveats apply as
215
- outlined above for the CoffeeScript engine.
171
+ alpha.js
172
+ beta.js
173
+ jquery.js
174
+ ```
216
175
 
217
- ## Invoking Ruby with ERB ##
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:
218
177
 
219
- Sprockets provides an ERB engine for preprocessing assets using
220
- embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
221
- filename to enable the ERB engine.
178
+ ```js
179
+ //= require jquery
180
+ //= require alpha
181
+ //= require beta
182
+ ```
222
183
 
223
- **Note**: Sprockets processes multiple engine extensions in order from
224
- right to left, so you can use multiple engines with a single
225
- asset. For example, to have a CoffeeScript asset that is first
226
- preprocessed with ERB, use the extension `.js.coffee.erb`.
184
+ Or you can use index files to proxy your folders.
227
185
 
228
- Ruby code embedded in an asset is evaluated in the context of a
229
- `Sprockets::Context` instance for the given asset. Common uses for ERB
230
- include:
186
+ ### Index files are proxies for folders
231
187
 
232
- - embedding another asset as a Base64-encoded `data:` URI with the
233
- `asset_data_uri` helper
234
- - inserting the URL to another asset, such as with the `asset_path`
235
- helper provided by the Sprockets Rails plugin
236
- - embedding other application resources, such as a localized string
237
- database, in a JavaScript asset via JSON
238
- - embedding version constants loaded from another file
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:
239
189
 
240
- See the [Helper Methods](#FIXME) section for more information about
241
- interacting with `Sprockets::Context` instances via ERB.
190
+ ```erb
191
+ <%= asset_path("foo/index.js") %>
192
+ ```
242
193
 
243
- ### String Interpolation Syntax ###
194
+ Instead you would need to use:
244
195
 
245
- If you need access to Ruby from an asset but cannot use ERB's `<% …
246
- %>` syntax, Sprockets also supports Ruby string interpolation syntax
247
- (`#{ … }`) with the `.str` engine extension.
196
+ ```erb
197
+ <%= asset_path("foo.js") %>
198
+ ```
248
199
 
249
- # Managing and Bundling Dependencies #
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 .`
250
201
 
251
- You can create *asset bundles* -- ordered concatenations of asset
252
- source files -- by specifying dependencies in a special comment syntax
253
- at the top of each source file.
202
+ ```js
203
+ //= require_tree .
204
+ ```
254
205
 
255
- Sprockets reads these comments, called *directives*, and processes
256
- them to recursively build a dependency graph. When you request an
257
- asset with dependencies, the dependencies will be included in order at
258
- the top of the file.
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.
259
207
 
260
- ## The Directive Processor ##
208
+ For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
261
209
 
262
- Sprockets runs the *directive processor* on each CSS and JavaScript
263
- source file. The directive processor scans for comment lines beginning
264
- with `=` in comment blocks at the top of the file.
210
+ ```js
211
+ //= require foo.js
212
+ ```
265
213
 
266
- //= require jquery
267
- //= require jquery-ui
268
- //= require backbone
269
- //= require_tree .
214
+ Then create a file `foo/index.js` that requires all the files in that folder in any order you want using relative references:
270
215
 
271
- The first word immediately following `=` specifies the directive
272
- name. Any words following the directive name are treated as
273
- arguments. Arguments may be placed in single or double quotes if they
274
- contain spaces, similar to commands in the Unix shell.
216
+ ```js
217
+ //= require ./foo.min.js
218
+ //= require ./foo-ui.js
219
+ ```
275
220
 
276
- **Note**: Non-directive comment lines will be preserved in the final
277
- asset, but directive comments are stripped after
278
- processing. Sprockets will not look for directives in comment blocks
279
- that occur after the first line of code.
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.
280
222
 
281
- ### Supported Comment Types ###
223
+ ## Cache
282
224
 
283
- The directive processor understands comment blocks in three formats:
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.
226
+
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.
228
+
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`
230
+
231
+ ```js
232
+ //= require a.js
233
+ //= require b.js
234
+ # ...
235
+ //= require z.js
236
+ ```
237
+
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`).
239
+
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.
241
+
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.
243
+
244
+ On Rails you can force a "clean" install by clearing the `public/assets` and `tmp/cache/assets` directories.
245
+
246
+
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:
284
250
 
285
- /* Multi-line comment blocks (CSS, SCSS, JavaScript)
286
- *= require foo
287
- */
251
+ ```js
252
+ //= require ../foo.js
253
+ ```
288
254
 
289
- // Single-line comment blocks (SCSS, JavaScript)
290
- //= require foo
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
291
256
 
292
- # Single-line comment blocks (CoffeeScript)
293
- #= require foo
257
+ ```js
258
+ //= require foo.js
259
+ ```
294
260
 
295
- ## Sprockets Directives ##
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:
296
262
 
297
- You can use the following directives to declare dependencies in asset
298
- source files.
263
+ ```js
264
+ //= require sub/path/foo.js
265
+ ```
299
266
 
300
- For directives that take a *path* argument, you may specify either a
301
- logical path or a relative path. Relative paths begin with `./` and
302
- reference files relative to the location of the current file.
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.
303
268
 
304
- ### The `require` Directive ###
269
+ Below is a section for each of the built in directive types supported by Sprockets.
270
+
271
+ ### require
305
272
 
306
273
  `require` *path* inserts the contents of the asset source file
307
274
  specified by *path*. If the file is required multiple times, it will
308
275
  appear in the bundle only once.
309
276
 
310
- ### The `include` Directive ###
277
+ **Example:**
278
+
279
+ If you've got an `a.js`:
280
+
281
+ ```js
282
+ var a = "A";
283
+ ```
284
+
285
+ and a `b.js`;
286
+
287
+ ```js
288
+ var b = "B";
289
+ ```
290
+
291
+ Then you could require both of these in an `application.js`
292
+
293
+ ```js
294
+ //= require a.js
295
+ //= require b.js
296
+ ```
297
+
298
+ Which would generate one concatenated file:
299
+
300
+ ```js
301
+ var a = "A";
302
+ var b = "B";
303
+ ```
304
+
305
+ ### require_self
306
+
307
+ `require_self` tells Sprockets to insert the body of the current
308
+ source file before any subsequent `require` directives.
309
+
310
+ **Example:**
311
+
312
+ If you've got an `a.js`:
313
+
314
+ ```js
315
+ var a = "A";
316
+ ```
317
+
318
+ And an `application.js`
319
+
320
+ ```js
321
+ //= require_self
322
+ //= require 'a.js'
311
323
 
312
- `include` *path* works like `require`, but inserts the contents of the
313
- specified source file even if it has already been included or
314
- required.
324
+ var app_name = "Sprockets";
325
+ ```
315
326
 
316
- ### The `require_directory` 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:
328
+
329
+ ```js
330
+ var app_name = "Sprockets";
331
+ var a = "A";
332
+ ```
333
+
334
+ ### require_directory
317
335
 
318
336
  `require_directory` *path* requires all source files of the same
319
337
  format in the directory specified by *path*. Files are required in
320
338
  alphabetical order.
321
339
 
322
- ### 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
323
358
 
324
359
  `require_tree` *path* works like `require_directory`, but operates
325
360
  recursively to require all files in all subdirectories of the
326
361
  directory specified by *path*.
327
362
 
328
- ### The `require_self` Directive ###
363
+ ### link
329
364
 
330
- `require_self` tells Sprockets to insert the body of the current
331
- source file before any subsequent `require` or `include` directives.
365
+ `link` *path* declares a dependency on the target *path* and adds it to a list
366
+ of subdependencies to automatically be compiled when the asset is written out to
367
+ disk.
368
+
369
+ Example:
370
+
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:
373
+
374
+ ```
375
+ //= link admin.js
376
+ ```
377
+
378
+ ### link_directory
379
+
380
+ `link_directory` *path* links all the files inside the directory specified by the *path*
381
+
382
+ ### link_tree
383
+
384
+ `link_tree` *path* works like `link_directory`, but operates
385
+ recursively to link all files in all subdirectories of the
386
+ directory specified by *path*.
387
+
388
+ Example:
389
+
390
+ You can specify a file extension so any extra files will be ignored:
332
391
 
333
- ### The `depend_on` Directive ###
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
334
399
 
335
400
  `depend_on` *path* declares a dependency on the given *path* without
336
401
  including it in the bundle. This is useful when you need to expire an
337
402
  asset's cache in response to a change in another file.
338
403
 
339
- # Development #
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
416
+
417
+ `depend_on_asset` *path* works like `depend_on`, but operates
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`.
419
+
420
+ ### stub
421
+
422
+ `stub` *path* excludes that asset and its dependencies from the asset bundle.
423
+ The *path* must be a valid asset and may or may not already be part
424
+ of the bundle. `stub` should only be used at the top level bundle, not
425
+ within any subdependencies.
426
+
427
+ ### Invoking Ruby with ERB
428
+
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.
432
+
433
+ For example if you have an `app/application/javascripts/app_name.js.erb`
434
+ you could have this in the template
435
+
436
+ ```js
437
+ var app_name = "<%= ENV['APP_NAME'] %>";
438
+ ```
439
+
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.
445
+
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.
448
+
449
+ For example if you have this in your `application.css`
450
+
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);
521
+ ```
522
+
523
+ Start a Rails server in development mode and visit `localhost:3000/assets/application.js`, and this asset will be transpiled to JavaScript:
524
+
525
+ ```js
526
+ var square = function square(n) {
527
+ return n * n;
528
+ };
529
+
530
+ console.log(square);
531
+ ```
532
+
533
+
534
+ ### JavaScript Templating with EJS and Eco
535
+
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.
340
568
 
341
- ## Contributing ##
569
+ ### Minifying Assets
342
570
 
343
- The Sprockets source code is [hosted on
344
- GitHub](https://github.com/sstephenson/sprockets). You can check out a
345
- copy of the latest code using Git:
571
+ Several JavaScript and CSS minifiers are available through shorthand.
346
572
 
347
- $ git clone https://github.com/sstephenson/sprockets.git
573
+ In Rails you will specify them with:
348
574
 
349
- If you've found a bug or have a question, please open an issue on the
350
- [Sprockets issue
351
- tracker](https://github.com/sstephenson/sprockets/issues). Or, clone
352
- the Sprockets repository, write a failing test case, fix the bug and
353
- submit a pull request.
575
+ ```ruby
576
+ config.assets.js_compressor = :uglify
577
+ config.assets.css_compressor = :scss
578
+ ```
354
579
 
355
- ## Version History ##
580
+ If you're not using Rails, configure this directly on the "environment".
356
581
 
357
- **2.2.0** (Unreleased)
582
+ ``` ruby
583
+ environment.js_compressor = :uglify
584
+ environment.css_compressor = :scss
585
+ ```
358
586
 
359
- * Added `sprockets` command line utility.
360
- * Added rake/sprocketstask.
361
- * Added json manifest log of compiled assets.
362
- * Added `stub` directive that allows you to exclude files from the bundle.
363
- * Added per environment external encoding (Environment#default_external_encoding). Defaults to UTF-8. Fixes issues where LANG is not set correctly and Rubys default external is set to ASCII.
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.
364
589
 
365
- **2.1.2** (November 20, 2011)
590
+ ### Gzip
366
591
 
367
- * Disabled If-Modified-Since server checks. Fixes some browser caching issues when serving the asset body only. If-None-Match caching is sufficent.
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.
368
593
 
369
- **2.1.1** (November 18, 2011)
594
+ For example if Sprockets is generating
370
595
 
371
- * Fix windows absolute path check bug.
596
+ ```
597
+ application-12345.css
598
+ ```
372
599
 
373
- **2.1.0** (November 11, 2011)
600
+ Then it will also generate a compressed copy in
374
601
 
375
- * Directive comment lines are now turned into empty lines instead of removed. This way line numbers in
376
- CoffeeScript syntax errors are correct.
377
- * Performance and caching bug fixes.
602
+ ```
603
+ application-12345.css.gz
604
+ ```
378
605
 
379
- **2.0.3** (October 17, 2011)
606
+ This behavior can be disabled, refer to your framework specific documentation.
380
607
 
381
- * Detect format extensions from right to left.
382
- * Make JST namespace configurable.
608
+ ### Serving Assets
383
609
 
384
- **2.0.2** (October 4, 2011)
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`.
385
611
 
386
- * Fixed loading stale cache from bundler gems.
612
+ On Rails you can generate assets by running:
387
613
 
388
- **2.0.1** (September 30, 2011)
614
+ ```term
615
+ $ RAILS_ENV=production rake assets:precompile
616
+ ```
389
617
 
390
- * Fixed bug with fingerprinting file names with multiple dots.
391
- * Decode URIs as default internal.
392
- * Fix symlinked asset directories.
618
+ In development Rails will serve assets from `Sprockets::Server`.
393
619
 
394
- **2.0.0** (August 29, 2011)
620
+ ## Contributing to Sprockets
395
621
 
396
- * Initial public release.
622
+ Sprockets is the work of hundreds of contributors. You're encouraged to submit pull requests, propose
623
+ features and discuss issues.
397
624
 
398
- # License #
625
+ See [CONTRIBUTING](CONTRIBUTING.md).
399
626
 
400
- Copyright &copy; 2011 Sam Stephenson <<sstephenson@gmail.com>>
627
+ ### Version History
401
628
 
402
- Copyright &copy; 2011 Joshua Peek <<josh@joshpeek.com>>
629
+ Please see the [CHANGELOG](https://github.com/rails/sprockets/tree/master/CHANGELOG.md)
403
630
 
404
- Sprockets is distributed under an MIT-style license. See LICENSE for
405
- details.
631
+ ## License
632
+ Sprockets is released under the [MIT License](MIT-LICENSE).