webpacker 3.6.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -0
  3. data/.travis.yml +12 -4
  4. data/CHANGELOG.md +240 -28
  5. data/CONTRIBUTING.md +33 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +78 -71
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +75 -16
  10. data/docs/assets.md +7 -4
  11. data/docs/css.md +47 -14
  12. data/docs/deployment.md +11 -0
  13. data/docs/engines.md +155 -0
  14. data/docs/es6.md +5 -5
  15. data/docs/testing.md +1 -1
  16. data/docs/troubleshooting.md +4 -4
  17. data/docs/v4-upgrade.md +132 -0
  18. data/docs/webpack.md +56 -3
  19. data/docs/yarn.md +12 -1
  20. data/gemfiles/Gemfile-rails-edge +1 -1
  21. data/gemfiles/Gemfile-rails.4.2.x +2 -2
  22. data/gemfiles/Gemfile-rails.5.0.x +2 -2
  23. data/gemfiles/Gemfile-rails.5.1.x +2 -2
  24. data/gemfiles/Gemfile-rails.5.2.x +10 -0
  25. data/lib/install/bin/webpack +5 -1
  26. data/lib/install/bin/webpack-dev-server +5 -1
  27. data/lib/install/coffee.rb +2 -2
  28. data/lib/install/config/.browserslistrc +1 -0
  29. data/lib/install/config/babel.config.js +70 -0
  30. data/lib/install/config/postcss.config.js +12 -0
  31. data/lib/install/config/webpacker.yml +26 -0
  32. data/lib/install/elm.rb +2 -2
  33. data/lib/install/erb.rb +2 -2
  34. data/lib/install/examples/react/babel.config.js +83 -0
  35. data/lib/install/examples/stimulus/application.js +1 -6
  36. data/lib/install/examples/stimulus/controllers/index.js +9 -0
  37. data/lib/install/examples/typescript/tsconfig.json +4 -0
  38. data/lib/install/examples/vue/hello_vue.js +6 -4
  39. data/lib/install/javascript/packs/application.js +8 -0
  40. data/lib/install/loaders/typescript.js +8 -3
  41. data/lib/install/loaders/vue.js +1 -8
  42. data/lib/install/react.rb +6 -19
  43. data/lib/install/template.rb +29 -30
  44. data/lib/install/typescript.rb +4 -4
  45. data/lib/install/vue.rb +14 -5
  46. data/lib/tasks/installers.rake +4 -2
  47. data/lib/tasks/webpacker/binstubs.rake +3 -2
  48. data/lib/tasks/webpacker/compile.rake +10 -5
  49. data/lib/tasks/webpacker/install.rake +3 -2
  50. data/lib/tasks/webpacker/verify_install.rake +1 -4
  51. data/lib/tasks/webpacker/yarn_install.rake +1 -1
  52. data/lib/webpacker/commands.rb +0 -1
  53. data/lib/webpacker/compiler.rb +17 -13
  54. data/lib/webpacker/configuration.rb +13 -5
  55. data/lib/webpacker/dev_server.rb +7 -10
  56. data/lib/webpacker/dev_server_proxy.rb +13 -6
  57. data/lib/webpacker/dev_server_runner.rb +13 -6
  58. data/lib/webpacker/helper.rb +78 -20
  59. data/lib/webpacker/manifest.rb +64 -21
  60. data/lib/webpacker/railtie.rb +16 -7
  61. data/lib/webpacker/runner.rb +3 -3
  62. data/lib/webpacker/version.rb +1 -1
  63. data/lib/webpacker/webpack_runner.rb +14 -3
  64. data/package.json +46 -34
  65. data/package/__tests__/config.js +37 -3
  66. data/package/__tests__/dev_server.js +15 -0
  67. data/package/__tests__/production.js +2 -2
  68. data/package/__tests__/staging.js +3 -3
  69. data/package/__tests__/test.js +2 -1
  70. data/package/config.js +21 -9
  71. data/package/config_types/config_list.js +5 -6
  72. data/package/dev_server.js +3 -1
  73. data/package/environments/__tests__/base.js +7 -5
  74. data/package/environments/base.js +84 -31
  75. data/package/environments/development.js +6 -2
  76. data/package/environments/production.js +46 -36
  77. data/package/rules/babel.js +10 -4
  78. data/package/rules/file.js +8 -3
  79. data/package/rules/index.js +7 -2
  80. data/package/rules/node_modules.js +23 -0
  81. data/package/utils/__tests__/get_style_rule.js +20 -0
  82. data/package/utils/deep_merge.js +5 -6
  83. data/package/utils/get_style_rule.js +29 -42
  84. data/package/utils/helpers.js +18 -6
  85. data/package/utils/objectify.js +1 -2
  86. data/test/compiler_test.rb +15 -3
  87. data/test/configuration_test.rb +9 -0
  88. data/test/dev_server_runner_test.rb +51 -0
  89. data/test/helper_test.rb +48 -5
  90. data/test/manifest_test.rb +14 -0
  91. data/test/rake_tasks_test.rb +34 -0
  92. data/test/test_app/config.ru +5 -0
  93. data/test/test_app/config/application.rb +1 -0
  94. data/test/test_app/config/webpack/development.js +0 -0
  95. data/test/test_app/config/webpacker.yml +20 -0
  96. data/test/test_app/config/webpacker_public_root.yml +19 -0
  97. data/test/test_app/package.json +13 -0
  98. data/test/test_app/public/packs/manifest.json +22 -1
  99. data/test/test_app/yarn.lock +11 -0
  100. data/test/test_helper.rb +1 -3
  101. data/test/webpack_runner_test.rb +51 -0
  102. data/yarn.lock +4077 -2816
  103. metadata +28 -6
  104. data/lib/install/config/.babelrc +0 -18
  105. data/lib/install/config/.postcssrc.yml +0 -3
  106. data/lib/install/examples/react/.babelrc +0 -6
