webpacker 4.0.7 → 5.4.4

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +8 -8
  3. data/.github/workflows/jest.yml +38 -0
  4. data/.github/workflows/js-lint.yml +39 -0
  5. data/.github/workflows/rubocop.yml +39 -0
  6. data/.github/workflows/ruby.yml +46 -0
  7. data/.node-version +1 -1
  8. data/.rubocop.yml +118 -14
  9. data/CHANGELOG.md +301 -138
  10. data/CONTRIBUTING.md +1 -1
  11. data/Gemfile +1 -0
  12. data/Gemfile.lock +123 -92
  13. data/README.md +86 -211
  14. data/docs/css.md +72 -6
  15. data/docs/deployment.md +40 -11
  16. data/docs/docker.md +33 -14
  17. data/docs/engines.md +53 -3
  18. data/docs/env.md +0 -2
  19. data/docs/es6.md +19 -1
  20. data/docs/integrations.md +220 -0
  21. data/docs/target.md +22 -0
  22. data/docs/testing.md +2 -3
  23. data/docs/troubleshooting.md +39 -9
  24. data/docs/typescript.md +93 -26
  25. data/docs/webpack-dev-server.md +2 -2
  26. data/docs/webpack.md +18 -3
  27. data/gemfiles/Gemfile-rails-edge +1 -1
  28. data/gemfiles/{Gemfile-rails.4.2.x → Gemfile-rails.6.0.x} +1 -1
  29. data/lib/install/bin/webpack +0 -1
  30. data/lib/install/bin/webpack-dev-server +0 -1
  31. data/lib/install/coffee.rb +1 -1
  32. data/lib/install/config/babel.config.js +23 -13
  33. data/lib/install/config/webpacker.yml +3 -6
  34. data/lib/install/elm.rb +1 -1
  35. data/lib/install/erb.rb +2 -2
  36. data/lib/install/examples/angular/hello_angular/polyfills.ts +2 -2
  37. data/lib/install/examples/react/babel.config.js +28 -14
  38. data/lib/install/examples/react/tsconfig.json +2 -1
  39. data/lib/install/examples/svelte/app.svelte +11 -0
  40. data/lib/install/examples/svelte/hello_svelte.js +20 -0
  41. data/lib/install/examples/typescript/tsconfig.json +2 -1
  42. data/lib/install/loaders/elm.js +9 -6
  43. data/lib/install/loaders/svelte.js +9 -0
  44. data/lib/install/svelte.rb +29 -0
  45. data/lib/install/template.rb +14 -6
  46. data/lib/install/typescript.rb +6 -13
  47. data/lib/install/vue.rb +1 -1
  48. data/lib/tasks/installers.rake +1 -0
  49. data/lib/tasks/webpacker/check_node.rake +15 -8
  50. data/lib/tasks/webpacker/check_yarn.rake +16 -10
  51. data/lib/tasks/webpacker/clean.rake +25 -0
  52. data/lib/tasks/webpacker/clobber.rake +8 -4
  53. data/lib/tasks/webpacker/compile.rake +2 -10
  54. data/lib/tasks/webpacker/yarn_install.rake +11 -1
  55. data/lib/tasks/webpacker.rake +2 -0
  56. data/lib/webpacker/commands.rb +53 -1
  57. data/lib/webpacker/compiler.rb +21 -10
  58. data/lib/webpacker/configuration.rb +36 -13
  59. data/lib/webpacker/dev_server.rb +1 -1
  60. data/lib/webpacker/dev_server_proxy.rb +5 -9
  61. data/lib/webpacker/dev_server_runner.rb +6 -6
  62. data/lib/webpacker/env.rb +6 -2
  63. data/lib/webpacker/helper.rb +70 -25
  64. data/lib/webpacker/manifest.rb +4 -4
  65. data/lib/webpacker/railtie.rb +6 -43
  66. data/lib/webpacker/runner.rb +1 -0
  67. data/lib/webpacker/version.rb +1 -1
  68. data/lib/webpacker/webpack_runner.rb +2 -2
  69. data/lib/webpacker.rb +9 -1
  70. data/package/__tests__/config.js +12 -24
  71. data/package/__tests__/dev_server.js +2 -0
  72. data/package/__tests__/development.js +14 -1
  73. data/package/config.js +6 -11
  74. data/package/configPath.js +3 -0
  75. data/package/config_types/config_list.js +3 -3
  76. data/package/config_types/config_object.js +1 -1
  77. data/package/dev_server.js +1 -1
  78. data/package/env.js +1 -2
  79. data/package/environments/__tests__/base.js +29 -2
  80. data/package/environments/base.js +18 -8
  81. data/package/environments/development.js +39 -37
  82. data/package/environments/production.js +12 -2
  83. data/package/rules/babel.js +12 -5
  84. data/package/rules/file.js +3 -2
  85. data/package/rules/node_modules.js +3 -5
  86. data/package/rules/sass.js +11 -2
  87. data/package/utils/__tests__/get_style_rule.js +9 -0
  88. data/package/utils/deep_merge.js +5 -5
  89. data/package/utils/get_style_rule.js +7 -12
  90. data/package/utils/helpers.js +10 -10
  91. data/package.json +43 -43
  92. data/test/command_test.rb +6 -0
  93. data/test/compiler_test.rb +10 -6
  94. data/test/configuration_test.rb +40 -30
  95. data/test/dev_server_runner_test.rb +1 -1
  96. data/test/dev_server_test.rb +22 -0
  97. data/test/helper_test.rb +58 -9
  98. data/test/manifest_test.rb +37 -6
  99. data/test/rake_tasks_test.rb +17 -0
  100. data/test/test_app/app/javascript/packs/multi_entry.css +4 -0
  101. data/test/test_app/app/javascript/packs/multi_entry.js +4 -0
  102. data/test/test_app/bin/webpack +0 -1
  103. data/test/test_app/bin/webpack-dev-server +0 -1
  104. data/test/test_app/config/application.rb +0 -1
  105. data/test/test_app/config/webpacker.yml +8 -1
  106. data/test/test_app/public/packs/manifest.json +4 -0
  107. data/test/webpack_runner_test.rb +1 -1
  108. data/webpacker.gemspec +6 -4
  109. data/yarn.lock +4350 -4099
  110. metadata +63 -23
  111. data/.travis.yml +0 -53
  112. data/gemfiles/Gemfile-rails.5.0.x +0 -9
  113. data/gemfiles/Gemfile-rails.5.1.x +0 -9
  114. data/lib/install/loaders/typescript.js +0 -11
