webpacker 3.6.0 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
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