@@ -13,6 +13,8 @@ dependencies = {
13
13
  "Angular": [:typescript]
14
14
  }
15
15
 
16
+ bin_path = ENV["BUNDLE_BIN"] || "./bin"
17
+
16
18
  namespace :webpacker do
17
19
  namespace :install do
18
20
  installers.each do |name, task_name|
@@ -21,9 +23,9 @@ namespace :webpacker do
21
23
  template = File.expand_path("../install/#{task_name}.rb", __dir__)
22
24
  base_path =
23
25
  if Rails::VERSION::MAJOR >= 5
24
- "#{RbConfig.ruby} ./bin/rails app:template"
26
+ "#{RbConfig.ruby} #{bin_path}/rails app:template"
25
27
  else
26
- "#{RbConfig.ruby} ./bin/rake rails:template"
28
+ "#{RbConfig.ruby} #{bin_path}/rake rails:template"
27
29
  end
28
30
 
29
31
  dependencies[name] ||= []
@@ -1,12 +1,13 @@
1
1
  binstubs_template_path = File.expand_path("../../install/binstubs.rb", __dir__).freeze
2
+ bin_path = ENV["BUNDLE_BIN"] || "./bin"
2
3
 
3
4
  namespace :webpacker do
4
5
  desc "Installs Webpacker binstubs in this application"
5
6
  task binstubs: [:check_node, :check_yarn] do
6
7
  if Rails::VERSION::MAJOR >= 5
7
- exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{binstubs_template_path}"
8
+ exec "#{RbConfig.ruby} #{bin_path}/rails app:template LOCATION=#{binstubs_template_path}"
8
9
  else
9
- exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{binstubs_template_path}"
10
+ exec "#{RbConfig.ruby} #{bin_path}/rake rails:template LOCATION=#{binstubs_template_path}"
10
11
  end
11
12
  end
12
13
  end
@@ -8,12 +8,17 @@ ensure
8
8
  Webpacker.logger = old_logger
9
9
  end
10
10
 