@@ -1,14 +1,14 @@
1
1
  module Webpacker::Helper
2
- # Returns current Webpacker instance.
2
+ # Returns the current Webpacker instance.
3
3
  # Could be overridden to use multiple Webpacker
4
- # configurations within the same app (e.g. with engines)
4
+ # configurations within the same app (e.g. with engines).
5
5
  def current_webpacker_instance
6
6
  Webpacker.instance
7
7
  end
8
8
 
9
9
  # Computes the relative path for a given Webpacker asset.
10
- # Return relative path using manifest.json and passes it to asset_path helper.
11
- # This will use asset_path internally, so most of their behaviors will be the same.
10
+ # Returns the relative path using manifest.json and passes it to path_to_asset helper.
11
+ # This will use path_to_asset internally, so most of their behaviors will be the same.
12
12
  #
13
13
  # Example:
14
14
  #
@@ -19,13 +19,13 @@ module Webpacker::Helper
19
19
  # <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
20
20
  def asset_pack_path(name, **options)
21
21
  if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
22
- asset_path(current_webpacker_instance.manifest.lookup!(name), **options)
22
+ path_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
23
23
  end
24
24
  end
25
25
 
26
26
  # Computes the absolute path for a given Webpacker asset.
27
- # Return absolute path using manifest.json and passes it to asset_url helper.
28
- # This will use asset_url internally, so most of their behaviors will be the same.
27
+ # Returns the absolute path using manifest.json and passes it to url_to_asset helper.
28
+ # This will use url_to_asset internally, so most of their behaviors will be the same.
29
29
  #
30
30
  # Example:
31
31
  #
@@ -36,22 +36,41 @@ module Webpacker::Helper
36
36
  # <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
37
37
  def asset_pack_url(name, **options)
38
38
  if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
39
- asset_url(current_webpacker_instance.manifest.lookup!(name), **options)
39
+ url_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
40
40
  end
41
41
  end
42
42
 
43
- # Creates a image tag that references the named pack file.
43
+ # Creates an image tag that references the named pack file.
44
44
  #
45
45
  # Example:
46
46
  #
47
47
  # <%= image_pack_tag 'application.png', size: '16x10', alt: 'Edit Entry' %>
48
48
  # <img alt='Edit Entry' src='/packs/application-k344a6d59eef8632c9d1.png' width='16' height='10' />
49
+ #
50
+ # <%= image_pack_tag 'picture.png', srcset: { 'picture-2x.png' => '2x' } %>
51
+ # <img srcset= "/packs/picture-2x-7cca48e6cae66ec07b8e.png 2x" src="/packs/picture-c38deda30895059837cf.png" >
49
52
  def image_pack_tag(name, **options)
