shakapacker 6.6.0 → 7.0.0.rc.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 (197) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-backward-compatibility.yml +43 -0
  3. data/CHANGELOG.md +50 -4
  4. data/CONTRIBUTING.md +4 -4
  5. data/Gemfile.development_dependencies +1 -1
  6. data/README.md +113 -88
  7. data/Rakefile +5 -0
  8. data/config/shakapacker.yml +1 -0
  9. data/docs/deployment.md +12 -10
  10. data/docs/developing_webpacker.md +5 -5
  11. data/docs/react.md +10 -6
  12. data/docs/style_loader_vs_mini_css.md +2 -2
  13. data/docs/troubleshooting.md +22 -18
  14. data/docs/using_esbuild_loader.md +5 -3
  15. data/docs/using_swc_loader.md +2 -2
  16. data/docs/v6_upgrade.md +2 -2
  17. data/docs/v7_upgrade.md +56 -0
  18. data/lib/install/bin/shakapacker +13 -0
  19. data/lib/install/bin/shakapacker-dev-server +13 -0
  20. data/lib/install/config/{webpacker.yml → shakapacker.yml} +13 -8
  21. data/lib/install/template.rb +7 -7
  22. data/lib/{webpacker → shakapacker}/base_strategy.rb +2 -2
  23. data/lib/{webpacker → shakapacker}/commands.rb +4 -4
  24. data/lib/{webpacker → shakapacker}/compiler.rb +43 -15
  25. data/lib/{webpacker → shakapacker}/compiler_strategy.rb +6 -6
  26. data/lib/{webpacker → shakapacker}/configuration.rb +52 -21
  27. data/lib/shakapacker/deprecation_helper.rb +88 -0
  28. data/lib/{webpacker → shakapacker}/dev_server.rb +27 -4
  29. data/lib/{webpacker → shakapacker}/dev_server_proxy.rb +4 -4
  30. data/lib/shakapacker/dev_server_runner.rb +104 -0
  31. data/lib/{webpacker → shakapacker}/digest_strategy.rb +6 -6
  32. data/lib/{webpacker → shakapacker}/env.rb +8 -8
  33. data/lib/{webpacker → shakapacker}/helper.rb +20 -20
  34. data/lib/{webpacker → shakapacker}/instance.rb +13 -10
  35. data/lib/{webpacker → shakapacker}/manifest.rb +14 -14
  36. data/lib/{webpacker → shakapacker}/mtime_strategy.rb +5 -5
  37. data/lib/shakapacker/railtie.rb +70 -0
  38. data/lib/shakapacker/runner.rb +28 -0
  39. data/lib/shakapacker/utils/version_syntax_converter.rb +2 -2
  40. data/lib/{webpacker → shakapacker}/version.rb +2 -2
  41. data/lib/{webpacker → shakapacker}/version_checker.rb +8 -8
  42. data/lib/shakapacker/webpack_runner.rb +67 -0
  43. data/lib/shakapacker.rb +51 -1
  44. data/lib/tasks/shakapacker/binstubs.rake +15 -0
  45. data/lib/tasks/shakapacker/check_binstubs.rake +25 -0
  46. data/lib/tasks/shakapacker/check_node.rake +31 -0
  47. data/lib/tasks/shakapacker/check_yarn.rake +33 -0
  48. data/lib/tasks/shakapacker/clean.rake +23 -0
  49. data/lib/tasks/shakapacker/clobber.rake +18 -0
  50. data/lib/tasks/shakapacker/compile.rake +31 -0
  51. data/lib/tasks/shakapacker/info.rake +21 -0
  52. data/lib/tasks/shakapacker/install.rake +17 -0
  53. data/lib/tasks/shakapacker/verify_config.rake +12 -0
  54. data/lib/tasks/shakapacker/verify_install.rake +4 -0
  55. data/lib/tasks/shakapacker/yarn_install.rake +24 -0
  56. data/lib/tasks/shakapacker.rake +18 -0
  57. data/lib/tasks/webpacker/binstubs.rake +5 -11
  58. data/lib/tasks/webpacker/check_binstubs.rake +6 -9
  59. data/lib/tasks/webpacker/check_node.rake +5 -27
  60. data/lib/tasks/webpacker/check_yarn.rake +5 -29
  61. data/lib/tasks/webpacker/clean.rake +5 -19
  62. data/lib/tasks/webpacker/clobber.rake +6 -13
  63. data/lib/tasks/webpacker/compile.rake +5 -33
  64. data/lib/tasks/webpacker/info.rake +5 -17
  65. data/lib/tasks/webpacker/install.rake +5 -13
  66. data/lib/tasks/webpacker/verify_config.rake +6 -11
  67. data/lib/tasks/webpacker/verify_install.rake +7 -2
  68. data/lib/tasks/webpacker/yarn_install.rake +5 -20
  69. data/lib/tasks/webpacker.rake +15 -13
  70. data/lib/webpacker/dev_server_runner.rb +9 -96
  71. data/lib/webpacker/webpack_runner.rb +9 -58
  72. data/lib/webpacker.rb +3 -47
  73. data/package/__tests__/config-bc.js +27 -0
  74. data/package/__tests__/config.js +6 -5
  75. data/package/__tests__/dev_server-bc.js +46 -0
  76. data/package/__tests__/dev_server.js +9 -8
  77. data/package/__tests__/development-bc.js +66 -0
  78. data/package/__tests__/development.js +36 -5
  79. data/package/__tests__/env-bc.js +59 -0
  80. data/package/__tests__/env.js +3 -2
  81. data/package/__tests__/index.js +13 -0
  82. data/package/__tests__/production-bc.js +51 -0
  83. data/package/__tests__/production.js +25 -3
  84. data/package/__tests__/staging-bc.js +53 -0
  85. data/package/__tests__/staging.js +27 -4
  86. data/package/__tests__/test-bc.js +43 -0
  87. data/package/__tests__/test.js +22 -4
  88. data/package/babel/preset.js +1 -4
  89. data/package/config.js +25 -7
  90. data/package/dev_server.js +7 -4
  91. data/package/env.js +22 -3
  92. data/package/environments/__tests__/base-bc.js +107 -0
  93. data/package/environments/__tests__/base.js +13 -13
  94. data/package/environments/base.js +1 -1
  95. data/package/environments/development.js +4 -46
  96. data/package/environments/production.js +1 -1
  97. data/package/index.js +11 -4
  98. data/package/rules/__tests__/__utils__/webpack.js +1 -1
  99. data/package/rules/__tests__/file.js +27 -0
  100. data/package/rules/__tests__/swc.js +1 -2
  101. data/package/rules/file.js +2 -2
  102. data/package/utils/configPath.js +19 -0
  103. data/package/utils/defaultConfigPath.js +2 -0
  104. data/package/utils/get_style_rule.js +5 -2
  105. data/package/utils/helpers.js +24 -1
  106. data/package/utils/inliningCss.js +7 -0
  107. data/package/utils/snakeToCamelCase +7 -0
  108. data/package/webpackDevServerConfig.js +68 -0
  109. data/package.json +2 -2
  110. data/{webpacker.gemspec → shakapacker.gemspec} +3 -3
  111. data/spec/backward_compatibility_specs/command_spec_bc.rb +116 -0
  112. data/spec/backward_compatibility_specs/compiler_spec_bc.rb +59 -0
  113. data/spec/backward_compatibility_specs/compiler_strategy_spec_bc.rb +22 -0
  114. data/spec/backward_compatibility_specs/configuration_spec_bc.rb +286 -0
  115. data/spec/backward_compatibility_specs/dev_server_runner_spec_bc.rb +79 -0
  116. data/spec/backward_compatibility_specs/dev_server_spec_bc.rb +47 -0
  117. data/spec/backward_compatibility_specs/digest_strategy_spec_bc.rb +35 -0
  118. data/spec/backward_compatibility_specs/engine_rake_tasks_spec_bc.rb +44 -0
  119. data/spec/backward_compatibility_specs/env_spec_bc.rb +23 -0
  120. data/spec/backward_compatibility_specs/helper_spec_bc.rb +243 -0
  121. data/spec/backward_compatibility_specs/instance_spec_bc.rb +31 -0
  122. data/spec/backward_compatibility_specs/manifest_spec_bc.rb +100 -0
  123. data/spec/backward_compatibility_specs/mtime_strategy_spec_bc.rb +55 -0
  124. data/spec/backward_compatibility_specs/rake_tasks_spec_bc.rb +37 -0
  125. data/spec/backward_compatibility_specs/spec_helper_initializer.rb +24 -0
  126. data/spec/backward_compatibility_specs/webpack_runner_spec_bc.rb +56 -0
  127. data/spec/backward_compatibility_specs/webpacker_spec_bc.rb +41 -0
  128. data/spec/backward_compatibility_specs/webpacker_test_app/.gitignore +2 -0
  129. data/spec/backward_compatibility_specs/webpacker_test_app/Rakefile +3 -0
  130. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/app/packs/entrypoints/application.js +1 -1
  131. data/{lib/install → spec/backward_compatibility_specs/webpacker_test_app}/bin/webpacker +0 -0
  132. data/spec/backward_compatibility_specs/webpacker_test_app/config/application.rb +11 -0
  133. data/spec/backward_compatibility_specs/webpacker_test_app/config/environment.rb +4 -0
  134. data/spec/backward_compatibility_specs/webpacker_test_app/config/initializers/inspect_autoload_paths.rb +1 -0
  135. data/spec/backward_compatibility_specs/webpacker_test_app/config/webpack/webpack.config.js +0 -0
  136. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker.yml +1 -1
  137. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_css_extract_ignore_order_warnings.yml +1 -1
  138. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_defaults_fallback.yml +1 -1
  139. data/spec/backward_compatibility_specs/webpacker_test_app/config/webpacker_no_precompile.yml +7 -0
  140. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_other_location.yml +1 -1
  141. data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_public_root.yml +1 -1
  142. data/spec/backward_compatibility_specs/webpacker_test_app/config.ru +5 -0
  143. data/spec/backward_compatibility_specs/webpacker_test_app/package.json +13 -0
  144. data/spec/backward_compatibility_specs/webpacker_test_app/public/packs/manifest.json +58 -0
  145. data/spec/backward_compatibility_specs/webpacker_test_app/some.config.js +0 -0
  146. data/spec/backward_compatibility_specs/webpacker_test_app/tmp/shakapacker/last-compilation-digest-production +1 -0
  147. data/spec/backward_compatibility_specs/webpacker_test_app/yarn.lock +11 -0
  148. data/spec/command_spec.rb +18 -16
  149. data/spec/compiler_spec.rb +19 -17
  150. data/spec/compiler_strategy_spec.rb +9 -7
  151. data/spec/configuration_spec.rb +108 -66
  152. data/spec/dev_server_runner_spec.rb +9 -8
  153. data/spec/dev_server_spec.rb +97 -9
  154. data/spec/digest_strategy_spec.rb +4 -2
  155. data/spec/engine_rake_tasks_spec.rb +12 -16
  156. data/spec/env_spec.rb +7 -5
  157. data/spec/helper_spec.rb +4 -2
  158. data/spec/instance_spec.rb +31 -0
  159. data/spec/manifest_spec.rb +21 -19
  160. data/spec/mounted_app/test/dummy/config/application.rb +1 -1
  161. data/spec/mounted_app/test/dummy/config/webpacker.yml +3 -3
  162. data/spec/mtime_strategy_spec.rb +4 -2
  163. data/spec/rake_tasks_spec.rb +20 -18
  164. data/spec/spec_helper.rb +0 -25
  165. data/spec/spec_helper_initializer.rb +24 -0
  166. data/spec/test_app/.gitignore +2 -0
  167. data/spec/test_app/app/javascript/entrypoints/application.js +10 -0
  168. data/spec/test_app/app/javascript/entrypoints/generated/something.js +2 -0
  169. data/spec/test_app/app/javascript/entrypoints/multi_entry.css +4 -0
  170. data/spec/test_app/app/javascript/entrypoints/multi_entry.js +4 -0
  171. data/spec/test_app/bin/{webpacker-dev-server → shakapacker} +3 -3
  172. data/spec/test_app/bin/{webpacker → shakapacker-dev-server} +3 -3
  173. data/spec/test_app/config/application.rb +1 -1
  174. data/spec/test_app/config/shakapacker.yml +82 -0
  175. data/spec/test_app/config/shakapacker_css_extract_ignore_order_warnings.yml +84 -0
  176. data/spec/test_app/config/shakapacker_defaults_fallback.yml +11 -0
  177. data/spec/test_app/config/shakapacker_manifest_path.yml +80 -0
  178. data/spec/test_app/config/shakapacker_nested_entries.yml +83 -0
  179. data/spec/test_app/config/shakapacker_no_precompile.yml +7 -0
  180. data/spec/test_app/config/shakapacker_other_location.yml +85 -0
  181. data/spec/test_app/config/shakapacker_public_root.yml +18 -0
  182. data/spec/version_checker_spec.rb +16 -15
  183. data/spec/webpack_runner_spec.rb +4 -3
  184. data/spec/webpacker_spec.rb +9 -29
  185. metadata +119 -44
  186. data/config/webpacker.yml +0 -1
  187. data/lib/webpacker/railtie.rb +0 -70
  188. data/lib/webpacker/runner.rb +0 -23
  189. data/package/configPath.js +0 -3
  190. data/package/inliningCss.js +0 -7
  191. data/spec/test_app/config/webpacker_no_precompile.yml +0 -7
  192. /data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/app/packs/entrypoints/generated/something.js +0 -0
  193. /data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/app/packs/entrypoints/multi_entry.css +0 -0
  194. /data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/app/packs/entrypoints/multi_entry.js +0 -0
  195. /data/{lib/install → spec/backward_compatibility_specs/webpacker_test_app}/bin/webpacker-dev-server +0 -0
  196. /data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_manifest_path.yml +0 -0
  197. /data/spec/{test_app → backward_compatibility_specs/webpacker_test_app}/config/webpacker_nested_entries.yml +0 -0
