jetpacker 0.4.2 → 0.6.0

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 (90) 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 +58 -0
  7. data/.gitignore +1 -0
  8. data/.node-version +1 -1
  9. data/.rubocop.yml +113 -13
  10. data/.travis.yml +8 -21
  11. data/CHANGELOG.jetpacker.md +5 -0
  12. data/CHANGELOG.md +68 -2
  13. data/Gemfile +1 -0
  14. data/README.md +23 -649
  15. data/docs/css.md +58 -3
  16. data/docs/deployment.md +2 -2
  17. data/docs/docker.md +17 -17
  18. data/docs/engines.md +13 -0
  19. data/docs/env.md +0 -2
  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 +3 -1
  24. data/docs/typescript.md +92 -28
  25. data/docs/webpack-dev-server.md +1 -1
  26. data/gemfiles/Gemfile-rails-edge +1 -1
  27. data/jetpacker.gemspec +4 -3
  28. data/lib/install/config/babel.config.js +13 -3
  29. data/lib/install/config/webpacker.yml +1 -4
  30. data/lib/install/examples/react/babel.config.js +12 -0
  31. data/lib/install/examples/react/tsconfig.json +2 -1
  32. data/lib/install/examples/typescript/tsconfig.json +2 -1
  33. data/lib/install/loaders/svelte.js +2 -2
  34. data/lib/install/template.rb +11 -3
  35. data/lib/install/typescript.rb +6 -2
  36. data/lib/jetpacker/version.rb +1 -1
  37. data/lib/tasks/webpacker/check_node.rake +15 -8
  38. data/lib/tasks/webpacker/check_yarn.rake +16 -10
  39. data/lib/tasks/webpacker/clean.rake +12 -8
  40. data/lib/tasks/webpacker/clobber.rake +8 -4
  41. data/lib/tasks/webpacker/yarn_install.rake +11 -16
  42. data/lib/webpacker/commands.rb +33 -9
  43. data/lib/webpacker/compiler.rb +9 -5
  44. data/lib/webpacker/configuration.rb +28 -13
  45. data/lib/webpacker/dev_server_proxy.rb +3 -1
  46. data/lib/webpacker/dev_server_runner.rb +2 -2
  47. data/lib/webpacker/env.rb +5 -1
  48. data/lib/webpacker/helper.rb +37 -18
  49. data/lib/webpacker/manifest.rb +4 -4
  50. data/lib/webpacker/railtie.rb +0 -43
  51. data/lib/webpacker/runner.rb +1 -0
  52. data/lib/webpacker/turbine.rb +0 -41
  53. data/lib/webpacker/version.rb +1 -1
  54. data/lib/webpacker/webpack_runner.rb +2 -2
  55. data/package/__tests__/config.js +12 -1
  56. data/package/__tests__/dev_server.js +2 -0
  57. data/package/__tests__/development.js +14 -1
  58. data/package/config.js +4 -1
  59. data/package/configPath.js +3 -0
  60. data/package/dev_server.js +1 -1
  61. data/package/env.js +1 -2
  62. data/package/environments/__tests__/base.js +29 -2
  63. data/package/environments/base.js +17 -7
  64. data/package/environments/development.js +39 -37
  65. data/package/environments/production.js +1 -3
  66. data/package/rules/babel.js +12 -5
  67. data/package/rules/file.js +3 -2
  68. data/package/rules/node_modules.js +1 -3
  69. data/package/rules/sass.js +10 -1
  70. data/package/utils/helpers.js +1 -1
  71. data/package.json +41 -41
  72. data/test/compiler_test.rb +8 -3
  73. data/test/configuration_test.rb +8 -7
  74. data/test/dev_server_runner_test.rb +1 -1
  75. data/test/helper_test.rb +24 -9
  76. data/test/manifest_test.rb +37 -6
  77. data/test/rake_tasks_test.rb +11 -0
  78. data/test/test_app/app/javascript/packs/multi_entry.css +4 -0
  79. data/test/test_app/app/javascript/packs/multi_entry.js +4 -0
  80. data/test/test_app/config/application.rb +0 -1
  81. data/test/test_app/config/webpacker.yml +7 -1
  82. data/test/test_app/public/packs/manifest.json +1 -0
  83. data/test/webpack_runner_test.rb +1 -1
  84. data/yarn.lock +3895 -3945
  85. metadata +35 -15
  86. data/Gemfile.lock +0 -171
  87. data/gemfiles/Gemfile-rails.4.2.x +0 -9
  88. data/gemfiles/Gemfile-rails.5.0.x +0 -9
  89. data/gemfiles/Gemfile-rails.5.1.x +0 -9
  90. data/lib/install/loaders/typescript.js +0 -11
@@ -7,8 +7,8 @@ module Webpacker::Helper
7
7
  end
8
8
 
9
9
  # Computes the relative path for a given Webpacker asset.
10
- # Returns the 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
- # Returns the 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,7 +36,7 @@ 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
 
@@ -46,7 +46,16 @@ module Webpacker::Helper
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)
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
+
50
59
  image_tag(resolve_path_to_image(name), options)