50
- image_tag(resolve_path_to_image(name), **options)
53
+ if options[:srcset] && !options[:srcset].is_a?(String)
54
+ options[:srcset] = options[:srcset].map do |src_name, size|
55
+ "#{resolve_path_to_image(src_name)} #{size}"
56
+ end.join(", ")
57
+ end
58
+
59
+ image_tag(resolve_path_to_image(name), options)
60
+ end
61
+
62
+ # Creates a link tag for a favicon that references the named pack file.
63
+ #
64
+ # Example:
65
+ #
66
+ # <%= favicon_pack_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png' %>
67
+ # <link href="/packs/mb-icon-k344a6d59eef8632c9d1.png" rel="apple-touch-icon" type="image/png" />
68
+ def favicon_pack_tag(name, **options)
69
+ favicon_link_tag(resolve_path_to_image(name), options)
51
70
  end
52
71
 
53
72
  # Creates a script tag that references the named pack file, as compiled by webpack per the entries list
54
- # in config/webpack/shared.js. By default, this list is auto-generated to match everything in
73
+ # in package/environments/base.js. By default, this list is auto-generated to match everything in
55
74
  # app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
56
75
  #
57
76
  # Example:
@@ -62,11 +81,12 @@ module Webpacker::Helper
62
81
  javascript_include_tag(*sources_from_manifest_entries(names, type: :javascript), **options)
63
82
  end
64
83
 
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.
84
+ # Creates script tags that reference the js chunks from entrypoints when using split chunks API,
85
+ # as compiled by webpack per the entries list in package/environments/base.js.
67
86
  # By default, this list is auto-generated to match everything in
68
87
  # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
69
88
  # See: https://webpack.js.org/plugins/split-chunks-plugin/
89
+ #
70
90
  # Example:
71
91
  #
72
92
  # <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
@@ -75,17 +95,37 @@ module Webpacker::Helper
75
95
  # <script src="/packs/calendar-1016838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
76
96
  # <script src="/packs/map~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
77
97
  # <script src="/packs/map-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
98
+ #
78
99
  # DO:
79
- # <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
100
+ #
101
+ # <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
102
+ #
80
103
  # DON'T:
81
- # <%= javascript_packs_with_chunks_tag 'calendar' %>
82
- # <%= javascript_packs_with_chunks_tag 'map' %>
104
+ #
105
+ # <%= javascript_packs_with_chunks_tag 'calendar' %>
106
+ # <%= javascript_packs_with_chunks_tag 'map' %>
83
107
  def javascript_packs_with_chunks_tag(*names, **options)
84
108
  javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options)
85
109
  end
86
110
 
111
+ # Creates a link tag, for preloading, that references a given Webpacker asset.
112
+ # In production mode, the digested reference is automatically looked up.
113
+ # See: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
114
+ #
115
+ # Example:
116
+ #
117
+ # <%= preload_pack_asset 'fonts/fa-regular-400.woff2' %> # =>
118
+ # <link rel="preload" href="/packs/fonts/fa-regular-400-944fb546bd7018b07190a32244f67dc9.woff2" as="font" type="font/woff2" crossorigin="anonymous">
119
+ def preload_pack_asset(name, **options)
120
+ if self.class.method_defined?(:preload_link_tag)
121
+ preload_link_tag(current_webpacker_instance.manifest.lookup!(name), options)
122
+ else
123
+ raise "You need Rails >= 5.2 to use this tag."
124
+ end
125
+ end
126
+
87
127
  # Creates a link tag that references the named pack file, as compiled by webpack per the entries list
88
- # in config/webpack/shared.js. By default, this list is auto-generated to match everything in
128
+ # in package/environments/base.js. By default, this list is auto-generated to match everything in
89
129
  # app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
90
130
  #
91
131
  # Note: If the development server is running and hot module replacement is active, this will return nothing.
@@ -106,22 +146,27 @@ module Webpacker::Helper
106
146
  end
107
147
  end
108
148
 
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.
149
+ # Creates link tags that reference the css chunks from entrypoints when using split chunks API,
150
+ # as compiled by webpack per the entries list in package/environments/base.js.
111
151
  # By default, this list is auto-generated to match everything in
112
152
  # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
113
153
  # See: https://webpack.js.org/plugins/split-chunks-plugin/
114
- # Example:
154
+ #
155
+ # Examples:
115
156
  #
116
157
  # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %> # =>
117
158
  # <link rel="stylesheet" media="screen" href="/packs/3-8c7ce31a.chunk.css" />