11
+ def yarn_install_available?
12
+ rails_major = Rails::VERSION::MAJOR
13
+ rails_minor = Rails::VERSION::MINOR
14
+
15
+ rails_major > 5 || (rails_major == 5 && rails_minor >= 1)
16
+ end
17
+
11
18
  def enhance_assets_precompile
12
- Rake::Task["assets:precompile"].enhance do
13
- unless Rake::Task.task_defined?("yarn:install")
14
- # For Rails < 5.1
15
- Rake::Task["webpacker:yarn_install"].invoke
16
- end
19
+ # yarn:install was added in Rails 5.1
20
+ deps = yarn_install_available? ? [] : ["webpacker:yarn_install"]
21
+ Rake::Task["assets:precompile"].enhance(deps) do
17
22
  Rake::Task["webpacker:compile"].invoke
18
23
  end
19
24
  end
@@ -1,12 +1,13 @@
1
1
  install_template_path = File.expand_path("../../install/template.rb", __dir__).freeze
2
+ bin_path = ENV["BUNDLE_BIN"] || "./bin"
2
3
 
3
4
  namespace :webpacker do
4
5
  desc "Install Webpacker in this application"
5
6
  task install: [:check_node, :check_yarn] do
6
7
  if Rails::VERSION::MAJOR >= 5
7
- exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{install_template_path}"
8
+ exec "#{RbConfig.ruby} #{bin_path}/rails app:template LOCATION=#{install_template_path}"
8
9
  else
9
- exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{install_template_path}"
10
+ exec "#{RbConfig.ruby} #{bin_path}/rake rails:template LOCATION=#{install_template_path}"
10
11
  end
11
12
  end
12
13
  end
@@ -3,10 +3,7 @@ require "webpacker/configuration"
3
3
  namespace :webpacker do
4
4
  desc "Verifies if Webpacker is installed"
5
5
  task verify_install: [:check_node, :check_yarn, :check_binstubs] do
6
- if Webpacker.config.config_path.exist?
7
- $stdout.puts "Webpacker is installed 🎉 🍰"
8
- $stdout.puts "Using #{Webpacker.config.config_path} file for setting up webpack paths"
9
- else
6
+ unless Webpacker.config.config_path.exist?
10
7
  $stderr.puts "Configuration config/webpacker.yml file not found. \n"\
11
8
  "Make sure webpacker:install is run successfully before " \
12
9
  "running dependent tasks"
@@ -1,6 +1,6 @@
1
1
  namespace :webpacker do
2
2
  desc "Support for older Rails versions. Install all JavaScript dependencies as specified via Yarn"
3
3
  task :yarn_install do
4
- system "yarn install --no-progress --production"
4
+ system "yarn install --no-progress"
5
5
  end
6
6
  end
@@ -11,7 +11,6 @@ class Webpacker::Commands
11
11
  end
12
12
 
13
13
  def bootstrap
14
- config.refresh
15
14
  manifest.refresh
16
15
  end
17
16
 
@@ -10,7 +10,7 @@ class Webpacker::Compiler
10
10
  # Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
11
11
  cattr_accessor(:env) { {} }
12
12
 
13
- delegate :config, :logger, to: :@webpacker
13
+ delegate :config, :logger, to: :webpacker
14
14
 
15
15
  def initialize(webpacker)
16
16
  @webpacker = webpacker
@@ -18,9 +18,8 @@ class Webpacker::Compiler
18
18
 
19
19
  def compile
20
20
  if stale?
21
- record_compilation_digest
22
21
  run_webpack.tap do |success|
23
- remove_compilation_digest if !success
22
+ record_compilation_digest if success
24
23
  end
25
24
  else
26
25
  true
@@ -38,8 +37,11 @@ class Webpacker::Compiler
38
37
  end
39
38
 
40
39
  private
40
+ attr_reader :webpacker
41
+
41
42
  def last_compilation_digest
42
43
  compilation_digest_path.read if compilation_digest_path.exist? && config.public_manifest_path.exist?
