Skip to content
This repository has been archived by the owner on Jun 10, 2018. It is now read-only.

Commit

Permalink
Add stub directive
Browse files Browse the repository at this point in the history
Fixes #202
  • Loading branch information
josh committed Dec 8, 2011
1 parent 5cac319 commit 95ae9b7
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 12 deletions.
12 changes: 11 additions & 1 deletion lib/sprockets/context.rb
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions lib/sprockets/directive_processor.rb
Expand Up @@ -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
Expand Down
26 changes: 15 additions & 11 deletions lib/sprockets/processed_asset.rb
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/asset/stub/application.js
@@ -0,0 +1,3 @@
//= require ./jquery
//= require ./foo
//= stub ./frameworks
1 change: 1 addition & 0 deletions test/fixtures/asset/stub/foo.js
@@ -0,0 +1 @@
var Foo = {};
2 changes: 2 additions & 0 deletions test/fixtures/asset/stub/frameworks.js
@@ -0,0 +1,2 @@
//= require ./jquery
//= require ./jquery-ui
2 changes: 2 additions & 0 deletions test/fixtures/asset/stub/jquery-ui.js
@@ -0,0 +1,2 @@
//= require ./jquery
var jQuery.UI = {};
1 change: 1 addition & 0 deletions test/fixtures/asset/stub/jquery.js
@@ -0,0 +1 @@
var jQuery = {};
2 changes: 2 additions & 0 deletions test/fixtures/asset/stub/skip_jquery.js
@@ -0,0 +1,2 @@
//= require ./jquery-ui
//= stub ./jquery
8 changes: 8 additions & 0 deletions test/test_asset.rb
Expand Up @@ -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")
Expand Down

8 comments on commit 95ae9b7

@romanbsd
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@radar
Copy link

@radar radar commented on 95ae9b7 Jun 27, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@jerefrer
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@pehrlich
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be made to work with directories as well?

@agrobbin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on this working with directories

@benjaminws
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

stub is confusing and doesn't express intent.

@zires
Copy link

@zires zires commented on 95ae9b7 Nov 13, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.