118
159
  # <link rel="stylesheet" media="screen" href="/packs/calendar-8c7ce31a.chunk.css" />
119
160
  # <link rel="stylesheet" media="screen" href="/packs/map-8c7ce31a.chunk.css" />
161
+ #
120
162
  # DO:
121
- # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
163
+ #
164
+ # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
165
+ #
122
166
  # DON'T:
123
- # <%= stylesheet_packs_with_chunks_tag 'calendar' %>
124
- # <%= stylesheet_packs_with_chunks_tag 'map' %>
167
+ #
168
+ # <%= stylesheet_packs_with_chunks_tag 'calendar' %>
169
+ # <%= stylesheet_packs_with_chunks_tag 'map' %>
125
170
  def stylesheet_packs_with_chunks_tag(*names, **options)
126
171
  if current_webpacker_instance.config.extract_css?
127
172
  stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
@@ -143,8 +188,8 @@ module Webpacker::Helper
143
188
 
144
189
  def resolve_path_to_image(name)
145
190
  path = name.starts_with?("media/images/") ? name : "media/images/#{name}"
146
- asset_path(current_webpacker_instance.manifest.lookup!(path))
191
+ path_to_asset(current_webpacker_instance.manifest.lookup!(path))
147
192
  rescue
148
- asset_path(current_webpacker_instance.manifest.lookup!(name))
193
+ path_to_asset(current_webpacker_instance.manifest.lookup!(name))
149
194
  end
150
195
  end
@@ -29,7 +29,7 @@ class Webpacker::Manifest
29
29
  end
30
30
 
31
31
  def lookup_pack_with_chunks!(name, pack_type = {})
32
- lookup_pack_with_chunks(name, pack_type) || handle_missing_entry(name)
32
+ lookup_pack_with_chunks(name, pack_type) || handle_missing_entry(name, pack_type)
33
33
  end
34
34
 
35
35
  # Computes the relative path for a given Webpacker asset using manifest.json.
@@ -46,7 +46,7 @@ class Webpacker::Manifest
46
46
 
47
47
  # Like lookup, except that if no asset is found, raises a Webpacker::Manifest::MissingEntryError.
48
48
  def lookup!(name, pack_type = {})
49
- lookup(name, pack_type) || handle_missing_entry(name)
49
+ lookup(name, pack_type) || handle_missing_entry(name, pack_type)
50
50
  end
51
51
 
52
52
  private
@@ -75,8 +75,8 @@ class Webpacker::Manifest
75
75
  "#{name}.#{manifest_type(pack_type)}"
76
76
  end
77
77
 
78
- def handle_missing_entry(name)
79
- raise Webpacker::Manifest::MissingEntryError, missing_file_from_manifest_error(name)
78
+ def handle_missing_entry(name, pack_type)
79
+ raise Webpacker::Manifest::MissingEntryError, missing_file_from_manifest_error(full_pack_name(name, pack_type[:type]))
80
80
  end
81
81
 
82
82
  def load
@@ -7,49 +7,6 @@ class Webpacker::Engine < ::Rails::Engine
7
7
  # Allows Webpacker config values to be set via Rails env config files
8
8
  config.webpacker = ActiveSupport::OrderedOptions.new
9
9
 
10
- initializer "webpacker.set_configs" do |app|
11
- if app.config.webpacker.key?(:check_yarn_integrity)
12
- Webpacker.config.check_yarn_integrity = app.config.webpacker.check_yarn_integrity
13
- end
14
- end
15
-
16
- # ================================
17
- # Check Yarn Integrity Initializer
18
- # ================================
19
- #
20
- # development (on by default):
21
- #
22
- # to turn off:
23
- # - edit config/environments/development.rb
24
- # - add `config.webpacker.check_yarn_integrity = false`
25
- #
26
- # production (off by default):
27
- #
28
- # to turn on:
29
- # - edit config/environments/production.rb
30
- # - add `config.webpacker.check_yarn_integrity = true`
31
- initializer "webpacker.yarn_check" do |app|
32
- if File.exist?("yarn.lock") && Webpacker.config.config_path.exist? && Webpacker.config.check_yarn_integrity?
33
- output = `yarn check --integrity && yarn check --verify-tree 2>&1`
34
-
35
- unless $?.success?
36
- $stderr.puts "\n\n"
37
- $stderr.puts "========================================"
38
- $stderr.puts " Your Yarn packages are out of date!"
39
- $stderr.puts " Please run `yarn install --check-files` to update."
40
- $stderr.puts "========================================"
41
- $stderr.puts "\n\n"
42
- $stderr.puts "To disable this check, please change `check_yarn_integrity`"
43
- $stderr.puts "to `false` in your webpacker config file (config/webpacker.yml)."
44
- $stderr.puts "\n\n"
45
- $stderr.puts output
46
- $stderr.puts "\n\n"
47
-
48
- exit(1)
49
- end
50
- end
51
- end
52
-
53
10
  initializer "webpacker.proxy" do |app|