44
+ rescue Errno::ENOENT, Errno::ENOTDIR
43
45
  end
44
46
 
45
47
  def watched_files_digest
@@ -53,16 +55,16 @@ class Webpacker::Compiler
53
55
  compilation_digest_path.write(watched_files_digest)
54
56
  end
55
57
 
56
- def remove_compilation_digest
57
- compilation_digest_path.delete if compilation_digest_path.exist?
58
- end
59
-
60
58
  def run_webpack
61
59
  logger.info "Compiling…"
62
60
 
63
- stdout, sterr , status = Open3.capture3(webpack_env, "#{RbConfig.ruby} ./bin/webpack")
61
+ stdout, sterr , status = Open3.capture3(
62
+ webpack_env,
63
+ "#{RbConfig.ruby} ./bin/webpack",
64
+ chdir: File.expand_path(config.root_path)
65
+ )
64
66
 
65
- if status.success?
67
+ if sterr == "" && status.success?
66
68
  logger.info "Compiled all packs in #{config.public_output_path}"
67
69
  logger.info stdout if config.webpack_compile_output?
68
70
  else
@@ -75,18 +77,20 @@ class Webpacker::Compiler
75
77
  def default_watched_paths
76
78
  [
77
79
  *config.resolved_paths_globbed,
78
- "#{config.source_path.relative_path_from(Rails.root)}/**/*",
80
+ "#{config.source_path.relative_path_from(config.root_path)}/**/*",
79
81
  "yarn.lock", "package.json",
80
82
  "config/webpack/**/*"
81
83
  ].freeze
82
84
  end
83
85
 
84
86
  def compilation_digest_path
85
- config.cache_path.join(".last-compilation-digest-#{Webpacker.env}")
87
+ config.cache_path.join("last-compilation-digest-#{webpacker.env}")
86
88
  end
87
89
 
88
90
  def webpack_env
89
- env.merge("WEBPACKER_ASSET_HOST" => ActionController::Base.helpers.compute_asset_host,
90
- "WEBPACKER_RELATIVE_URL_ROOT" => ActionController::Base.relative_url_root)
91
+ return env unless defined?(ActionController::Base)
92
+
93
+ env.merge("WEBPACKER_ASSET_HOST" => ENV.fetch("WEBPACKER_ASSET_HOST", ActionController::Base.helpers.compute_asset_host),
94
+ "WEBPACKER_RELATIVE_URL_ROOT" => ENV.fetch("WEBPACKER_RELATIVE_URL_ROOT", ActionController::Base.relative_url_root))
91
95
  end
92
96
  end
@@ -11,10 +11,6 @@ class Webpacker::Configuration
11
11
  @env = env
12
12
  end
13
13
 
14
- def refresh
15
- @data = load
16
- end
17
-
18
14
  def dev_server
19
15
  fetch(:dev_server)
20
16
  end
@@ -40,7 +36,7 @@ class Webpacker::Configuration
40
36
  end
41
37
 
42
38
  def public_path
43
- root_path.join("public")
39
+ root_path.join(fetch(:public_root_path))
44
40
  end
45
41
 
46
42
  def public_output_path
@@ -63,10 +59,22 @@ class Webpacker::Configuration
63
59
  fetch(:extensions)
64
60
  end
65
61
 
62
+ def check_yarn_integrity=(value)
63
+ data[:check_yarn_integrity] = value
64
+ end
65
+
66
+ def check_yarn_integrity?
67
+ fetch(:check_yarn_integrity)
68
+ end
69
+
66
70
  def webpack_compile_output?
67
71
  fetch(:webpack_compile_output)
68
72
  end
69
73
 
74
+ def extract_css?
75
+ fetch(:extract_css)
76
+ end
77
+
70
78
  private
71
79
  def fetch(key)
72
80
  data.fetch(key, defaults[key])
@@ -1,4 +1,6 @@
1
1
  class Webpacker::DevServer
2
+ DEFAULT_ENV_PREFIX = "WEBPACKER_DEV_SERVER".freeze
3
+
2
4
  # Configure dev server connection timeout (in seconds), default: 0.01