@@ -0,0 +1,68 @@
1
+ const shakapackerDevServerYamlConfig = require('./dev_server')
2
+ const snakeToCamelCase = require('./utils/snakeToCamelCase')
3
+ const { outputPath: contentBase, publicPath } = require('./config')
4
+
5
+ const webpackDevServerMappedKeys = new Set([
6
+ // client, server, liveReload, devMiddleware are handled separately
7
+ 'allowedHosts',
8
+ 'bonjour',
9
+ 'compress',
10
+ 'headers',
11
+ 'historyApiFallback',
12
+ 'host',
13
+ 'hot',
14
+ 'http2',
15
+ 'https',
16
+ 'ipc',
17
+ 'magicHtml',
18
+ 'onAfterSetupMiddleware',
19
+ 'onBeforeSetupMiddleware',
20
+ 'open',
21
+ 'port',
22
+ 'proxy',
23
+ 'server',
24
+ 'setupExitSignals',
25
+ 'setupMiddlewares',
26
+ 'watchFiles',
27
+ 'webSocketServer'
28
+ ])
29
+
30
+ function createDevServerConfig() {
31
+ const devServerYamlConfig = { ...shakapackerDevServerYamlConfig }
32
+ const liveReload = devServerYamlConfig.live_reload !== undefined ? devServerYamlConfig.live_reload : !devServerYamlConfig.hmr
33
+ delete devServerYamlConfig.live_reload
34
+
35
+ const config = {
36
+ devMiddleware: {
37
+ publicPath
38
+ },
39
+ liveReload,
40
+ historyApiFallback: {
41
+ disableDotRule: true
42
+ },
43
+ static: {
44
+ publicPath: contentBase
45
+ }
46
+ }
47
+
48
+ if (devServerYamlConfig.static) {
49
+ config.static = { ...config.static, ...devServerYamlConfig.static }
50
+ delete devServerYamlConfig.static
51
+ }
52
+
53
+ if (devServerYamlConfig.client) {
54
+ config.client = devServerYamlConfig.client
55
+ delete devServerYamlConfig.client
56
+ }
57
+
58
+ Object.keys(devServerYamlConfig).forEach((yamlKey) => {
59
+ const camelYamlKey = snakeToCamelCase(yamlKey)
60
+ if (webpackDevServerMappedKeys.has(camelYamlKey)) {
61
+ config[camelYamlKey] = devServerYamlConfig[yamlKey]
62
+ }
63
+ })
64
+
65
+ return config
66
+ }
67
+
68
+ module.exports = createDevServerConfig
data/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "6.6.0",
3
+ "version": "7.0.0-rc.0",
4
4
  "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