54
11
  insert_middleware = Webpacker.config.dev_server.present? rescue nil
55
12
  if insert_middleware
@@ -89,4 +46,10 @@ class Webpacker::Engine < ::Rails::Engine
89
46
  end
90
47
  end
91
48
  end
49
+
50
+ initializer "webpacker.set_source" do |app|
51
+ if Webpacker.config.config_path.exist?
52
+ app.config.javascript_path = Webpacker.config.source_path.relative_path_from(Rails.root.join("app")).to_s
53
+ end
54
+ end
92
55
  end
@@ -12,6 +12,7 @@ module Webpacker
12
12
  @app_path = File.expand_path(".", Dir.pwd)
13
13
  @node_modules_bin_path = ENV["WEBPACKER_NODE_MODULES_BIN_PATH"] || `yarn bin`.chomp
14
14
  @webpack_config = File.join(@app_path, "config/webpack/#{ENV["NODE_ENV"]}.js")
15
+ @webpacker_config = File.join(@app_path, "config/webpacker.yml")
15
16
 
16
17
  unless File.exist?(@webpack_config)
17
18
  $stderr.puts "webpack config #{@webpack_config} not found, please run 'bundle exec rails webpacker:install' to install Webpacker with default configs or add the missing config file for your custom environment."
@@ -1,4 +1,4 @@
1
1
  module Webpacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "4.0.7".freeze
3
+ VERSION = "5.4.4".freeze
4
4
  end
@@ -5,6 +5,7 @@ module Webpacker
5
5
  class WebpackRunner < Webpacker::Runner
6
6
  def run
7
7
  env = Webpacker::Compiler.env
8
+ env["WEBPACKER_CONFIG"] = @webpacker_config
8
9
 
9
10
  cmd = if node_modules_bin_exist?
10
11
  ["#{@node_modules_bin_path}/webpack"]
@@ -12,9 +13,8 @@ module Webpacker
12
13
  ["yarn", "webpack"]
13
14
  end
14
15
 
15
- if ARGV.include?("--debug")
16
+ if @argv.include?("--debug-webpacker")
16
17
  cmd = [ "node", "--inspect-brk"] + cmd
17
- ARGV.delete("--debug")
18
18
  end
19
19
 
20
20
  cmd += ["--config", @webpack_config] + @argv
data/lib/webpacker.rb CHANGED
@@ -22,9 +22,17 @@ module Webpacker
22
22
  ENV["NODE_ENV"] = original
23
23
  end
24
24
 
25
+ def ensure_log_goes_to_stdout
26
+ old_logger = Webpacker.logger
27
+ Webpacker.logger = ActiveSupport::Logger.new(STDOUT)
28
+ yield
29
+ ensure
30
+ Webpacker.logger = old_logger
31
+ end
32
+
25
33
  delegate :logger, :logger=, :env, to: :instance
26
34
  delegate :config, :compiler, :manifest, :commands, :dev_server, to: :instance
27
- delegate :bootstrap, :clobber, :compile, to: :commands
35
+ delegate :bootstrap, :clean, :clobber, :compile, to: :commands
28
36
  end
29
37
 
30
38
  require "webpacker/instance"
@@ -16,29 +16,6 @@ describe('Config', () => {
16
16
  expect(config.publicPath).toEqual('/packs/')
17
17
  })
18
18
 