3
5
  # Webpacker.dev_server.connect_timeout = 1
4
6
  cattr_accessor(:connect_timeout) { 0.01 }
@@ -20,15 +22,6 @@ class Webpacker::DevServer
20
22
  false
21
23
  end
22
24
 
23
- def hot_module_replacing?
24
- case fetch(:hmr)
25
- when true, "true"
26
- true
27
- else
28
- false
29
- end
30
- end
31
-
32
25
  def host
33
26
  fetch(:host)
34
27
  end
@@ -58,9 +51,13 @@ class Webpacker::DevServer
58
51
  fetch(:pretty)
59
52
  end
60
53
 
54
+ def env_prefix
55
+ config.dev_server.fetch(:env_prefix, DEFAULT_ENV_PREFIX)
56
+ end
57
+
61
58
  private
62
59
  def fetch(key)
63
- ENV["WEBPACKER_DEV_SERVER_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
60
+ ENV["#{env_prefix}_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
64
61
  end
65
62
 
66
63
  def defaults
@@ -1,18 +1,25 @@
1
1
  require "rack/proxy"
2
2
 
3
3
  class Webpacker::DevServerProxy < Rack::Proxy
4
+ delegate :config, :dev_server, to: :@webpacker
5
+
6
+ def initialize(app = nil, opts = {})
7
+ @webpacker = opts.delete(:webpacker) || Webpacker.instance
8
+ super
9
+ end
10
+
4
11
  def rewrite_response(response)
5
12
  _status, headers, _body = response
6
13
  headers.delete "transfer-encoding"
7
- headers.delete "content-length" if Webpacker.dev_server.running? && Webpacker.dev_server.https?
14
+ headers.delete "content-length" if dev_server.running? && dev_server.https?
8
15
  response
9
16
  end
10
17
 
11
18
  def perform_request(env)
12
- if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && Webpacker.dev_server.running?
13
- env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = env["HTTP_X_FORWARDED_SERVER"] = Webpacker.dev_server.host_with_port
14
- env["HTTP_X_FORWARDED_PROTO"] = env["HTTP_X_FORWARDED_SCHEME"] = Webpacker.dev_server.protocol
15
- unless Webpacker.dev_server.https?
19
+ if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && dev_server.running?
20
+ env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = env["HTTP_X_FORWARDED_SERVER"] = dev_server.host_with_port
21
+ env["HTTP_X_FORWARDED_PROTO"] = env["HTTP_X_FORWARDED_SCHEME"] = dev_server.protocol
22
+ unless dev_server.https?
16
23
  env["HTTPS"] = env["HTTP_X_FORWARDED_SSL"] = "off"
17
24
  end
18
25
  env["SCRIPT_NAME"] = ""
@@ -25,6 +32,6 @@ class Webpacker::DevServerProxy < Rack::Proxy
25
32
 
26
33
  private
27
34
  def public_output_uri_path
28
- Webpacker.config.public_output_path.relative_path_from(Webpacker.config.public_path)
35
+ config.public_output_path.relative_path_from(config.public_path)
29
36
  end
30
37
  end
@@ -44,16 +44,23 @@ module Webpacker
44
44
  end
45
45
 
46
46
  def execute_cmd
47
- env = { "NODE_PATH" => @node_modules_path.shellescape }
48
- cmd = [
49
- "#{@node_modules_path}/.bin/webpack-dev-server",
50
- "--config", @webpack_config
51
- ]
47
+ env = Webpacker::Compiler.env
48
+
49
+ cmd = if node_modules_bin_exist?
50
+ ["#{@node_modules_bin_path}/webpack-dev-server"]
51
+ else
52
+ ["yarn", "webpack-dev-server"]
53
+ end
54
+ cmd += ["--config", @webpack_config]
52
55
  cmd += ["--progress", "--color"] if @pretty
53
56
 
54
57
  Dir.chdir(@app_path) do
55
- exec env, *cmd
58
+ Kernel.exec env, *cmd
56
59
  end
57
60
  end
61
+
62
+ def node_modules_bin_exist?
63
+ File.exist?("#{@node_modules_bin_path}/webpack-dev-server")
64
+ end
58
65
  end
59
66
  end
@@ -1,35 +1,42 @@
1
1
  module Webpacker::Helper
2
+ # Returns current Webpacker instance.
3
+ # Could be overriden to use multiple Webpacker
4
+ # configurations within the same app (e.g. with engines)
5
+ def current_webpacker_instance
6
+ Webpacker.instance
7
+ end
8
+
2
9
  # Computes the relative path for a given Webpacker asset.
3
- # Return relative path using manifest.json and passes it to asset_path helper
10
+ # Return relative path using manifest.json and passes it to asset_path helper.
4
11
  # This will use asset_path internally, so most of their behaviors will be the same.
5
12
  #
6
13
  # Example:
7
14
  #
8
- # # In development mode with hot module replacement:
15
+ # # When extract_css is false in webpacker.yml and the file is a css:
9
16
  # <%= asset_pack_path 'calendar.css' %> # => nil
10
17
  #
11
- # # In production mode:
18
+ # # When extract_css is true in webpacker.yml or the file is not a css:
12
19
  # <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
13
20
  def asset_pack_path(name, **options)
14
- unless stylesheet?(name) && Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing?
15
- asset_path(Webpacker.manifest.lookup!(name), **options)
21
+ if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
22
+ asset_path(current_webpacker_instance.manifest.lookup!(name), **options)
16
23
  end
17
24
  end
18
25
 
19
26
  # Computes the absolute path for a given Webpacker asset.
20
- # Return absolute path using manifest.json and passes it to asset_url helper
27
+ # Return absolute path using manifest.json and passes it to asset_url helper.
21
28
  # This will use asset_url internally, so most of their behaviors will be the same.
22
29
  #
23
30
  # Example:
24
31
  #
25
- # # In development mode with hot module replacement:
32
+ # # When extract_css is false in webpacker.yml and the file is a css:
26
33
  # <%= asset_pack_url 'calendar.css' %> # => nil
27
34
  #
28
- # # In production mode:
35
+ # # When extract_css is true in webpacker.yml or the file is not a css:
29
36
  # <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
30
37
  def asset_pack_url(name, **options)
31
- unless Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing?
32
- asset_url(Webpacker.manifest.lookup!(name), **options)
38
+ if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
39
+ asset_url(current_webpacker_instance.manifest.lookup!(name), **options)
33
40
  end
34
41
  end
35
42
 
@@ -40,7 +47,7 @@ module Webpacker::Helper
40
47
  # <%= image_pack_tag 'application.png', size: '16x10', alt: 'Edit Entry' %>
41
48
  # <img alt='Edit Entry' src='/packs/application-k344a6d59eef8632c9d1.png' width='16' height='10' />
42
49
  def image_pack_tag(name, **options)
43
- image_tag(asset_path(Webpacker.manifest.lookup!(name)), **options)
50
+ image_tag(resolve_path_to_image(name), **options)
44
51
  end
45
52
 
46
53
  # Creates a script tag that references the named pack file, as compiled by webpack per the entries list
@@ -52,7 +59,29 @@ module Webpacker::Helper
52
59
  # <%= javascript_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
53
60
  # <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
54
61
  def javascript_pack_tag(*names, **options)
55
- javascript_include_tag(*sources_from_pack_manifest(names, type: :javascript), **options)
62
+ javascript_include_tag(*sources_from_manifest_entries(names, type: :javascript), **options)
63
+ end
64
+
65
+ # Creates script tags that references the js chunks from entrypoints when using split chunks API,
66
+ # as compiled by webpack per the entries list in config/webpack/shared.js.
67
+ # By default, this list is auto-generated to match everything in
68
+ # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
69
+ # See: https://webpack.js.org/plugins/split-chunks-plugin/
70
+ # Example:
71
+ #
72
+ # <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
73
+ # <script src="/packs/vendor-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
74
+ # <script src="/packs/calendar~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
75
+ # <script src="/packs/calendar-1016838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
76
+ # <script src="/packs/map~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
77
+ # <script src="/packs/map-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
78
+ # DO:
79
+ # <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
80
+ # DON'T:
81
+ # <%= javascript_packs_with_chunks_tag 'calendar' %>
82
+ # <%= javascript_packs_with_chunks_tag 'map' %>
83
+ def javascript_packs_with_chunks_tag(*names, **options)
84
+ javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options)
56
85
  end
57
86
 
58
87
  # Creates a link tag that references the named pack file, as compiled by webpack per the entries list
@@ -64,16 +93,38 @@ module Webpacker::Helper
64
93
  #
65
94
  # Examples:
66
95
  #
67
- # # In development mode with hot module replacement:
96
+ # # When extract_css is false in webpacker.yml:
68
97
  # <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
69
98
  # nil
70
99
  #
71
- # # In production mode:
100
+ # # When extract_css is true in webpacker.yml:
72
101
  # <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
73
102
  # <link rel="stylesheet" media="screen" href="/packs/calendar-1016838bab065ae1e122.css" data-turbolinks-track="reload" />
74
103
  def stylesheet_pack_tag(*names, **options)
75
- unless Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing?
76
- stylesheet_link_tag(*sources_from_pack_manifest(names, type: :stylesheet), **options)
104
+ if current_webpacker_instance.config.extract_css?
105
+ stylesheet_link_tag(*sources_from_manifest_entries(names, type: :stylesheet), **options)
106
+ end
107
+ end
108
+
109
+ # Creates link tags that references the css chunks from entrypoints when using split chunks API,
110
+ # as compiled by webpack per the entries list in config/webpack/shared.js.
111
+ # By default, this list is auto-generated to match everything in
112
+ # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
113
+ # See: https://webpack.js.org/plugins/split-chunks-plugin/
114
+ # Example:
115
+ #
116
+ # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %> # =>
117
+ # <link rel="stylesheet" media="screen" href="/packs/3-8c7ce31a.chunk.css" />
118
+ # <link rel="stylesheet" media="screen" href="/packs/calendar-8c7ce31a.chunk.css" />
119
+ # <link rel="stylesheet" media="screen" href="/packs/map-8c7ce31a.chunk.css" />
120
+ # DO:
121
+ # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
122
+ # DON'T:
123
+ # <%= stylesheet_packs_with_chunks_tag 'calendar' %>
124
+ # <%= stylesheet_packs_with_chunks_tag 'map' %>
125
+ def stylesheet_packs_with_chunks_tag(*names, **options)
126
+ if current_webpacker_instance.config.extract_css?
127
+ stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
77
128
  end
78
129
  end
79
130
 
@@ -82,11 +133,18 @@ module Webpacker::Helper
82
133
  File.extname(name) == ".css"
83
134
  end
84
135
 
85
- def sources_from_pack_manifest(names, type:)
86
- names.map { |name| Webpacker.manifest.lookup!(pack_name_with_extension(name, type: type)) }
136
+ def sources_from_manifest_entries(names, type:)
137
+ names.map { |name| current_webpacker_instance.manifest.lookup!(name, type: type) }.flatten
138
+ end
139
+
140
+ def sources_from_manifest_entrypoints(names, type:)
141
+ names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name, type: type) }.flatten.uniq
87
142
  end
88
143
 
89
- def pack_name_with_extension(name, type:)
90
- "#{name}#{compute_asset_extname(name, type: type)}"
144
+ def resolve_path_to_image(name)
145
+ path = name.starts_with?("media/images/") ? name : "media/images/#{name}"
146
+ asset_path(current_webpacker_instance.manifest.lookup!(path))
147
+ rescue
148
+ asset_path(current_webpacker_instance.manifest.lookup!(name))
91
149
  end
92
150
  end