public
Description: JavaScript and CSS dependency manager for Rails projects
Homepage:
Clone URL: git://github.com/jcoglan/holly.git
holly / README
100644 154 lines (112 sloc) 6.341 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
== Holly
 
Holly is an automated dependency manager for JavaScript and CSS assets in Ruby on Rails
projects. Its name is 'Holly', as in 'the holly and the ivy', Ivy being a Java-based
dependency manager. It was begun just after Christmas and I had to call it _something_.
 
Copyright (c) 2008 James Coglan, released under the MIT license
 
=== The problem
 
You're building part of your site, which has a little bit of script on the page. Something
to the effect of:
 
  var myWidget = new Widget('elementID');
 
To implement that, you know you need to include the .js file for +Widget+, so you put this
in the document's head:
 
  <%= javascript_include_tag 'widget' %>
 
What you don't know (and what I don't think you should need to know) is that +Widget+
uses <tt>dragdrop.js</tt>, which itself relies on <tt>effects.js</tt>, which again relies on
<tt>prototype.js</tt>. Holly allows each script/css file to declare its dependencies using
special comments. Whenever you use +javascript_include_tag+ or +stylesheet_link_tag+,
Holly examines the file's dependencies and makes sure they are included into your HTML,
in the correct order and without duplication. This allows all script files to make sure
they will run properly when loaded, and to load additional script files and stylesheets
without the template author needing to know which files to add to the page.
 
=== How to use
 
Let's say our +Widget+ class lives in <tt>widget.js</tt>. It has two other classes it uses;
<tt>Widget.Item</tt> in <tt>widget/item.js</tt> and <tt>Widget.Page</tt> in
<tt>widget/page.js</tt>. These classes should be loaded after +Widget+. It needs
<tt>dragdrop.js</tt> to be loaded first, and it also has a stylesheet associated with it,
called <tt>widget.css</tt>. Add the following lines to the top of <tt>widget.js</tt>:
 
  // @require dragdrop
  // @load widget/item
  // @load widget/page
  // @load widget.css
 
<tt>dragdrop.js</tt> has it own dependencies. Add this line to <tt>dragdrop.js</tt>:
 
  // @require effects
 
and this line to <tt>effects.js</tt>:
 
  // @require prototype
 
You can also use <tt>/*</tt> comment syntax - as long as the line begins with a comment
opening, it will be parsed by Holly.
 
Now, when you call <tt>javascript_include_tag 'widget'</tt>, you'll get:
 
  <script src="/javascripts/prototype.js" type="text/javascript"></script>
  <script src="/javascripts/effects.js" type="text/javascript"></script>
  <script src="/javascripts/dragdrop.js" type="text/javascript"></script>
  <script src="/javascripts/widget.js" type="text/javascript"></script>
  <script src="/javascripts/widget/item.js" type="text/javascript"></script>
  <script src="/javascripts/widget/page.js" type="text/javascript"></script>
  <link href="/stylesheets/widget.css" media="screen" rel="stylesheet" type="text/css" />
 
If any of these assets have already been rendered to the page, they will be omitted;
Holly will not allow +javascript_include_tag+ or +stylesheet_link_tag+ to render any
asset more than once per request.
 
=== <tt>@require</tt> vs. <tt>@load</tt>
 
<tt>@require</tt> means that the given file _must_ be loaded before the current file.
<tt>@load</tt> means that the given file should be loaded after the current file. Files
are rendered to the page as early as they are <tt>require</tt>d, and as late as they
are <tt>load</tt>ed.
 
=== Source resolution
 
It may help you to know how Holly resolves paths to files you +require+ or +load+. Follow
these rules and you shouldn't go wrong:
 
* Remote URLs: these are left unmodified unless they lack a file extension. <tt>.js</tt>
  is added if the URL is within a JavaScript file, <tt>.css</tt> if within a CSS file.
  
* Absolute paths: these are also left untouched unless they lack a file extension. If
  the path begins with <tt>/javascripts/</tt>, a <tt>.js</tt> extension is added. If
  the path begins with <tt>/stylesheets/</tt>, a <tt>.css</tt> extension is added.
  Otherwise, an extension is added based on which type of file is making the +require+ or
  +load+ call.
  
* Relative paths: these are resolved relative to <tt>/javascripts/</tt> or <tt>/stylesheets/</tt>.
  If the given filename has an extension, that extension is used to determine the directory.
  For example, if you <tt>@require widget/item.js</tt>, that will always look for
  <tt>/javascripts/widget/item.js</tt>, whether you call <tt>@require</tt> from a
  JavaScript or a CSS file. If no extension is present, Holly assumes that you want
  a <tt>.js</tt> file if the current file is <tt>.js</tt>, and a <tt>.css</tt> if
  the current file is <tt>.css</tt>.
 
=== Rake tasks
 
Holly provides some rake tasks for inspecting the dependencies of the script/css
files in your project. Just run <tt>rake holly:inspect q=somefile</tt> to see a report
on its dependencies. For example:
 
  > rake holly:inspect q=effects.js
  
      Requires:
            /javascripts/prototype.js
      
      Loads:
            (none)
      
      Full expansion:
            /javascripts/prototype.js
        -> /javascripts/effects.js
      
      Referring files:
            /javascripts/dragdrop.js
      
      Dependants:
            /javascripts/dragdrop.js
            /javascripts/widget.js
  
  > rake holly:inspect q=widget.js
  
      Requires:
            /javascripts/dragdrop.js
      
      Loads:
            /javascripts/widget/item.js
            /javascripts/widget/page.js
        ! /stylesheets/widget.css
      
      Full expansion:
            /javascripts/prototype.js
            /javascripts/effects.js
            /javascripts/dragdrop.js
        -> /javascripts/widget.js
            /javascripts/widget/item.js
            /javascripts/widget/page.js
        ! /stylesheets/widget.css
      
      Referring files:
            (none)
      
      Dependants:
            (none)
 
+Requires+ and +Loads+ list the files directly referenced by +somefile+. <tt>Full
expansion</tt> shows the full list of assets loaded by Holly when you include +somefile+
in one of your pages, in order. <tt>-></tt> indicates +somefile+ in the list. In all
these lists, a <tt>!</tt> next to a filename indicates that the file is missing.
<tt>Referring files</tt> lists all the files that contain direct references to
+somefile+, and +Dependants+ lists any files whose full expansion contains references
to +somefile+.