19
- // also tests removal of extra slashes
20
- test('public path with relative root', () => {
21
- process.env.RAILS_ENV = 'development'
22
- process.env.RAILS_RELATIVE_URL_ROOT = '/foo'
23
- const config = require('../config')
24
- expect(config.publicPath).toEqual('/foo/packs/')
25
- })
26
-
27
- test('public path with relative root without slash', () => {
28
- process.env.RAILS_ENV = 'development'
29
- process.env.RAILS_RELATIVE_URL_ROOT = 'foo'
30
- const config = require('../config')
31
- expect(config.publicPath).toEqual('/foo/packs/')
32
- })
33
-
34
- test('public path with asset host and relative root', () => {
35
- process.env.RAILS_ENV = 'development'
36
- process.env.RAILS_RELATIVE_URL_ROOT = '/foo/'
37
- process.env.WEBPACKER_ASSET_HOST = 'http://foo.com/'
38
- const config = require('../config')
39
- expect(config.publicPath).toEqual('http://foo.com/foo/packs/')
40
- })
41
-
42
19
  test('public path with asset host', () => {
43
20
  process.env.RAILS_ENV = 'development'
44
21
  process.env.WEBPACKER_ASSET_HOST = 'http://foo.com/'
@@ -46,6 +23,16 @@ describe('Config', () => {
46
23
  expect(config.publicPath).toEqual('http://foo.com/packs/')
47
24
  })
48
25
 
26
+ test('should return additional paths as listed in app config, with resolved paths', () => {
27
+ expect(config.additional_paths).toEqual(
28
+ [
29
+ 'app/assets',
30
+ '/etc/yarn',
31
+ 'app/elm'
32
+ ]
33
+ )
34
+ })
35
+
49
36
  test('should return extensions as listed in app config', () => {
50
37
  expect(config.extensions).toEqual([
51
38
  '.mjs',
@@ -60,7 +47,8 @@ describe('Config', () => {
60
47
  '.svg',
61
48
  '.gif',
62
49
  '.jpeg',
63
- '.jpg'
50
+ '.jpg',
51
+ '.elm'
64
52
  ])
65
53
  })
66
54
 
@@ -13,11 +13,13 @@ describe('DevServer', () => {
13
13
  process.env.RAILS_ENV = 'development'
14
14
  process.env.WEBPACKER_DEV_SERVER_HOST = '0.0.0.0'
15
15
  process.env.WEBPACKER_DEV_SERVER_PORT = 5000
16
+ process.env.WEBPACKER_DEV_SERVER_DISABLE_HOST_CHECK = false
16
17
 
17
18
  const devServer = require('../dev_server')
18
19
  expect(devServer).toBeDefined()
19
20
  expect(devServer.host).toEqual('0.0.0.0')
20
21
  expect(devServer.port).toEqual('5000')
22
+ expect(devServer.disable_host_check).toBe(false)
21
23
  })
22
24
 
23
25
  test('with custom env prefix', () => {
@@ -11,9 +11,10 @@ describe('Development environment', () => {
11
11
  describe('toWebpackConfig', () => {
12
12
  beforeEach(() => jest.resetModules())
13
13
 
14
- test('should use development config and environment', () => {
14
+ test('should use development config and environment including devServer if WEBPACK_DEV_SERVER', () => {
15
15
  process.env.RAILS_ENV = 'development'
16
16
  process.env.NODE_ENV = 'development'
17
+ process.env.WEBPACK_DEV_SERVER = 'YES'
17
18
  const { environment } = require('../index')
18
19
 
19
20
  const config = environment.toWebpackConfig()
@@ -26,5 +27,17 @@ describe('Development environment', () => {
26
27
  }
27
28
  })
28
29
  })
30
+
31
+ test('should use development config and environment if WEBPACK_DEV_SERVER', () => {
32
+ process.env.RAILS_ENV = 'development'
33
+ process.env.NODE_ENV = 'development'
34
+ process.env.WEBPACK_DEV_SERVER = undefined
35
+ const { environment } = require('../index')
36
+
37
+ const config = environment.toWebpackConfig()
38
+ expect(config.output.path).toEqual(resolve('public', 'packs'))
39
+ expect(config.output.publicPath).toEqual('/packs/')
40
+ expect(config.devServer).toEqual(undefined)
41
+ })
29
42
  })
30
43
  })
data/package/config.js CHANGED
@@ -4,9 +4,9 @@ const { readFileSync } = require('fs')
4
4
  const deepMerge = require('./utils/deep_merge')
5
5
  const { isArray, ensureTrailingSlash } = require('./utils/helpers')
6
6
  const { railsEnv } = require('./env')
7
+ const configPath = require('./configPath')
7
8
 
8
9
  const defaultConfigPath = require.resolve('../lib/install/config/webpacker.yml')
9
- const configPath = resolve('config', 'webpacker.yml')
10
10
 
11
11
  const getDefaultConfig = () => {
12
12
  const defaultConfig = safeLoad(readFileSync(defaultConfigPath), 'utf8')
@@ -24,19 +24,14 @@ if (isArray(app.static_assets_extensions) && app.static_assets_extensions.length
24
24
  const config = deepMerge(defaults, app)
25
25
  config.outputPath = resolve(config.public_root_path, config.public_output_path)
26
26
 
27
+ // Merge resolved_paths into additional_paths for backwards-compat
28
+ config.additional_paths = config.additional_paths.concat(config.resolved_paths || [])
29
+
27
30
  // Ensure that the publicPath includes our asset host so dynamic imports
28
31
  // (code-splitting chunks and static assets) load from the CDN instead of a relative path.
29
32
  const getPublicPath = () => {
30
- const rootUrl = process.env.WEBPACKER_ASSET_HOST || '/'
31
- let packPath = `${config.public_output_path}/`
32
- // Add relative root prefix to pack path.
33
- if (process.env.RAILS_RELATIVE_URL_ROOT) {
34
- let relativeRoot = process.env.RAILS_RELATIVE_URL_ROOT
35
- relativeRoot = relativeRoot.startsWith('/') ? relativeRoot.substr(1) : relativeRoot
36
- packPath = `${ensureTrailingSlash(relativeRoot)}${packPath}`
37
- }
38
-
39
- return ensureTrailingSlash(rootUrl) + packPath
33
+ const rootUrl = ensureTrailingSlash(process.env.WEBPACKER_ASSET_HOST || '/')
34
+ return `${rootUrl}${config.public_output_path}/`
40
35
  }
41
36
 
42
37
  config.publicPath = getPublicPath()
@@ -0,0 +1,3 @@
1
+ const { resolve } = require('path')
2
+
3
+ module.exports = process.env.WEBPACKER_CONFIG || resolve('config', 'webpacker.yml')
@@ -38,7 +38,7 @@ class ConfigList extends Array {
38
38
  }
39
39
 
40
40
  getIndex(key, shouldThrow = false) {
41
- const index = this.findIndex(entry => (
41
+ const index = this.findIndex((entry) => (
42
42
  entry === key
43
43
  || entry.key === key
44
44
  || (entry.constructor && entry.constructor.name === key)
@@ -64,11 +64,11 @@ class ConfigList extends Array {
64
64
  }
65
65
 
66
66
  values() {
67
- return this.map(item => item.value)
67
+ return this.map((item) => item.value)
68
68
  }
69
69
 
70
70
  keys() {
71
- return this.map(item => item.key)
71
+ return this.map((item) => item.key)
72
72
  }
73
73
  }
74
74
 
@@ -42,7 +42,7 @@ class ConfigObject extends Object {
42
42
  toObject() {
43
43
  const object = {}
44
44
  /* eslint no-return-assign: 0 */
45
- Object.keys(this).forEach(key => (object[key] = this[key]))
45
+ Object.keys(this).forEach((key) => (object[key] = this[key]))
46
46
  return object
47
47
  }
48
48
 
@@ -12,7 +12,7 @@ if (devServerConfig) {
12
12
  const envPrefix = config.dev_server.env_prefix || 'WEBPACKER_DEV_SERVER'
13
13
 
14
14
  Object.keys(devServerConfig).forEach((key) => {
15
- const envValue = fetch(`${envPrefix}_${key.toUpperCase().replace(/_/g, '')}`)
15
+ const envValue = fetch(`${envPrefix}_${key.toUpperCase()}`)
16
16
  if (envValue !== undefined) devServerConfig[key] = envValue
17
17
  })
18
18
  }
data/package/env.js CHANGED
@@ -1,10 +1,9 @@
1
- const { resolve } = require('path')
2
1
  const { safeLoad } = require('js-yaml')
3
2
  const { readFileSync } = require('fs')
4
3
 
5
4
  const NODE_ENVIRONMENTS = ['development', 'production', 'test']
6
5
  const DEFAULT = 'production'
7
- const configPath = resolve('config', 'webpacker.yml')
6
+ const configPath = require('./configPath')
8
7
 
9
8
  const railsEnv = process.env.RAILS_ENV
10
9
  const nodeEnv = process.env.NODE_ENV
@@ -29,10 +29,20 @@ describe('Environment', () => {
29
29
  )
30
30
  })
31
31
 
32
+ test('should return multi file entry points', () => {
33
+ const config = environment.toWebpackConfig()
34
+ expect(config.entry.multi_entry.sort()).toEqual([
35
+ resolve('app', 'javascript', 'packs', 'multi_entry.css'),
36
+ resolve('app', 'javascript', 'packs', 'multi_entry.js')
37
+ ])
38
+ })
39
+
32
40
  test('should return output', () => {
33
41
  const config = environment.toWebpackConfig()
34
42
  expect(config.output.filename).toEqual('js/[name]-[contenthash].js')
35
- expect(config.output.chunkFilename).toEqual('js/[name]-[contenthash].chunk.js')
43
+ expect(config.output.chunkFilename).toEqual(
44
+ 'js/[name]-[contenthash].chunk.js'
45
+ )
36
46
  })
37
47
 
38
48
  test('should return default loader rules for each file in config/loaders', () => {
@@ -41,7 +51,23 @@ describe('Environment', () => {
41
51
  const configRules = config.module.rules
42
52
 
43
53
  expect(defaultRules.length).toEqual(7)
44
- expect(configRules.length).toEqual(8)
54
+ expect(configRules.length).toEqual(7)
55
+ })
56
+
57
+ test('should return cache path for nodeModules rule', () => {
58
+ const nodeModulesLoader = rules.nodeModules.use.find(
59
+ (rule) => rule.loader === 'babel-loader'
60
+ )
61
+
62
+ expect(nodeModulesLoader.options.cacheDirectory).toBeTruthy()
63
+ })
64
+
65
+ test('should return cache path for babel-loader rule', () => {
66
+ const babelLoader = rules.babel.use.find(
67
+ (rule) => rule.loader === 'babel-loader'
68
+ )
69
+
70
+ expect(babelLoader.options.cacheDirectory).toBeTruthy()
45
71
  })
46
72
 
47
73
  test('should return default plugins', () => {
@@ -60,6 +86,7 @@ describe('Environment', () => {
60
86
  resolve('app', 'javascript'),
61
87
  resolve('app/assets'),
62
88
  resolve('/etc/yarn'),
89
+ resolve('app/elm'),
63
90
  'node_modules'
64
91
  ])
65
92
  })
@@ -22,7 +22,7 @@ const config = require('../config')
22
22
 
23
23
  const getLoaderList = () => {
24
24
  const result = new ConfigList()
25
- Object.keys(rules).forEach(key => result.append(key, rules[key]))
25
+ Object.keys(rules).forEach((key) => result.append(key, rules[key]))
26
26
  return result
27
27
  }
28
28
 
@@ -30,7 +30,7 @@ const getPluginList = () => {
30
30
  const result = new ConfigList()
31
31
  result.append(
32
32
  'Environment',
33
- new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env)))
33
+ new webpack.EnvironmentPlugin(process.env)
34
34
  )
35
35
  result.append('CaseSensitivePaths', new CaseSensitivePathsPlugin())
36
36
  result.append(
@@ -43,7 +43,6 @@ const getPluginList = () => {
43
43
  result.append(
44
44
  'Manifest',
45
45
  new WebpackAssetsManifest({
46
- integrity: false,
47
46
  entrypoints: true,
48
47
  writeToDisk: true,
49
48
  publicPath: config.publicPathWithoutCDN
@@ -65,7 +64,18 @@ const getEntryObject = () => {
65
64
  paths.forEach((path) => {
66
65
  const namespace = relative(join(rootPath), dirname(path))
67
66
  const name = join(namespace, basename(path, extname(path)))
68
- result.set(name, resolve(path))
67
+ let assetPaths = resolve(path)
68
+
69
+ // Allows for multiple filetypes per entry (https://webpack.js.org/guides/entry-advanced/)
70
+ // Transforms the config object value to an array with all values under the same name
71
+ let previousPaths = result.get(name)
72
+ if (previousPaths) {
73
+ previousPaths = Array.isArray(previousPaths) ? previousPaths : [previousPaths]
74
+ previousPaths.push(assetPaths)
75
+ assetPaths = previousPaths
76
+ }
77
+
78
+ result.set(name, assetPaths)
69
79
  })
70
80
  return result
71
81
  }
@@ -73,8 +83,8 @@ const getEntryObject = () => {
73
83
  const getModulePaths = () => {
74
84
  const result = new ConfigList()
75
85
  result.append('source', resolve(config.source_path))
76
- if (config.resolved_paths) {
77
- config.resolved_paths.forEach(path => result.append(path, resolve(path)))
86
+ if (config.additional_paths) {
87
+ config.additional_paths.forEach((path) => result.append(path, resolve(path)))
78
88
  }
79
89
  result.append('node_modules', 'node_modules')
80
90
  return result
@@ -126,7 +136,7 @@ module.exports = class Base {
126
136
  // https://twitter.com/wSokra/status/969633336732905474
127
137
  splitChunks: {
128
138
  chunks: 'all',
129
- name: false
139
+ name: true
130
140
  },
131
141
  // Separate runtime chunk to enable long term caching
132
142
  // https://twitter.com/wSokra/status/969679223278505985
@@ -153,7 +163,7 @@ module.exports = class Base {
153
163
 
154
164
  module: {
155
165
  strictExportPresence: true,
156
- rules: [{ parser: { requireEnsure: false } }, ...this.loaders.values()]
166
+ rules: this.loaders.values()
157
167
  },
158
168
 
159
169
  plugins: this.plugins.values(),