5
  "main": "package/index.js",
6
6
  "files": [
7
7
  "package",
8
- "lib/install/config/webpacker.yml"
8
+ "lib/install/config/shakapacker.yml"
9
9
  ],
10
10
  "engines": {
11
11
  "node": "^12.13.0 || ^14 || >=16",
@@ -1,16 +1,16 @@
1
1
  $:.push File.expand_path("../lib", __FILE__)
2
- require "webpacker/version"
2
+ require "shakapacker/version"
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "shakapacker"
6
- s.version = Webpacker::VERSION
6
+ s.version = Shakapacker::VERSION
7
7
  s.authors = [ "David Heinemeier Hansson", "Gaurav Tiwari", "Justin Gordon" ]
8
8
  s.email = [ "david@basecamp.com", "gaurav@gauravtiwari.co.uk", "justin@shakacode.com" ]
9
9
  s.summary = "Use webpack to manage app-like JavaScript modules in Rails"
10
10
  s.homepage = "https://github.com/shakacode/shakapacker"
11
11
  s.license = "MIT"
12
12
 
13
- npm_version = Webpacker::VERSION.gsub(".rc", "-rc")
13
+ npm_version = Shakapacker::VERSION.gsub(".rc", "-rc")
14
14
  s.metadata = {
15
15
  "source_code_uri" => "https://github.com/shakacode/shakapacker/tree/v#{npm_version}",
16
16
  }
@@ -0,0 +1,116 @@
1
+ require_relative "spec_helper_initializer"
2
+
3
+ describe "Command" do
4
+ before do
5
+ allow(Webpacker.logger).to receive(:info)
6
+ end
7
+
8
+ describe "#compile" do
9
+ it "returns success status when stale" do
10
+ expect(Webpacker.compiler).to receive(:stale?).and_return(true)
11
+ expect(Webpacker.compiler).to receive(:run_webpack).and_return(true)
12
+
13
+ expect(Webpacker.commands.compile).to be true
14
+ end
15
+
16
+ it "returns success status when fresh" do
17
+ expect(Webpacker.compiler).to receive(:stale?).and_return(false)
18
+
19
+ expect(Webpacker.commands.compile).to be true
20
+ end
21
+
22
+ it "returns failure status when stale" do
23
+ expect(Webpacker.compiler).to receive(:stale?).and_return(true)
24
+ expect(Webpacker.compiler).to receive(:run_webpack).and_return(false)
25
+
26
+ expect(Webpacker.commands.compile).to be false
27
+ end
28
+ end
29
+
30
+ describe "#clean" do
31
+ let(:now) { Time.parse("2021-01-01 12:34:56 UTC") }
32
+ let(:prev_files) do
33
+ # Test assets to be kept and deleted, path and mtime
34
+ {
35
+ # recent versions to be kept with Webpacker.commands.clean(count = 2)
36
+ "js/application-deadbeef.js" => now - 4000,
37
+ "js/common-deadbeee.js" => now - 4002,
38
+ "css/common-deadbeed.css" => now - 4004,
39
+ "media/images/logo-deadbeeb.css" => now - 4006,
40
+ "js/application-1eadbeef.js" => now - 8000,
41
+ "js/common-1eadbeee.js" => now - 8002,
42
+ "css/common-1eadbeed.css" => now - 8004,
43
+ "media/images/logo-1eadbeeb.css" => now - 8006,
44
+ # new files to be kept with Webpacker.commands.clean(age = 3600)
45
+ "js/brandnew-0001.js" => now,
46
+ "js/brandnew-0002.js" => now - 10,
47
+ "js/brandnew-0003.js" => now - 20,
48
+ "js/brandnew-0004.js" => now - 40,
49
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
50
+ end
51
+
52
+ let(:expired_files) do
53
+ {
54
+ # old files that are outside count = 2 or age = 3600 and to be deleted
55
+ "js/application-0eadbeef.js" => now - 9000,
56
+ "js/common-0eadbeee.js" => now - 9002,
57
+ "css/common-0eadbeed.css" => now - 9004,
58
+ "js/brandnew-0005.js" => now - 3640,
59
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
60
+ end
61
+
62
+ let(:all_files) { prev_files.merge(expired_files) }
63
+
64
+ let(:file_delete_mock) { double("File Delete") }
65
+ let(:file_mtime_stub) { Proc.new { |longpath| all_files[longpath] } }
66
+ let(:file_delete_stub) { Proc.new { |longpath| file_delete_mock.delete(longpath) } }
67
+
68
+ before :context do
69
+ @dir_glob_stub = Proc.new { |arg|
70
+ case arg
71
+ when "#{Webpacker.config.public_output_path}/**/*"
72
+ all_files.keys
73
+ else
74
+ []
75
+ end
76
+ }
77
+ end
78
+
79
+ it "works with nested hashes and without any compiled files" do
80
+ allow(File).to receive(:delete).and_return(true)
81
+ expect(Webpacker.commands.clean).to be true
82
+ end
83
+
84
+ it "deletes only and only expired versioned files if no parameter passed" do
85
+ all_files.keys.each do |longpath|
86
+ allow(file_delete_mock).to receive(:delete).with(longpath)
87
+ end
88
+
89
+ with_time_dir_and_files_stub do
90
+ expect(Webpacker.commands.clean).to be true
91
+
92
+ # Verify that only and only expired files are deleted
93
+ all_files.keys.each do |longpath|
94
+ if expired_files.has_key? longpath
95
+ expect(file_delete_mock).to have_received(:delete).with(longpath)
96
+ else
97
+ expect(file_delete_mock).to_not have_received(:delete).with(longpath)
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def with_time_dir_and_files_stub(&proc)
106
+ allow(Time).to receive(:now).and_return(now)
107
+ allow(Dir).to receive(:glob) { |arg| @dir_glob_stub.call(arg) }
108
+ allow(File).to receive(:directory?).and_return(false)
109
+ allow(File).to receive(:file?).and_return(true)
110
+ allow(File).to receive(:mtime) { |arg| file_mtime_stub.call(arg) }
111
+ allow(File).to receive(:delete) { |arg| file_delete_stub.call(arg) }
112
+
113
+ yield proc
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,59 @@
1
+ require_relative "spec_helper_initializer"
2
+
3
+ describe "Webpacker::Compiler" do
4
+ it "accepts custom environment variables" do
5
+ expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to be nil
6
+
7
+ Webpacker.compiler.env["FOO"] = "BAR"
8
+ expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to eq "BAR"
9
+ ensure
10
+ Webpacker.compiler.env = {}
11
+ end
12
+
13
+ it "returns true when fresh" do
14
+ mocked_strategy = double("Strategy")
15
+ expect(mocked_strategy).to receive(:stale?).and_return(false)
16
+
17
+ expect(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
18
+
19
+ expect(Webpacker.compiler.compile).to be true
20
+ end
21
+
22
+ it "returns true and calls after_compile_hook on successful compile" do
23
+ mocked_strategy = spy("Strategy")
24
+ expect(mocked_strategy).to receive(:stale?).and_return(true)
25
+
26
+ allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
27
+
28
+ status = OpenStruct.new(success?: true)
29
+ allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
30
+
31
+ expect(Webpacker.compiler.compile).to be true
32
+ expect(mocked_strategy).to have_received(:after_compile_hook)
33
+ end
34
+
35
+ it "returns false and calls after_compile_hook on failed compile" do
36
+ mocked_strategy = spy("Strategy")
37
+ allow(mocked_strategy).to receive(:stale?).and_return(true)
38
+ allow(mocked_strategy).to receive(:after_compile_hook)
39
+
40
+ allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
41
+
42
+ status = OpenStruct.new(success?: false)
43
+ allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
44
+
45
+ expect(Webpacker.compiler.compile).to be false
46
+ expect(mocked_strategy).to have_received(:after_compile_hook)
47
+ end
48
+
49
+ it "accepts external env variables" do
50
+ expect(Webpacker.compiler.send(:webpack_env)["SHAKAPACKER_ASSET_HOST"]).to be nil
51
+ expect(Webpacker.compiler.send(:webpack_env)["SHAKAPACKER_RELATIVE_URL_ROOT"]).to be nil
52
+
53
+ ENV["WEBPACKER_ASSET_HOST"] = "foo.bar"
54
+ ENV["WEBPACKER_RELATIVE_URL_ROOT"] = "/baz"
55
+
56
+ expect(Webpacker.compiler.send(:webpack_env)["SHAKAPACKER_ASSET_HOST"]).to eq "foo.bar"
57
+ expect(Webpacker.compiler.send(:webpack_env)["SHAKAPACKER_RELATIVE_URL_ROOT"]).to eq "/baz"
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "spec_helper_initializer"
2
+
3
+ describe "Webpacker::CompilerStrategy" do
4
+ describe "#from_config" do
5
+ it "returns and instance of MtimeStrategy when compiler_strategy is set to mtime" do
6
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("mtime")
7
+ expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::MtimeStrategy)
8
+ end
9
+
10
+ it "returns and instance of DigestStrategy when compiler_strategy is set to digest" do
11
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("digest")
12
+ expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::DigestStrategy)
13
+ end
14
+
15
+ it "raise exception for unknown compiler_strategy in the config file" do
16
+ expected_error_message = "Unknown strategy 'other'. Available options are 'mtime' and 'digest'."
17
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("other")
18
+
19
+ expect { Webpacker::CompilerStrategy.from_config }.to raise_error(expected_error_message)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,286 @@
1
+ require_relative "spec_helper_initializer"
2
+
3
+ describe "Webpacker::Configuration" do
4
+ ROOT_PATH = Pathname.new(File.expand_path("webpacker_test_app", __dir__))
5
+
6
+ context "with standard webpacker.yml" do
7
+ let(:config) do
8
+ Webpacker::Configuration.new(
9
+ root_path: ROOT_PATH,
10
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker.yml", __dir__)),
11
+ env: "production"
12
+ )
13
+ end
14
+
15
+ it "#source_path returns correct path" do
16
+ source_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/app/packs").to_s
17
+ expect(config.source_path.to_s).to eq source_path
18
+ end
19
+
20
+ it "#source_entry_path returns correct path" do
21
+ source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/app/packs", "entrypoints").to_s
22
+ expect(config.source_entry_path.to_s).to eq source_entry_path
23
+ end
24
+
25
+ it "#public_root_path returns correct path" do
26
+ public_root_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/public").to_s
27
+ expect(config.public_path.to_s).to eq public_root_path
28
+ end
29
+
30
+ it "#public_output_path returns correct path" do
31
+ public_output_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/public/packs").to_s
32
+ expect(config.public_output_path.to_s).to eq public_output_path
33
+ end
34
+
35
+ it "#public_manifest_path returns correct path" do
36
+ public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/public/packs", "manifest.json").to_s
37
+ expect(config.public_manifest_path.to_s).to eq public_manifest_path
38
+ end
39
+
40
+ it "#manifest_path returns correct path" do
41
+ manifest_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/public/packs", "manifest.json").to_s
42
+ expect(config.manifest_path.to_s).to eq manifest_path
43
+ end
44
+
45
+ it "#cache_path returns correct path" do
46
+ cache_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/tmp/webpacker").to_s
47
+ expect(config.cache_path.to_s).to eq cache_path
48
+ end
49
+
50
+ it "#additional_paths returns correct path" do
51
+ expect(config.additional_paths).to eq ["app/assets", "/etc/yarn", "some.config.js", "app/elm"]
52
+ end
53
+
54
+ describe "#cache_manifest?" do
55
+ it "returns true in production environment" do
56
+ expect(config.cache_manifest?).to be true
57
+ end
58
+
59
+ it "returns false in developemnt environemnt" do
60
+ with_rails_env("development") do
61
+ expect(Webpacker.config.cache_manifest?).to be false
62
+ end
63
+ end
64
+
65
+ it "returns false in test environment" do
66
+ with_rails_env("test") do
67
+ expect(Webpacker.config.cache_manifest?).to be false
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "#compile?" do
73
+ it "returns false in production environment" do
74
+ expect(config.compile?).to be false
75
+ end
76
+
77
+ it "returns true in developemnt environemnt" do
78
+ with_rails_env("development") do
79
+ expect(Webpacker.config.compile?).to be true
80
+ end
81
+ end
82
+
83
+ it "returns true in test environemnt" do
84
+ with_rails_env("test") do
85
+ expect(Webpacker.config.compile?).to be true
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "#nested_entries?" do
91
+ it "returns false in production environment" do
92
+ expect(config.nested_entries?).to be false
93
+ end
94
+
95
+ it "returns false in development environment" do
96
+ with_rails_env("development") do
97
+ expect(Webpacker.config.nested_entries?).to be false
98
+ end
99
+ end
100
+
101
+ it "returns false in test environment" do
102
+ with_rails_env("test") do
103
+ expect(Webpacker.config.nested_entries?).to be false
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#ensure_consistent_versioning?" do
109
+ it "returns false in production environment" do
110
+ expect(config.ensure_consistent_versioning?).to be false
111
+ end
112
+
113
+ it "returns true in development environment" do
114
+ with_rails_env("development") do
115
+ expect(Webpacker.config.ensure_consistent_versioning?).to be true
116
+ end
117
+ end
118
+
119
+ it "returns false in test environment" do
120
+ with_rails_env("test") do
121
+ expect(Webpacker.config.ensure_consistent_versioning?).to be false
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#webpacker_precompile?" do
127
+ before :each do
128
+ ENV.delete("SHAKAPACKER_PRECOMPILE")
129
+ ENV.delete("WEBPACKER_PRECOMPILE")
130
+ end
131
+
132
+ subject { config.webpacker_precompile? }
133
+
134
+ it "returns true when WEBPACKER_PRECOMPILE is unset" do
135
+ is_expected.to be true
136
+ end
137
+
138
+ it "returns false when WEBPACKER_PRECOMPILE sets to no" do
139
+ ENV["WEBPACKER_PRECOMPILE"] = "no"
140
+ is_expected.to be false
141
+ end
142
+
143
+ it "returns true when WEBPACKER_PRECOMPILE sets to yes" do
144
+ ENV["WEBPACKER_PRECOMPILE"] = "yes"
145
+ is_expected.to be true
146
+ end
147
+
148
+ it "returns false when WEBPACKER_PRECOMPILE sets to false" do
149
+ ENV["WEBPACKER_PRECOMPILE"] = "false"
150
+ is_expected.to be false
151
+ end
152
+
153
+ it "returns true when WEBPACKER_PRECOMPILE sets to true" do
154
+ ENV["WEBPACKER_PRECOMPILE"] = "true"
155
+ is_expected.to be true
156
+ end
157
+
158
+ it "returns false when WEBPACKER_PRECOMPILE sets to n" do
159
+ ENV["WEBPACKER_PRECOMPILE"] = "n"
160
+ is_expected.to be false
161
+ end
162
+
163
+ it "returns true when WEBPACKER_PRECOMPILE sets to y" do
164
+ ENV["WEBPACKER_PRECOMPILE"] = "y"
165
+ is_expected.to be true
166
+ end
167
+
168
+ it "returns false when WEBPACKER_PRECOMPILE sets to f" do
169
+ ENV["WEBPACKER_PRECOMPILE"] = "f"
170
+ is_expected.to be false
171
+ end
172
+
173
+ it "returns true when WEBPACKER_PRECOMPILE sets to t" do
174
+ ENV["WEBPACKER_PRECOMPILE"] = "t"
175
+ is_expected.to be true
176
+ end
177
+ end
178
+ end
179
+
180
+ context "with webpacker config file containing public_output_path entry" do
181
+ config = Webpacker::Configuration.new(
182
+ root_path: ROOT_PATH,
183
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker_public_root.yml", __dir__)),
184
+ env: "production"
185
+ )
186
+
187
+ it "#public_output_path returns correct path" do
188
+ expected_public_output_path = File.expand_path File.join(File.dirname(__FILE__), "public/packs").to_s
189
+ expect(config.public_output_path.to_s).to eq expected_public_output_path
190
+ end
191
+ end
192
+
193
+ context "with webpacker config file containing manifext_path entry" do
194
+ config = Webpacker::Configuration.new(
195
+ root_path: ROOT_PATH,
196
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker_manifest_path.yml", __dir__)),
197
+ env: "production"
198
+ )
199
+
200
+ it "#manifest_path returns correct expected value" do
201
+ expected_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "webpacker_test_app/app/packs", "manifest.json").to_s
202
+ expect(config.manifest_path.to_s).to eq expected_manifest_path
203
+ end
204
+ end
205
+
206
+ context "with webpacker_precompile entry set to false" do
207
+ describe "#webpacker_precompile?" do
208
+ before :each do
209
+ ENV.delete("WEBPACKER_PRECOMPILE")
210
+ ENV.delete("SHAKAPACKER_PRECOMPILE")
211
+ end
212
+
213
+ let(:config) {
214
+ Webpacker::Configuration.new(
215
+ root_path: ROOT_PATH,
216
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker_no_precompile.yml", __dir__)),
217
+ env: "production"
218
+ )
219
+ }
220
+
221
+ subject { config.webpacker_precompile? }
222
+
223
+ it "returns false with unset WEBPACKER_PRECOMPILE" do
224
+ expect(subject).to be false
225
+ end
226
+
227
+ it "returns true with WEBPACKER_PRECOMPILE set to true" do
228
+ ENV["WEBPACKER_PRECOMPILE"] = "true"
229
+ expect(subject).to be true
230
+ end
231
+
232
+ it "returns false with WEBPACKER_PRECOMPILE set to falsy value" do
233
+ # ENV["WEBPACKER_PRECOMPILE"] = "no"
234
+ ENV.delete("WEBPACKER_PRECOMPILE")
235
+ expect(subject).to be false
236
+ end
237
+ end
238
+ end
239
+
240
+ context "with webpacker config file containing invalid path" do
241
+ config = Webpacker::Configuration.new(
242
+ root_path: ROOT_PATH,
243
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/invalid_path.yml", __dir__)),
244
+ env: "default"
245
+ )
246
+
247
+ it "#webpacker_precompile? returns false" do
248
+ expect(config.webpacker_precompile?).to be false
249
+ end
250
+ end
251
+
252
+ context "with webpacker config file with defaults fallback" do
253
+ let(:config) do
254
+ Webpacker::Configuration.new(
255
+ root_path: ROOT_PATH,
256
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker_defaults_fallback.yml", __dir__)),
257
+ env: "default"
258
+ )
259
+ end
260
+
261
+ it "#cache_manifest? falls back to 'default' config from bundled file" do
262
+ expect(config.cache_manifest?).to be false
263
+ end
264
+
265
+ it "#webpacker_precompile? uses 'default' config from custom file" do
266
+ expect(config.webpacker_precompile?).to be false
267
+ end
268
+ end
269
+
270
+ context "falls back to bundled production config for custom environments" do
271
+ let(:config) do
272
+ Webpacker::Configuration.new(
273
+ root_path: ROOT_PATH,
274
+ config_path: Pathname.new(File.expand_path("./webpacker_test_app/config/webpacker_defaults_fallback.yml", __dir__)),
275
+ env: "staging"
276
+ )
277
+ end
278
+
279
+ it "#cache_manifest? fall back to 'production' config from bundled file" do
280
+ expect(config.cache_manifest?).to be true
281
+ end
282
+ it "#webpacker_precompile? use 'staging' config from custom file" do
283
+ expect(config.webpacker_precompile?).to be false
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,79 @@
1
+ require_relative "spec_helper_initializer"
2
+ # Requiring from webpacker directory to ensure old ./bin/webpacker-dev-server works fine
3
+ require "webpacker/dev_server_runner"
4
+
5
+ describe "DevServerRunner" do
6
+ before do
7
+ @original_node_env, ENV["NODE_ENV"] = ENV["NODE_ENV"], "development"
8
+ @original_rails_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "development"
9
+ @original_webpacker_config = ENV["WEBPACKER_CONFIG"]
10
+ end
11
+
12
+ after do
13
+ ENV["NODE_ENV"] = @original_node_env
14
+ ENV["RAILS_ENV"] = @original_rails_env
15
+ ENV["WEBPACKER_CONFIG"] = @original_webpacker_config
16
+ end
17
+
18
+ let(:test_app_path) { File.expand_path("webpacker_test_app", __dir__) }
19
+
20
+ it "run cmd via node modules" do
21
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
22
+ verify_command(cmd, use_node_modules: true)
23
+ end
24
+
25
+ it "run cmd via yarn" do
26
+ cmd = ["yarn", "webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
27
+ verify_command(cmd, use_node_modules: false)
28
+ end
29
+
30
+ it "run cmd argv" do
31
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--quiet"]
32
+ verify_command(cmd, argv: (["--quiet"]))
33
+ end
34
+
35
+ it "run cmd argv with https" do
36
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--https"]
37
+
38
+ dev_server = double()
39
+ allow(dev_server).to receive(:host).and_return("localhost")
40
+ allow(dev_server).to receive(:port).and_return("3035")
41
+ allow(dev_server).to receive(:pretty?).and_return(false)
42
+ allow(dev_server).to receive(:https?).and_return(true)
43
+ allow(dev_server).to receive(:hmr?).and_return(false)
44
+
45
+ allow(Webpacker::DevServer).to receive(:new) do
46
+ verify_command(cmd, argv: (["--https"]))
47
+ end.and_return(dev_server)
48
+ end
49
+
50
+ it "accepts environment variables" do
51
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
52
+ env = Webpacker::Compiler.env.dup
53
+
54
+ # ENV["WEBPACKER_CONFIG"] is the interface and env["SHAKAPACKER_CONFIG"] is internal
55
+ ENV["WEBPACKER_CONFIG"] = env["SHAKAPACKER_CONFIG"] = "#{test_app_path}/config/webpacker_other_location.yml"
56
+ env["WEBPACK_SERVE"] = "true"
57
+ verify_command(cmd, env: env)
58
+ end
59
+
60
+ private
61
+
62
+ def verify_command(cmd, use_node_modules: true, argv: [], env: Webpacker::Compiler.env)
63
+ cwd = Dir.pwd
64
+ Dir.chdir(test_app_path)
65
+ klass = Webpacker::DevServerRunner
66
+ instance = klass.new(argv)
67
+
68
+ allow(klass).to receive(:new).and_return(instance)
69
+ allow(instance).to receive(:node_modules_bin_exist?).and_return(use_node_modules)
70
+ allow(Kernel).to receive(:exec).with(env, *cmd)
71
+
72
+ klass.run(argv)
73
+
74
+ expect(Kernel).to have_received(:exec).with(env, *cmd)
75
+
76
+ ensure
77
+ Dir.chdir(cwd)
78
+ end
79
+ end