51
60
  end
52
61
 
@@ -61,7 +70,7 @@ module Webpacker::Helper
61
70
  end
62
71
 
63
72
  # Creates a script tag that references the named pack file, as compiled by webpack per the entries list
64
- # 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
65
74
  # app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
66
75
  #
67
76
  # Example:
@@ -73,10 +82,11 @@ module Webpacker::Helper
73
82
  end
74
83
 
75
84
  # Creates script tags that reference the js chunks from entrypoints when using split chunks API,
76
- # as compiled by webpack per the entries list in config/webpack/shared.js.
85
+ # as compiled by webpack per the entries list in package/environments/base.js.
77
86
  # By default, this list is auto-generated to match everything in
78
87
  # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
79
88
  # See: https://webpack.js.org/plugins/split-chunks-plugin/
89
+ #
80
90
  # Example:
81
91
  #
82
92
  # <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
@@ -85,11 +95,15 @@ module Webpacker::Helper
85
95
  # <script src="/packs/calendar-1016838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
86
96
  # <script src="/packs/map~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
87
97
  # <script src="/packs/map-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
98
+ #
88
99
  # DO:
89
- # <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
100
+ #
101
+ # <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
102
+ #
90
103
  # DON'T:
91
- # <%= javascript_packs_with_chunks_tag 'calendar' %>
92
- # <%= javascript_packs_with_chunks_tag 'map' %>
104
+ #
105
+ # <%= javascript_packs_with_chunks_tag 'calendar' %>
106
+ # <%= javascript_packs_with_chunks_tag 'map' %>
93
107
  def javascript_packs_with_chunks_tag(*names, **options)
94
108
  javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options)
95
109
  end
@@ -97,6 +111,7 @@ module Webpacker::Helper
97
111
  # Creates a link tag, for preloading, that references a given Webpacker asset.
98
112
  # In production mode, the digested reference is automatically looked up.
99
113
  # See: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
114
+ #
100
115
  # Example:
101
116
  #
102
117
  # <%= preload_pack_asset 'fonts/fa-regular-400.woff2' %> # =>
@@ -110,7 +125,7 @@ module Webpacker::Helper
110
125
  end
111
126
 
112
127
  # Creates a link tag that references the named pack file, as compiled by webpack per the entries list
113
- # 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
114
129
  # app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
115
130
  #
116
131
  # Note: If the development server is running and hot module replacement is active, this will return nothing.
@@ -132,7 +147,7 @@ module Webpacker::Helper
132
147
  end
133
148
 
134
149
  # Creates link tags that reference the css chunks from entrypoints when using split chunks API,
135
- # as compiled by webpack per the entries list in config/webpack/shared.js.
150
+ # as compiled by webpack per the entries list in package/environments/base.js.
136
151
  # By default, this list is auto-generated to match everything in
137
152
  # app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
138
153
  # See: https://webpack.js.org/plugins/split-chunks-plugin/
@@ -143,11 +158,15 @@ module Webpacker::Helper
143
158
  # <link rel="stylesheet" media="screen" href="/packs/3-8c7ce31a.chunk.css" />
144
159
  # <link rel="stylesheet" media="screen" href="/packs/calendar-8c7ce31a.chunk.css" />
145
160
  # <link rel="stylesheet" media="screen" href="/packs/map-8c7ce31a.chunk.css" />
161
+ #
146
162
  # DO:
147
- # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
163
+ #
164
+ # <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
165
+ #
148
166
  # DON'T:
149
- # <%= stylesheet_packs_with_chunks_tag 'calendar' %>
150
- # <%= stylesheet_packs_with_chunks_tag 'map' %>
167
+ #
168
+ # <%= stylesheet_packs_with_chunks_tag 'calendar' %>
169
+ # <%= stylesheet_packs_with_chunks_tag 'map' %>
151
170
  def stylesheet_packs_with_chunks_tag(*names, **options)
152
171
  if current_webpacker_instance.config.extract_css?
153
172
  stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
@@ -169,8 +188,8 @@ module Webpacker::Helper
169
188
 
170
189
  def resolve_path_to_image(name)
171
190
  path = name.starts_with?("media/images/") ? name : "media/images/#{name}"
172
- asset_path(current_webpacker_instance.manifest.lookup!(path))
191
+ path_to_asset(current_webpacker_instance.manifest.lookup!(path))
173
192
  rescue
174
- asset_path(current_webpacker_instance.manifest.lookup!(name))
193
+ path_to_asset(current_webpacker_instance.manifest.lookup!(name))
175
194
  end
176
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
@@ -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."
@@ -7,49 +7,8 @@ module Webpacker
7
7
  initializer "webpacker.set_configs" do |app|
8
8
  # Allows Webpacker config values to be set via Jets env config files
9
9
  app.config.webpacker ||= ActiveSupport::OrderedOptions.new # TODO: all config access outside initializer block
10
-
11
- if app.config.webpacker.key?(:check_yarn_integrity)
12
- Webpacker.config.check_yarn_integrity = app.config.webpacker.check_yarn_integrity
13
- end
14
10
  end
