diff --git a/Gemfile b/Gemfile
index 1f00b8752..532cca3f4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,3 +9,13 @@ gem "rubocop", ">= 0.47", require: false
group :test do
gem "minitest", "~> 5.0"
end
+
+if ENV["USE_PRY"]
+ gem "awesome_print"
+ gem "pry"
+ gem "pry-byebug"
+ gem "pry-doc"
+ gem "pry-rails"
+ gem "pry-rescue"
+ gem "pry-stack_explorer"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index fb75154fa..f49deed5b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -48,12 +48,19 @@ GEM
tzinfo (~> 1.1)
arel (7.1.4)
ast (2.3.0)
+ awesome_print (1.8.0)
+ binding_of_caller (0.7.2)
+ debug_inspector (>= 0.0.1)
builder (3.2.3)
+ byebug (9.0.6)
+ coderay (1.1.1)
concurrent-ruby (1.0.5)
+ debug_inspector (0.0.3)
erubis (2.7.0)
globalid (0.3.7)
activesupport (>= 4.1.0)
i18n (0.8.1)
+ interception (0.5)
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.4)
@@ -71,6 +78,24 @@ GEM
parser (2.4.0.0)
ast (~> 2.2)
powerpack (0.1.1)
+ pry (0.10.4)
+ coderay (~> 1.1.0)
+ method_source (~> 0.8.1)
+ slop (~> 3.4)
+ pry-byebug (3.4.2)
+ byebug (~> 9.0)
+ pry (~> 0.10)
+ pry-doc (0.10.0)
+ pry (~> 0.9)
+ yard (~> 0.9)
+ pry-rails (0.3.6)
+ pry (>= 0.10.4)
+ pry-rescue (1.4.5)
+ interception (>= 0.5)
+ pry
+ pry-stack_explorer (0.4.9.2)
+ binding_of_caller (>= 0.7)
+ pry (>= 0.9.11)
rack (2.0.1)
rack-test (0.6.3)
rack (>= 1.0)
@@ -106,6 +131,7 @@ GEM
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1)
+ slop (3.6.0)
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
@@ -121,17 +147,25 @@ GEM
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
+ yard (0.9.9)
PLATFORMS
ruby
DEPENDENCIES
+ awesome_print
bundler (~> 1.12)
minitest (~> 5.0)
+ pry
+ pry-byebug
+ pry-doc
+ pry-rails
+ pry-rescue
+ pry-stack_explorer
rails
rake (>= 11.1)
rubocop (>= 0.47)
webpacker!
BUNDLED WITH
- 1.14.6
+ 1.15.3
diff --git a/README.md b/README.md
index 60c079ff6..2433bd2fd 100644
--- a/README.md
+++ b/README.md
@@ -367,8 +367,14 @@ development:
host: 0.0.0.0
port: 8080
https: false
+ hot: false
```
+If you have hot turned to `true`, then the `stylesheet_pack_tag` generates no output, as you will want
+to configure your styles to be inlined in your JavaScript for hot reloading. During production and testing, the
+`stylesheet_pack_tag` will create the appropriate HTML tags.
+
+
#### Resolved Paths
If you are adding webpacker to an existing app that has most of the assets inside
@@ -601,8 +607,12 @@ and
#### React
-You may consider using [react-rails](https://github.com/reactjs/react-rails) or
-[webpacker-react](https://github.com/renchap/webpacker-react) for more advanced react integration. However here is how you can do it yourself:
+The most widely used React integration is [shakacode/react_on_rails](https://github.com/shakacode/react_on_rails) which includes support for server rendering, redux and react-router.
+
+Other alternatives include [react-rails](https://github.com/reactjs/react-rails) and
+[webpacker-react](https://github.com/renchap/webpacker-react) for more advanced react integration.
+
+If you're not concerned with view helpers to pass props or server rendering, can do it yourself:
```erb
<%# views/layouts/application.html.erb %>
@@ -1103,6 +1113,8 @@ git push heroku master
Webpacker lazily compiles assets in test env so you can write your tests without any extra
setup and everything will just work out of the box.
+Note, [React on Rails] users should set configuration value `compile` to false, as React on Rails
+handle compilation for test and production environments.
Here is a sample system test case with hello_react example component:
diff --git a/lib/install/config/webpack/shared.js b/lib/install/config/webpack/shared.js
index 45abc33b6..8b25115df 100644
--- a/lib/install/config/webpack/shared.js
+++ b/lib/install/config/webpack/shared.js
@@ -28,7 +28,6 @@ module.exports = {
output: {
filename: '[name].js',
path: output.path,
- publicPath: output.publicPath
},
module: {
@@ -39,7 +38,6 @@ module.exports = {
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
new ManifestPlugin({
- publicPath: output.publicPath,
writeToFileEmit: true
})
],
diff --git a/lib/install/config/webpacker.yml b/lib/install/config/webpacker.yml
index b670ae4cd..15df260f7 100644
--- a/lib/install/config/webpacker.yml
+++ b/lib/install/config/webpacker.yml
@@ -34,6 +34,7 @@ development:
host: localhost
port: 8080
https: false
+ hot: false
test:
<<: *default
diff --git a/lib/webpacker.rb b/lib/webpacker.rb
index 2a2791634..db55fe0bf 100644
--- a/lib/webpacker.rb
+++ b/lib/webpacker.rb
@@ -2,14 +2,15 @@ module Webpacker
extend self
def bootstrap
- Webpacker::Env.load
- Webpacker::Configuration.load
- Webpacker::Manifest.load
+ Webpacker::Env.load_instance
+ Webpacker::Configuration.load_instance
+ Webpacker::DevServer.load_instance
+ Webpacker::Manifest.load_instance
end
def compile
Webpacker::Compiler.compile
- Webpacker::Manifest.load
+ Webpacker::Manifest.load_instance
end
def env
@@ -19,6 +20,7 @@ def env
require "webpacker/env"
require "webpacker/configuration"
+require "webpacker/dev_server"
require "webpacker/manifest"
require "webpacker/compiler"
require "webpacker/railtie" if defined?(Rails)
diff --git a/lib/webpacker/configuration.rb b/lib/webpacker/configuration.rb
index b20808d9e..edd5e102a 100644
--- a/lib/webpacker/configuration.rb
+++ b/lib/webpacker/configuration.rb
@@ -4,12 +4,21 @@
class Webpacker::Configuration < Webpacker::FileLoader
class << self
+ def reset
+ @defaults = nil
+ super
+ end
+
def entry_path
source_path.join(fetch(:source_entry_path))
end
+ def public_output_path
+ fetch(:public_output_path)
+ end
+
def output_path
- public_path.join(fetch(:public_output_path))
+ public_path.join(public_output_path)
end
def manifest_path
@@ -45,19 +54,30 @@ def fetch(key)
end
def data
- load if Webpacker.env.development?
- raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load must be called first") unless instance
+ load_instance if Webpacker.env.development?
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load_data must be called first") unless instance
instance.data
end
def defaults
@defaults ||= HashWithIndifferentAccess.new(YAML.load(default_file_path.read)[Webpacker.env])
end
+
+ # Uses the webpack dev server host if appropriate
+ def output_path_or_url
+ if Webpacker::DevServer.dev_server?
+ Webpacker::DevServer.base_url
+ else
+ # Ensure we start with a slash so that the asset helpers don't prepend the default asset
+ # pipeline locations.
+ public_output_path.starts_with?("/") ? public_output_path : "/#{public_output_path}"
+ end
+ end
end
private
- def load
- return super unless File.exist?(@path)
+ def load_data
+ return Webpacker::Configuration.defaults unless File.exist?(@path)
HashWithIndifferentAccess.new(YAML.load(File.read(@path))[Webpacker.env])
end
end
diff --git a/lib/webpacker/dev_server.rb b/lib/webpacker/dev_server.rb
new file mode 100644
index 000000000..ceb931026
--- /dev/null
+++ b/lib/webpacker/dev_server.rb
@@ -0,0 +1,78 @@
+# Same convention as manifest/configuration.rb
+
+# Loads webpacker configuration from config/webpacker.yml
+
+require "webpacker/configuration"
+
+class Webpacker::DevServer < Webpacker::FileLoader
+ class << self
+ def dev_server?
+ !dev_server_values.nil?
+ end
+
+ # read settings for dev_server
+ def hot?
+ return false unless dev_server?
+ if ENV["WEBPACKER_HMR"].present?
+ val = ENV["WEBPACKER_HMR"].downcase
+ return true if val == "true"
+ return false if val == "false"
+ raise new ArgumentError("WEBPACKER_HMR value is #{ENV['WEBPACKER_HMR']}. Set to TRUE|FALSE")
+ end
+ fetch(:hot)
+ end
+
+ def host
+ fetch(:host)
+ end
+
+ def port
+ fetch(:port)
+ end
+
+ def https?
+ fetch(:https)
+ end
+
+ def protocol
+ https? ? "https" : "http"
+ end
+
+ def file_path
+ Webpacker::Configuration.file_path
+ end
+
+ # Uses the hot_reloading_host if appropriate
+ def base_url
+ "#{protocol}://#{host}:#{port}"
+ end
+
+ private
+
+ def dev_server_values
+ data.fetch(:dev_server, nil)
+ end
+
+ def fetch(key)
+ return nil unless dev_server?
+ dev_server_values.fetch(key, dev_server_defaults[key])
+ end
+
+ def data
+ load_instance if Webpacker.env.development?
+ unless instance
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::DevServer.load_data must be called first")
+ end
+ instance.data
+ end
+
+ def dev_server_defaults
+ @defaults ||= Webpacker::Configuration.defaults[:dev_server]
+ end
+ end
+
+ private
+ def load_data
+ Webpacker::Configuration.instance.data
+ end
+end
diff --git a/lib/webpacker/env.rb b/lib/webpacker/env.rb
index f7a385e37..1f276e3bb 100644
--- a/lib/webpacker/env.rb
+++ b/lib/webpacker/env.rb
@@ -14,7 +14,7 @@ def file_path
end
private
- def load
+ def load_data
environments = File.exist?(@path) ? YAML.load(File.read(@path)).keys : [].freeze
return ENV["NODE_ENV"] if environments.include?(ENV["NODE_ENV"])
return Rails.env if environments.include?(Rails.env)
diff --git a/lib/webpacker/file_loader.rb b/lib/webpacker/file_loader.rb
index 8d478420b..ea01f7016 100644
--- a/lib/webpacker/file_loader.rb
+++ b/lib/webpacker/file_loader.rb
@@ -4,21 +4,44 @@ class NotFoundError < StandardError; end
class FileLoaderError < StandardError; end
class_attribute :instance
- attr_accessor :data
+ attr_accessor :data, :mtime, :path
class << self
- def load(path = file_path)
+ def load_instance(path = file_path)
+ # Assume production is 100% cached and don't reload if file's mtime not changed
+ cached = self.instance && # if we have a singleton
+ (env == "production" || # skip if production bc always cached
+ (File.exist?(path) && self.instance.mtime == File.mtime(path))) # skip if mtime not changed
+
+ return if cached
self.instance = new(path)
end
+
+ def file_path
+ raise FileLoaderError.new("Subclass of Webpacker::FileLoader should override this method")
+ end
+
+ def reset
+ self.instance = nil
+ load_instance
+ end
+
+ private
+
+ # Prefer the NODE_ENV to the rails env.
+ def env
+ ENV["NODE_ENV"].presence || Rails.env
+ end
end
private
def initialize(path)
@path = path
- @data = load
+ @mtime = File.exist?(path) ? File.mtime(path) : nil
+ @data = load_data
end
- def load
+ def load_data
{}.freeze
end
end
diff --git a/lib/webpacker/helper.rb b/lib/webpacker/helper.rb
index e90997e41..f707e25f1 100644
--- a/lib/webpacker/helper.rb
+++ b/lib/webpacker/helper.rb
@@ -9,8 +9,12 @@ module Webpacker::Helper
# In production mode:
# <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
def asset_pack_path(name, **options)
- asset_path(Webpacker::Manifest.lookup(name), **options)
+ path = Webpacker::Configuration.public_output_path
+ file = Webpacker::Manifest.lookup(name)
+ full_path = "#{path}/#{file}"
+ asset_path(full_path, **options)
end
+
# Creates a script tag that references the named pack file, as compiled by Webpack per the entries list
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
@@ -25,8 +29,7 @@ def asset_pack_path(name, **options)
# <%= javascript_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
#
def javascript_pack_tag(*names, **options)
- sources = names.map { |name| Webpacker::Manifest.lookup("#{name}#{compute_asset_extname(name, type: :javascript)}") }
- javascript_include_tag(*sources, **options)
+ javascript_include_tag(*asset_source(names, :javascript), **options)
end
# Creates a link tag that references the named pack file, as compiled by Webpack per the entries list
@@ -42,8 +45,25 @@ def javascript_pack_tag(*names, **options)
# # In production mode:
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
#
+ # # In development mode with hot-reloading
+ # <%= stylesheet_pack_tag('main') %> <% # Default is false for enabled_when_hot_loading%>
+ # # No output
+ #
+ # # In development mode with hot-reloading and enabled_when_hot_loading
+ # # <%= stylesheet_pack_tag('main', enabled_when_hot_loading: true) %>
+ #
+ #
def stylesheet_pack_tag(*names, **options)
- sources = names.map { |name| Webpacker::Manifest.lookup("#{name}#{compute_asset_extname(name, type: :stylesheet)}") }
- stylesheet_link_tag(*sources, **options)
+ return "" if Webpacker::DevServer.hot?
+ stylesheet_link_tag(*asset_source(names, :stylesheet), **options)
end
+
+ private
+ def asset_source(names, type)
+ output_path_or_url = Webpacker::Configuration.output_path_or_url
+ names.map do |name|
+ path = Webpacker::Manifest.lookup("#{name}#{compute_asset_extname(name, type: type)}")
+ "#{output_path_or_url}/#{path}"
+ end
+ end
end
diff --git a/lib/webpacker/manifest.rb b/lib/webpacker/manifest.rb
index bcd1d9710..40a76004d 100644
--- a/lib/webpacker/manifest.rb
+++ b/lib/webpacker/manifest.rb
@@ -13,6 +13,10 @@ def file_path
Webpacker::Configuration.manifest_path
end
+ # Throws an error if the file is not found. If Configuration.compile? then compilation is invoked
+ # the file is missing.
+ # React on Rails users will need to set Configuration.compile? to false as compilation is configured
+ # in the package.json for React on Rails.
def lookup(name)
if Webpacker::Configuration.compile?
compile_and_find!(name)
@@ -21,24 +25,76 @@ def lookup(name)
end
end
+ # Why does this method exist? Testing? It's not in the README
def lookup_path(name)
- Rails.root.join(File.join(Webpacker::Configuration.public_path, lookup(name)))
+ Rails.root.join(File.join(Webpacker::Configuration.output_path, lookup(name)))
end
- private
- def find!(name)
- raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Manifest.load must be called first") unless instance
- instance.data[name.to_s] || raise(Webpacker::FileLoader::NotFoundError.new("Can't find #{name} in #{file_path}. Is webpack still compiling?"))
+ # Helper method to determine if the manifest file exists. Maybe Webpack needs to run?
+ # **Used by React on Rails.**
+ def exist?
+ path_object = Webpacker::Configuration.manifest_path
+ path_object.exist?
+ end
+
+ # Find the real file name from the manifest key. Don't throw an error if the file is simply
+ # missing from the manifest. Return nil in that case.
+ # If no manifest file exists, then throw an error.
+ # **Used by React on Rails.**
+ def lookup_no_throw(name)
+ instance.confirm_manifest_exists
+
+ load_instance
+ unless instance
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Manifest.load must be called first")
end
+ instance.data[name.to_s]
+ end
- def compile_and_find!(name)
- Webpacker.compile
- find!(name)
+ private
+ def find!(name)
+ unless instance
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Manifest.load must be called first")
end
+ instance.data[name.to_s] || missing_file_from_manifest_error(name)
+ end
+
+ def missing_file_from_manifest_error(bundle_name)
+ msg = <<-MSG
+ Webpacker can't find #{bundle_name} in your manifest at #{file_path}. Possible causes:
+ 1. You are hot reloading.
+ 2. You want to set Configuration.compile to true for your environment.
+ 3. Webpack has not re-run to reflect updates.
+ 4. You have misconfigured Webpacker's config/webpacker.yml file.
+ 5. Your Webpack configuration is not creating a manifest.
+ MSG
+ raise(Webpacker::FileLoader::NotFoundError.new(msg))
+ end
+
+ def missing_manifest_file_error(path_object)
+ msg = <<-MSG
+ Webpacker can't find the manifest file: #{path_object}
+ Possible causes:
+ 1. You have not invoked webpack.
+ 2. You have misconfigured Webpacker's config/webpacker_.yml file.
+ 3. Your Webpack configuration is not creating a manifest.
+ MSG
+ raise(Webpacker::FileLoader::NotFoundError.new(msg))
+ end
+
+ def compile_and_find!(name)
+ Webpacker.compile
+ find!(name)
+ end
+ end
+
+ def confirm_manifest_exists
+ raise missing_manifest_file_error(@path) unless File.exist?(@path)
end
private
- def load
+
+ def load_data
return super unless File.exist?(@path)
JSON.parse(File.read(@path))
end
diff --git a/test/configuration_test.rb b/test/configuration_test.rb
index c6d55da5a..f2b23cdee 100644
--- a/test/configuration_test.rb
+++ b/test/configuration_test.rb
@@ -3,31 +3,31 @@
class ConfigurationTest < Minitest::Test
def test_entry_path
entry_path = File.join(File.dirname(__FILE__), "test_app/app/javascript", "packs").to_s
- assert_equal Webpacker::Configuration.entry_path.to_s, entry_path
+ assert_equal entry_path, Webpacker::Configuration.entry_path.to_s
end
def test_file_path
file_path = File.join(File.dirname(__FILE__), "test_app/config", "webpacker.yml").to_s
- assert_equal Webpacker::Configuration.file_path.to_s, file_path
+ assert_equal file_path, Webpacker::Configuration.file_path.to_s
end
def test_manifest_path
manifest_path = File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
- assert_equal Webpacker::Configuration.manifest_path.to_s, manifest_path
+ assert_equal manifest_path, Webpacker::Configuration.manifest_path.to_s
end
def test_output_path
output_path = File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
- assert_equal Webpacker::Configuration.output_path.to_s, output_path
+ assert_equal output_path, Webpacker::Configuration.output_path.to_s
end
def test_source
- assert_equal Webpacker::Configuration.source.to_s, "app/javascript"
+ assert_equal "app/javascript", Webpacker::Configuration.source.to_s
end
def test_source_path
source_path = File.join(File.dirname(__FILE__), "test_app/app/javascript").to_s
- assert_equal Webpacker::Configuration.source_path.to_s, source_path
+ assert_equal source_path, Webpacker::Configuration.source_path.to_s
end
def test_compile?
diff --git a/test/dev_server_test.rb b/test/dev_server_test.rb
new file mode 100644
index 000000000..5c59dacbb
--- /dev/null
+++ b/test/dev_server_test.rb
@@ -0,0 +1,56 @@
+require "webpacker_test"
+
+class DevServerTest < Minitest::Test
+ require "webpacker_test"
+
+ def check_assertion
+ stub_value = ActiveSupport::StringInquirer.new("development")
+ Webpacker.stub(:env, stub_value) do
+ Webpacker::Configuration.reset
+ Webpacker::DevServer.reset
+ result = yield
+ assert_equal(result[0], result[1])
+ end
+ Webpacker::Configuration.reset
+ Webpacker::DevServer.reset
+ end
+
+ def test_dev_server?
+ check_assertion { [true, Webpacker::DevServer.dev_server?] }
+ end
+
+ def test_dev_server_host
+ check_assertion { ["localhost", Webpacker::DevServer.host] }
+ end
+
+ def test_dev_server_port
+ check_assertion { [8080, Webpacker::DevServer.port] }
+ end
+
+ def test_dev_server_hot?
+ check_assertion { [false, Webpacker::DevServer.hot?] }
+
+ ENV.stub(:[], "TRUE") do
+ check_assertion { [true, Webpacker::DevServer.hot?] }
+ end
+
+ ENV.stub(:[], "FALSE") do
+ check_assertion { [false, Webpacker::DevServer.hot?] }
+ end
+ ENV.stub(:[], "true") do
+ check_assertion { [true, Webpacker::DevServer.hot?] }
+ end
+ end
+
+ def test_dev_server_https?
+ check_assertion { [false, Webpacker::DevServer.https?] }
+ end
+
+ def test_dev_server_protocol?
+ check_assertion { ["http", Webpacker::DevServer.protocol] }
+ end
+
+ def test_base_url?
+ check_assertion { ["http://localhost:8080", Webpacker::DevServer.base_url] }
+ end
+end
diff --git a/test/helper_test.rb b/test/helper_test.rb
index 527968b24..1215581e6 100644
--- a/test/helper_test.rb
+++ b/test/helper_test.rb
@@ -7,29 +7,39 @@ def setup
end
def test_asset_pack_path
- assert_equal @view.asset_pack_path("bootstrap.js"), "/packs/bootstrap-300631c4f0e0f9c865bc.js"
- assert_equal @view.asset_pack_path("bootstrap.css"), "/packs/bootstrap-c38deda30895059837cf.css"
+ assert_equal "/packs/bootstrap-300631c4f0e0f9c865bc.js", @view.asset_pack_path("bootstrap.js")
+ assert_equal "/packs/bootstrap-c38deda30895059837cf.css", @view.asset_pack_path("bootstrap.css")
end
def test_javascript_pack_tag
script = %()
- assert_equal @view.javascript_pack_tag("bootstrap.js"), script
+ assert_equal script, @view.javascript_pack_tag("bootstrap.js")
end
def test_javascript_pack_tag_splat
script = %(\n) +
%()
- assert_equal @view.javascript_pack_tag("bootstrap.js", "application.js", defer: true), script
+ assert_equal script, @view.javascript_pack_tag("bootstrap.js", "application.js", defer: true)
end
def test_stylesheet_pack_tag
style = %()
- assert_equal @view.stylesheet_pack_tag("bootstrap.css"), style
+ assert_equal style, @view.stylesheet_pack_tag("bootstrap.css")
end
def test_stylesheet_pack_tag_splat
style = %(\n) +
%()
- assert_equal @view.stylesheet_pack_tag("bootstrap.css", "application.css", media: "all"), style
+ assert_equal style, @view.stylesheet_pack_tag("bootstrap.css", "application.css", media: "all")
+ end
+
+ def test_stylesheet_pack_tag_outputs_nothing_for_hot
+ Webpacker::DevServer.stub(:hot?, true) do
+ # Webpacker::Configuration.reset
+ # Webpacker::DevServer.reset
+ assert_equal "", @view.stylesheet_pack_tag("bootstrap.css")
+ end
+ # Webpacker::Configuration.reset
+ # Webpacker::DevServer.reset
end
end
diff --git a/test/manifest_test.rb b/test/manifest_test.rb
index 528064800..751d7df42 100644
--- a/test/manifest_test.rb
+++ b/test/manifest_test.rb
@@ -3,30 +3,75 @@
class ManifestTest < Minitest::Test
def test_file_path
file_path = File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
- assert_equal Webpacker::Manifest.file_path.to_s, file_path
+ assert_equal(Webpacker::Manifest.file_path.to_s, file_path)
end
def test_lookup_exception
manifest_path = File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
asset_file = "calendar.js"
+ msg = <<-MSG
+ Webpacker can't find #{asset_file} in your manifest at #{manifest_path}. Possible causes:
+ 1. You are hot reloading.
+ 2. You want to set Configuration.compile to true for your environment.
+ 3. Webpack has not re-run to reflect updates.
+ 4. You have misconfigured Webpacker's config/webpacker.yml file.
+ 5. Your Webpack configuration is not creating a manifest.
+ MSG
Webpacker::Configuration.stub :compile?, false do
error = assert_raises Webpacker::FileLoader::NotFoundError do
Webpacker::Manifest.lookup(asset_file)
end
- assert_equal error.message, "Can't find #{asset_file} in #{manifest_path}. Is webpack still compiling?"
+ assert_equal(error.message, msg)
end
end
def test_lookup_success
asset_file = "bootstrap.js"
- assert_equal Webpacker::Manifest.lookup(asset_file), "/packs/bootstrap-300631c4f0e0f9c865bc.js"
+ assert_equal("bootstrap-300631c4f0e0f9c865bc.js", Webpacker::Manifest.lookup(asset_file))
end
def test_lookup_path
file_path = File.join(File.dirname(__FILE__), "test_app/public/packs", "bootstrap-300631c4f0e0f9c865bc.js").to_s
asset_file = "bootstrap.js"
- assert_equal Webpacker::Manifest.lookup_path(asset_file).to_s, file_path
+ assert_equal(file_path, Webpacker::Manifest.lookup_path(asset_file).to_s)
+ end
+
+ def test_file_not_existing
+ begin
+ file_path = File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json")
+ temp_path = "#{file_path}.backup"
+ FileUtils.mv(file_path, temp_path)
+ # Point of this test is to ensure no crash
+ Webpacker::Manifest.load_instance
+ assert_equal({}, Webpacker::Manifest.instance.data)
+ ensure
+ FileUtils.mv(temp_path, file_path)
+ Webpacker::Manifest.instance = nil
+ Webpacker::Manifest.load_instance
+ end
+ end
+
+ def test_lookup_success
+ asset_file = "bootstrap.js"
+ assert_equal("bootstrap-300631c4f0e0f9c865bc.js", Webpacker::Manifest.lookup(asset_file))
+ end
+
+ def test_confirm_manifest_exists_for_existing
+ Webpacker::Manifest.instance.confirm_manifest_exists
+ end
+
+ def test_confirm_manifest_exists_for_missing
+ assert_raises do
+ Webpacker::Manifest.stub :path, "non-existent-file" do
+ confirm_manifest_exists
+ end
+ end
+ end
+
+ def test_lookup_no_throw
+ value = Webpacker::Manifest.lookup_no_throw("non-existent-bundle.js")
+ assert_equal(nil, value)
end
end
diff --git a/test/test_app/public/packs/manifest.json b/test/test_app/public/packs/manifest.json
index f7b77dd63..a5b6cb8e5 100644
--- a/test/test_app/public/packs/manifest.json
+++ b/test/test_app/public/packs/manifest.json
@@ -1,6 +1,6 @@
{
- "bootstrap.css": "/packs/bootstrap-c38deda30895059837cf.css",
- "application.css": "/packs/application-dd6b1cd38bfa093df600.css",
- "bootstrap.js": "/packs/bootstrap-300631c4f0e0f9c865bc.js",
- "application.js": "/packs/application-k344a6d59eef8632c9d1.js"
+ "bootstrap.css": "bootstrap-c38deda30895059837cf.css",
+ "application.css": "application-dd6b1cd38bfa093df600.css",
+ "bootstrap.js": "bootstrap-300631c4f0e0f9c865bc.js",
+ "application.js": "application-k344a6d59eef8632c9d1.js"
}
diff --git a/test/webpacker_test.rb b/test/webpacker_test.rb
index f05871147..02547fb18 100644
--- a/test/webpacker_test.rb
+++ b/test/webpacker_test.rb
@@ -5,6 +5,11 @@
require "rails/test_help"
require "webpacker"
+if ENV["USE_PRY"]
+ require "pry"
+ require "awesome_print"
+end
+
module TestApp
class Application < ::Rails::Application
config.root = File.join(File.dirname(__FILE__), "test_app")