Skip to content
This repository
Browse code

Add `stub` directive

Fixes #202
  • Loading branch information...
commit 95ae9b78ec3e20978bfff56c7df8ea53930967f9 1 parent 5cac319
Joshua Peek authored December 08, 2011
12  lib/sprockets/context.rb
@@ -22,7 +22,8 @@ module Sprockets
22 22
   # assets. See `DirectiveProcessor` for an example of this.
23 23
   class Context
24 24
     attr_reader :environment, :pathname
25  
-    attr_reader :_required_paths, :_dependency_paths, :_dependency_assets
  25
+    attr_reader :_required_paths, :_stubbed_assets
  26
+    attr_reader :_dependency_paths, :_dependency_assets
26 27
     attr_writer :__LINE__
27 28
 
28 29
     def initialize(environment, logical_path, pathname)
@@ -32,6 +33,7 @@ def initialize(environment, logical_path, pathname)
32 33
       @__LINE__     = nil
33 34
 
34 35
       @_required_paths    = []
  36
+      @_stubbed_assets    = Set.new
35 37
       @_dependency_paths  = Set.new
36 38
       @_dependency_assets = Set.new([pathname.to_s])
37 39
     end
@@ -143,6 +145,14 @@ def require_asset(path)
143 145
       nil
144 146
     end
145 147
 
  148
+    # `stub_asset` blacklists `path` from being included in the bundle.
  149
+    # `path` must be an asset which may or may not already be included
  150
+    # in the bundle.
  151
+    def stub_asset(path)
  152
+      @_stubbed_assets << resolve(path, :content_type => :self).to_s
  153
+      nil
  154
+    end
  155
+
146 156
     # Tests if target path is able to be safely required into the
147 157
     # current concatenation.
148 158
     def asset_requirable?(path)
12  lib/sprockets/directive_processor.rb
@@ -340,6 +340,18 @@ def process_depend_on_asset_directive(path)
340 340
         context.depend_on_asset(path)
341 341
       end
342 342
 
  343
+      # Allows dependency to be excluded from the asset bundle.
  344
+      #
  345
+      # The `path` must be a valid asset and may or may not already
  346
+      # be part of the bundle. Once stubbed, it is blacklisted and
  347
+      # can't be brought back by any other `require`.
  348
+      #
  349
+      #     //= stub "jquery"
  350
+      #
  351
+      def process_stub_directive(path)
  352
+        context.stub_asset(path)
  353
+      end
  354
+
343 355
       # Enable Sprockets 1.x compat mode.
344 356
       #
345 357
       # Makes it possible to use the same JavaScript source
26  lib/sprockets/processed_asset.rb
@@ -94,27 +94,31 @@ def hash
94 94
 
95 95
     private
96 96
       def build_required_assets(environment, context)
97  
-        @required_assets = []
98  
-        required_assets_cache = {}
  97
+        @required_assets = resolve_dependencies(environment, context._required_paths + [pathname.to_s]) -
  98
+          resolve_dependencies(environment, context._stubbed_assets.to_a)
  99
+      end
  100
+
  101
+      def resolve_dependencies(environment, paths)
  102
+        assets = []
  103
+        cache  = {}
99 104
 
100  
-        (context._required_paths + [pathname.to_s]).each do |path|
  105
+        paths.each do |path|
101 106
           if path == self.pathname.to_s
102  
-            unless required_assets_cache[self]
103  
-              required_assets_cache[self] = true
104  
-              @required_assets << self
  107
+            unless cache[self]
  108
+              cache[self] = true
  109
+              assets << self
105 110
             end
106 111
           elsif asset = environment.find_asset(path, :bundle => false)
107 112
             asset.required_assets.each do |asset_dependency|
108  
-              unless required_assets_cache[asset_dependency]
109  
-                required_assets_cache[asset_dependency] = true
110  
-                @required_assets << asset_dependency
  113
+              unless cache[asset_dependency]
  114
+                cache[asset_dependency] = true
  115
+                assets << asset_dependency
111 116
               end
112 117
             end
113 118
           end
114 119
         end
115 120
 
116  
-        required_assets_cache.clear
117  
-        required_assets_cache = nil
  121
+        assets
118 122
       end
119 123
 
120 124
       def build_dependency_paths(environment, context)
3  test/fixtures/asset/stub/application.js
... ...
@@ -0,0 +1,3 @@
  1
+//= require ./jquery
  2
+//= require ./foo
  3
+//= stub ./frameworks
1  test/fixtures/asset/stub/foo.js
... ...
@@ -0,0 +1 @@
  1
+var Foo = {};
2  test/fixtures/asset/stub/frameworks.js
... ...
@@ -0,0 +1,2 @@
  1
+//= require ./jquery
  2
+//= require ./jquery-ui
2  test/fixtures/asset/stub/jquery-ui.js
... ...
@@ -0,0 +1,2 @@
  1
+//= require ./jquery
  2
+var jQuery.UI = {};
1  test/fixtures/asset/stub/jquery.js
... ...
@@ -0,0 +1 @@
  1
+var jQuery = {};
2  test/fixtures/asset/stub/skip_jquery.js
... ...
@@ -0,0 +1,2 @@
  1
+//= require ./jquery-ui
  2
+//= stub ./jquery
8  test/test_asset.rb
@@ -732,6 +732,14 @@ def setup
732 732
     end
733 733
   end
734 734
 
  735
+  test "stub single dependency" do
  736
+    assert_equal "var jQuery.UI = {};\n\n\n", asset("stub/skip_jquery").to_s
  737
+  end
  738
+
  739
+  test "stub dependency tree" do
  740
+    assert_equal "var Foo = {};\n\n\n\n", asset("stub/application").to_s
  741
+  end
  742
+
735 743
   test "circular require raises an error" do
736 744
     assert_raise(Sprockets::CircularDependencyError) do
737 745
       asset("circle/a.js")

8 notes on commit 95ae9b7

Roman Shterenzon

Nice!! Why didn't you call it blacklist then?

Ryan Bigg
radar commented on 95ae9b7 June 26, 2012

Why wasn't this added to the asset pipeline guide for Rails? Could be something people are interested in.

Jérémy FRERE

@radar : Because it seems that Rails is not yet using sprockets > 2.1.3 ... I just asked them why here. Feel free to +1 :)

williscool

What made you chose the name "stub" for this method?

Peter Ehrlich

Can this be made to work with directories as well?

Alex Robbin

+1 on this working with directories

Benjamin W. Smith

+1 to working with directories, -1 to the name stub

stub is confusing and doesn't express intent.

Please sign in to comment.
Something went wrong with that request. Please try again.