15
11
 
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 unless ENV['AWS_LAMBDA_FUNCTION_NAME'] # dont run yarn check on lambda
52
-
53
12
  # TODO: add support load middleware in a Turbine
54
13
  # initializer "webpacker.proxy" do |app|
55
14
  # insert_middleware = Webpacker.config.dev_server.present? rescue nil
@@ -1,4 +1,4 @@
1
1
  module Webpacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "4.2.2".freeze
3
+ VERSION = "5.4.3".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
@@ -23,6 +23,16 @@ describe('Config', () => {
23
23
  expect(config.publicPath).toEqual('http://foo.com/packs/')
24
24
  })
25
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
+
26
36
  test('should return extensions as listed in app config', () => {
27
37
  expect(config.extensions).toEqual([
28
38
  '.mjs',
@@ -37,7 +47,8 @@ describe('Config', () => {
37
47
  '.svg',
38
48
  '.gif',
39
49
  '.jpeg',
40
- '.jpg'
50
+ '.jpg',
51
+ '.elm'
41
52
  ])
42
53
  })
43
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,6 +24,9 @@ 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 = () => {
@@ -0,0 +1,3 @@
1
+ const { resolve } = require('path')
2
+
3
+ module.exports = process.env.WEBPACKER_CONFIG || resolve('config', 'webpacker.yml')
@@ -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
  })
@@ -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(),
@@ -7,45 +7,47 @@ module.exports = class extends Base {
7
7
  constructor() {
8
8
  super()
9
9
 
10
- if (devServer.hmr) {
11
- this.plugins.append('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
12
- this.config.output.filename = '[name]-[hash].js'
13
- }
14
-
15
10
  this.config.merge({
16
11
  mode: 'development',
17
- cache: true,
18
- devtool: 'cheap-module-source-map',
19
- output: {
20
- pathinfo: true
21
- },
22
- devServer: {
23
- clientLogLevel: 'none',
24
- compress: devServer.compress,
25
- quiet: devServer.quiet,
26
- disableHostCheck: devServer.disable_host_check,
27
- host: devServer.host,
28
- port: devServer.port,
29
- https: devServer.https,
30
- hot: devServer.hmr,
31
- contentBase,
32
- inline: devServer.inline,
33
- useLocalIp: devServer.use_local_ip,
34
- public: devServer.public,
35
- publicPath,
36
- historyApiFallback: {
37
- disableDotRule: true
38
- },
39
- headers: devServer.headers,
40
- overlay: devServer.overlay,
41
- stats: {
42
- entrypoints: false,
43
- errorDetails: true,
44
- modules: false,
45
- moduleTrace: false
46
- },
47
- watchOptions: devServer.watch_options
48
- }
12
+ devtool: 'cheap-module-source-map'
49
13
  })
14
+
15
+ if (process.env.WEBPACK_DEV_SERVER
16
+ && process.env.WEBPACK_DEV_SERVER !== 'undefined') {
17
+ if (devServer.hmr) {
18
+ this.plugins.append('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
19
+ this.config.output.filename = '[name]-[hash].js'
20
+ }
21
+
22
+ this.config.merge({
23
+ devServer: {
24
+ clientLogLevel: 'none',
25
+ compress: devServer.compress,
26
+ quiet: devServer.quiet,
27
+ disableHostCheck: devServer.disable_host_check,
28
+ host: devServer.host,
29
+ port: devServer.port,
30
+ https: devServer.https,
31
+ hot: devServer.hmr,
32
+ contentBase,
33
+ inline: devServer.inline,
34
+ useLocalIp: devServer.use_local_ip,
35
+ public: devServer.public,
36
+ publicPath,
37
+ historyApiFallback: {
38
+ disableDotRule: true
39
+ },
40
+ headers: devServer.headers,
41
+ overlay: devServer.overlay,
42
+ stats: {
43
+ entrypoints: false,
44
+ errorDetails: true,
45
+ modules: false,
46
+ moduleTrace: false
47
+ },
48
+ watchOptions: devServer.watch_options
49
+ }
50
+ })
51
+ }
50
52
  }
51
53
  }
@@ -13,7 +13,6 @@ module.exports = class extends Base {
13
13
  new CompressionPlugin({
14
14
  filename: '[path].gz[query]',
15
15
  algorithm: 'gzip',
16
- cache: true,
17
16
  test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
18
17
  })
19
18
  )
@@ -24,7 +23,6 @@ module.exports = class extends Base {
24
23
  new CompressionPlugin({
25
24
  filename: '[path].br[query]',
26
25
  algorithm: 'brotliCompress',
27
- cache: true,
28
26
  test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
29
27
  })
30
28
  )
@@ -48,7 +46,7 @@ module.exports = class extends Base {
48
46
  optimization: {
49
47
  minimizer: [
50
48
  new TerserPlugin({
51
- parallel: true,
49
+ parallel: Number.parseInt(process.env.WEBPACKER_PARALLEL, 10) || true,
52
50
  cache: true,
53
51
  sourceMap: true,
54
52
  terserOptions: {