This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Add `stub` directive

Fixes #202
  • Loading branch information...
josh committed Dec 8, 2011
1 parent 5cac319 commit 95ae9b78ec3e20978bfff56c7df8ea53930967f9
View
@@ -22,7 +22,8 @@ module Sprockets
# assets. See `DirectiveProcessor` for an example of this.
class Context
attr_reader :environment, :pathname
- attr_reader :_required_paths, :_dependency_paths, :_dependency_assets
+ attr_reader :_required_paths, :_stubbed_assets
+ attr_reader :_dependency_paths, :_dependency_assets
attr_writer :__LINE__
def initialize(environment, logical_path, pathname)
@@ -32,6 +33,7 @@ def initialize(environment, logical_path, pathname)
@__LINE__ = nil
@_required_paths = []
+ @_stubbed_assets = Set.new
@_dependency_paths = Set.new
@_dependency_assets = Set.new([pathname.to_s])
end
@@ -143,6 +145,14 @@ def require_asset(path)
nil
end
+ # `stub_asset` blacklists `path` from being included in the bundle.
+ # `path` must be an asset which may or may not already be included
+ # in the bundle.
+ def stub_asset(path)
+ @_stubbed_assets << resolve(path, :content_type => :self).to_s
+ nil
+ end
+
# Tests if target path is able to be safely required into the
# current concatenation.
def asset_requirable?(path)
@@ -340,6 +340,18 @@ def process_depend_on_asset_directive(path)
context.depend_on_asset(path)
end
+ # Allows dependency to be excluded from the asset bundle.
+ #
+ # The `path` must be a valid asset and may or may not already
+ # be part of the bundle. Once stubbed, it is blacklisted and
+ # can't be brought back by any other `require`.
+ #
+ # //= stub "jquery"
+ #
+ def process_stub_directive(path)
+ context.stub_asset(path)
+ end
+
# Enable Sprockets 1.x compat mode.
#
# Makes it possible to use the same JavaScript source
@@ -94,27 +94,31 @@ def hash
private
def build_required_assets(environment, context)
- @required_assets = []
- required_assets_cache = {}
+ @required_assets = resolve_dependencies(environment, context._required_paths + [pathname.to_s]) -
+ resolve_dependencies(environment, context._stubbed_assets.to_a)
+ end
+
+ def resolve_dependencies(environment, paths)
+ assets = []
+ cache = {}
- (context._required_paths + [pathname.to_s]).each do |path|
+ paths.each do |path|
if path == self.pathname.to_s
- unless required_assets_cache[self]
- required_assets_cache[self] = true
- @required_assets << self
+ unless cache[self]
+ cache[self] = true
+ assets << self
end
elsif asset = environment.find_asset(path, :bundle => false)
asset.required_assets.each do |asset_dependency|
- unless required_assets_cache[asset_dependency]
- required_assets_cache[asset_dependency] = true
- @required_assets << asset_dependency
+ unless cache[asset_dependency]
+ cache[asset_dependency] = true
+ assets << asset_dependency
end
end
end
end
- required_assets_cache.clear
- required_assets_cache = nil
+ assets
end
def build_dependency_paths(environment, context)
@@ -0,0 +1,3 @@
+//= require ./jquery
+//= require ./foo
+//= stub ./frameworks
@@ -0,0 +1 @@
+var Foo = {};
@@ -0,0 +1,2 @@
+//= require ./jquery
+//= require ./jquery-ui
@@ -0,0 +1,2 @@
+//= require ./jquery
+var jQuery.UI = {};
@@ -0,0 +1 @@
+var jQuery = {};
@@ -0,0 +1,2 @@
+//= require ./jquery-ui
+//= stub ./jquery
View
@@ -732,6 +732,14 @@ def setup
end
end
+ test "stub single dependency" do
+ assert_equal "var jQuery.UI = {};\n\n\n", asset("stub/skip_jquery").to_s
+ end
+
+ test "stub dependency tree" do
+ assert_equal "var Foo = {};\n\n\n\n", asset("stub/application").to_s
+ end
+
test "circular require raises an error" do
assert_raise(Sprockets::CircularDependencyError) do
asset("circle/a.js")

8 comments on commit 95ae9b7

@romanbsd

This comment has been minimized.

Show comment
Hide comment
@romanbsd

romanbsd Jan 13, 2012

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

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

@radar

This comment has been minimized.

Show comment
Hide comment
@radar

radar Jun 27, 2012

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

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

@jerefrer

This comment has been minimized.

Show comment
Hide comment
@jerefrer

jerefrer Jul 2, 2012

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

@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

This comment has been minimized.

Show comment
Hide comment
@williscool

williscool Jul 30, 2012

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

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

@pehrlich

This comment has been minimized.

Show comment
Hide comment
@pehrlich

pehrlich Oct 13, 2012

Can this be made to work with directories as well?

Can this be made to work with directories as well?

@agrobbin

This comment has been minimized.

Show comment
Hide comment
@agrobbin

agrobbin Oct 18, 2012

+1 on this working with directories

+1 on this working with directories

@benjaminws

This comment has been minimized.

Show comment
Hide comment
@benjaminws

benjaminws Nov 5, 2012

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

stub is confusing and doesn't express intent.

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

stub is confusing and doesn't express intent.

@zires

This comment has been minimized.

Show comment
Hide comment

👍

Please sign in to comment.