Skip to content
This repository was archived by the owner on Mar 23, 2024. It is now read-only.

Commit 25c47fe

Browse files
committed
Merge pull request #48 from jwhitley/issue/48
Support for CDN hosted assets
2 parents 6b4c964 + 5f1224e commit 25c47fe

File tree

5 files changed

+106
-6
lines changed

5 files changed

+106
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# v0.8.0
2+
3+
- Build will now substitute `empty:` for the right-hand side of
4+
`config/requirejs.yml` paths entries that are URLs.
5+
- Documented how to configure assets hosted on a CDN.
6+
17
# v0.7.3
28

39
- Upgrade RequireJS and r.js to v1.0.8

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,38 @@ This will generate a script tag like so:
186186
<script data-main="/assets/page1.js" data-foo="..." data-bar="..." src="/assets/require.js"></script>
187187
```
188188

189+
### External domain (CDN) support
190+
191+
There are two ways in which requirejs-rails supports the use of different
192+
domains for serving built JavaScript modules, as is the case when using
193+
a [CDN](http://en.wikipedia.org/wiki/Content_delivery_network).
194+
195+
1. URLs in paths config in `requirejs.yml`:
196+
197+
If requirejs-rails encounters an URL as the right-hand side of a paths
198+
configuration, it will correctly emit that as `"empty:"` during the build
199+
process so that [r.js will do the right thing](http://requirejs.org/docs/optimization.html#empty).
200+
201+
Example:
202+
203+
```yaml
204+
paths:
205+
jquery: "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
206+
```
207+
208+
2. Deploying all requirejs-rails assets to a CDN:
209+
210+
In `config/environments/production.rb` (or another environment)
211+
set the run_config as follows:
212+
213+
```ruby
214+
config.requirejs.run_config['baseUrl'] = 'http://mycdn.example.com/12345abc/assets'
215+
```
216+
217+
The [`asset_sync` gem](https://github.com/rumblelabs/asset_sync) is one
218+
tool that can be used to deploy your built assets to a CDN (S3, in this
219+
case).
220+
189221
## Troubleshooting
190222

191223
### Avoid `config.assets.precompile`
@@ -196,7 +228,9 @@ javascript_include_tag, and which is **never** referenced by the AMD codebase.
196228

197229
## Using AMD libraries
198230

199-
I currently recommend placing your AMD libraries into `vendor/assets/javascripts`. The needs of a few specific libraries are discussed below.
231+
I currently recommend placing your AMD libraries into
232+
`vendor/assets/javascripts`. The needs of a few specific libraries are
233+
discussed below.
200234

201235
### jQuery
202236

app/helpers/requirejs_helper.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ def requirejs_include_tag(name=nil, &block)
5454
paths = {}
5555
modules.each { |m| paths[m] = _javascript_path(m).sub /\.js$/,'' }
5656

57-
# Override uesr paths, whose mappings are only relevant in dev mode
57+
# Add paths for assets specified by full URL (on a CDN)
58+
run_config['paths'].each { |k,v| paths[k] = v if v =~ /^https?:/ }
59+
60+
# Override user paths, whose mappings are only relevant in dev mode
5861
# and in the build_config.
5962
run_config['paths'] = paths
6063
end

lib/requirejs/rails/config.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,17 @@ def build_config
108108
mod['name'] = 'almond'
109109
mod['include'] = name
110110
end
111+
self.rewrite_urls_in_paths self[:build_config]
111112
end
112113
self[:build_config]
113114
end
114115

115116
def run_config
116-
run_config = { "baseUrl" => "/assets" }
117-
run_config.merge!(self.user_config).slice(*self.run_config_whitelist)
117+
unless self.has_key?(:run_config)
118+
self[:run_config] = { "baseUrl" => "/assets" }
119+
self[:run_config].merge!(self.user_config).slice!(*self.run_config_whitelist)
120+
end
121+
self[:run_config]
118122
end
119123

120124
def user_config=(cfg)
@@ -146,5 +150,13 @@ def asset_allowed?(asset)
146150
accum || (matcher =~ asset)
147151
end ? true : false
148152
end
153+
154+
def rewrite_urls_in_paths(cfg)
155+
if cfg.has_key? 'paths'
156+
cfg['paths'] = cfg['paths'].each_with_object({}) do |(k, v), h|
157+
h[k] = (v =~ /^https?:/) ? 'empty:' : v
158+
end
159+
end
160+
end
149161
end
150162
end

test/requirejs-rails_test.rb

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def setup
5151

5252
test "user_config should reject baseUrl" do
5353
exc = assert_raises Requirejs::ConfigError do
54-
@cfg.user_config = { "baseUrl" => "/frobnitz" }
54+
@cfg.user_config = { 'baseUrl' => '/frobnitz' }
5555
end
5656
assert_match /baseUrl is not needed/, exc.message
5757
end
@@ -63,6 +63,11 @@ def setup
6363
assert_equal 'lib/jquery-1.7.2.min', @cfg.run_config['paths']['jquery']
6464
end
6565

66+
test "run_config should allow settings to be overridden" do
67+
@cfg.run_config['baseUrl'] = 'http://cdn.example.com/assets'
68+
assert_equal 'http://cdn.example.com/assets', @cfg.run_config['baseUrl']
69+
end
70+
6671
test "build_config should inherit user_config settings" do
6772
@cfg.user_config = { 'paths' => { 'jquery' => 'lib/jquery-1.7.2.min' } }
6873
refute_nil @cfg.build_config['paths']
@@ -80,7 +85,27 @@ def setup
8085
assert_nil @cfg.build_config['priority']
8186
end
8287

83-
## Almond tests
88+
test "build config should replace urls in paths with 'empty:'" do
89+
@cfg.user_config = { 'paths' =>
90+
{
91+
'jquery' => 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',
92+
'jqueryssl' => 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'
93+
}
94+
}
95+
assert_equal 'empty:', @cfg.build_config['paths']['jquery']
96+
assert_equal 'empty:', @cfg.build_config['paths']['jqueryssl']
97+
end
98+
99+
test "build_config should not modify non-urls in paths" do
100+
@cfg.user_config = { 'paths' =>
101+
{
102+
'foo' => 'components/foo'
103+
}
104+
}
105+
assert_equal 'components/foo', @cfg.build_config['paths']['foo']
106+
end
107+
108+
## Almond-specific tests
84109
test "build_config with almond should accept one module" do
85110
@cfg.loader = :almond
86111
@cfg.user_config = { 'modules' => [ { 'name' => 'foo' } ] }
@@ -101,6 +126,10 @@ class RequirejsHelperTest < ActionView::TestCase
101126

102127
def setup
103128
controller.requirejs_included = false
129+
Rails.application.config.requirejs.user_config = { 'paths' =>
130+
{ 'jquery' => 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' }
131+
}
132+
104133
end
105134

106135
def wrap(tag)
@@ -133,4 +162,20 @@ def wrap(tag)
133162
render :text => "#{requirejs_include_tag}\n#{requirejs_include_tag}"
134163
end
135164
end
165+
166+
test "requirejs_include_tag with CDN asset in paths" do
167+
render :text => wrap(requirejs_include_tag)
168+
assert_select "script:first-of-type", :text => %r{var require =.*paths.*http://ajax}
169+
end
170+
171+
test "requirejs_include_tag with CDN asset and digested asset paths" do
172+
begin
173+
saved_digest = Rails.application.config.assets.digest
174+
Rails.application.config.assets.digest = true
175+
render :text => wrap(requirejs_include_tag)
176+
assert_select "script:first-of-type", :text => %r{var require =.*paths.*http://ajax}
177+
ensure
178+
Rails.application.config.assets.digest = saved_digest
179+
end
180+
end
136181
end

0 commit comments

Comments
 (0)