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
data/package/config.js CHANGED
@@ -1,12 +1,16 @@
1
1
  const { resolve } = require('path')
2
2
  const { load } = require('js-yaml')
3
- const { readFileSync } = require('fs')
3
+ const { existsSync, readFileSync } = require('fs')
4
+
4
5
  const { merge } = require('webpack-merge')
5
- const { ensureTrailingSlash } = require('./utils/helpers')
6
+ const {
7
+ ensureTrailingSlash,
8
+ setShakapackerEnvVariablesForBackwardCompatibility
9
+ } = require('./utils/helpers')
6
10
  const { railsEnv } = require('./env')
7
- const configPath = require('./configPath')
11
+ const configPath = require('./utils/configPath')
8
12
 
9
- const defaultConfigPath = require.resolve('../lib/install/config/webpacker.yml')
13
+ const defaultConfigPath = require('./utils/defaultConfigPath')
10
14
 
11
15
  const getDefaultConfig = () => {
12
16
  const defaultConfig = load(readFileSync(defaultConfigPath), 'utf8')
@@ -14,15 +18,29 @@ const getDefaultConfig = () => {
14
18
  }
15
19
 
16
20
  const defaults = getDefaultConfig()
17
- const app = load(readFileSync(configPath), 'utf8')[railsEnv]
21
+ let config
22
+
23
+ if (existsSync(configPath)) {
24
+ const appYmlObject = load(readFileSync(configPath), 'utf8')
25
+ const envAppConfig = appYmlObject[railsEnv]
26
+
27
+ if (!envAppConfig) {
28
+ /* eslint no-console:0 */
29
+ console.warn(`Warning: ${railsEnv} key not found in the configuration file. Using production configuration as a fallback.`)
30
+ }
31
+
32
+ config = merge(defaults, envAppConfig || {})
33
+ } else {
34
+ config = merge(defaults, {})
35
+ }
18
36
 
19
- const config = merge(defaults, app)
20
37
  config.outputPath = resolve(config.public_root_path, config.public_output_path)
21
38
 
22
39
  // Ensure that the publicPath includes our asset host so dynamic imports
23
40
  // (code-splitting chunks and static assets) load from the CDN instead of a relative path.
24
41
  const getPublicPath = () => {
25
- const rootUrl = ensureTrailingSlash(process.env.WEBPACKER_ASSET_HOST || '/')
42
+ setShakapackerEnvVariablesForBackwardCompatibility()
43
+ const rootUrl = ensureTrailingSlash(process.env.SHAKAPACKER_ASSET_HOST || '/')
26
44
  return `${rootUrl}${config.public_output_path}/`
27
45
  }
28
46
 
@@ -1,7 +1,8 @@
1
+ // These are the raw webpacker dev server config settings from the YML file with ENV overrides applied.
1
2
  const { isBoolean } = require('./utils/helpers')
2
3
  const config = require('./config')
3
4
 
4
- const fetch = (key) => {
5
+ const envFetch = (key) => {
5
6
  const value = process.env[key]
6
7
  return isBoolean(value) ? JSON.parse(value) : value
7
8
  }
@@ -9,11 +10,13 @@ const fetch = (key) => {
9
10
  const devServerConfig = config.dev_server
10
11
 
11
12
  if (devServerConfig) {
12
- const envPrefix = config.dev_server.env_prefix || 'WEBPACKER_DEV_SERVER'
13
+ const envPrefix = config.dev_server.env_prefix || 'SHAKAPACKER_DEV_SERVER'
13
14
 
14
15
  Object.keys(devServerConfig).forEach((key) => {
15
- const envValue = fetch(`${envPrefix}_${key.toUpperCase()}`)
16
- if (envValue !== undefined) devServerConfig[key] = envValue
16
+ const envValue = envFetch(`${envPrefix}_${key.toUpperCase()}`)
17
+ if (envValue !== undefined) {
18
+ devServerConfig[key] = envValue
19
+ }
17
20
  })
18
21
  }
19
22
 
data/package/env.js CHANGED
@@ -1,9 +1,10 @@
1
1
  const { load } = require('js-yaml')
2
2
  const { readFileSync } = require('fs')
3
+ const defaultConfigPath = require('./utils/defaultConfigPath')
3
4
 
4
5
  const NODE_ENVIRONMENTS = ['development', 'production', 'test']
5
6
  const DEFAULT = 'production'
6
- const configPath = require('./configPath')
7
+ const configPath = require('./utils/configPath')
7
8
 
8
9
  const railsEnv = process.env.RAILS_ENV
9
10
  const rawNodeEnv = process.env.NODE_ENV
@@ -12,14 +13,32 @@ const nodeEnv
12
13
  const isProduction = nodeEnv === 'production'
13
14
  const isDevelopment = nodeEnv === 'development'
14
15
 
15
- const config = load(readFileSync(configPath), 'utf8')
16
+ let config
17
+ try {
18
+ config = load(readFileSync(configPath), 'utf8')
19
+ } catch (error) {
20
+ if (error.code === 'ENOENT') {
21
+ // File not found, use default configuration
22
+ config = load(readFileSync(defaultConfigPath), 'utf8')
23
+ } else {
24
+ throw error
25
+ }
26
+ }
27
+
16
28
  const availableEnvironments = Object.keys(config).join('|')
17
29
  const regex = new RegExp(`^(${availableEnvironments})$`, 'g')
18
30
 
19
31
  const runningWebpackDevServer = process.env.WEBPACK_SERVE === 'true'
20
32
 
33
+ const validatedRailsEnv = railsEnv && railsEnv.match(regex) ? railsEnv : DEFAULT
34
+
35
+ if (railsEnv && validatedRailsEnv !== railsEnv) {
36
+ /* eslint no-console:0 */
37
+ console.warn(`Warning: '${railsEnv}' environment not found in the configuration. Using '${DEFAULT}' configuration as a fallback.`)
38
+ }
39
+
21
40
  module.exports = {
22
- railsEnv: railsEnv && railsEnv.match(regex) ? railsEnv : DEFAULT,
41
+ railsEnv: validatedRailsEnv,
23
42
  nodeEnv,
24
43
  isProduction,
25
44
  isDevelopment,
@@ -0,0 +1,107 @@
1
+ /* global test expect, describe, afterAll, beforeEach */
2
+
3
+ // environment.js expects to find config/webapacker.yml and resolved modules from
4
+ // the root of a Rails project
5
+
6
+ const { resetEnv, chdirWebpackerTestApp } = require('../../utils/helpers')
7
+
8
+ const rootPath = process.cwd()
9
+ chdirWebpackerTestApp()
10
+
11
+ const { resolve } = require('path')
12
+
13
+ const baseConfig = require('../base')
14
+ const config = require("../../config");
15
+
16
+ describe('Base config', () => {
17
+ beforeEach(() => jest.resetModules() && resetEnv())
18
+ afterAll(() => process.chdir(rootPath))
19
+
20
+ describe('config', () => {
21
+ test('should return entry', () => {
22
+ expect(baseConfig.entry.application).toEqual(
23
+ resolve('app', 'packs', 'entrypoints', 'application.js')
24
+ )
25
+ })
26
+
27
+ test('should return false for css_extract_ignore_order_warnings when using default config', () => {
28
+ expect(config.css_extract_ignore_order_warnings).toEqual(false)
29
+ })
30
+
31
+ test('should return true for css_extract_ignore_order_warnings when configured', () => {
32
+ process.env.WEBPACKER_CONFIG = 'config/webpacker_css_extract_ignore_order_warnings.yml'
33
+ const config = require("../../config");
34
+
35
+ expect(config.css_extract_ignore_order_warnings).toEqual(true)
36
+ })
37
+
38
+ test('should return only 2 entry points with config.nested_entries == false', () => {
39
+ expect(config.nested_entries).toEqual(false)
40
+
41
+ expect(baseConfig.entry.multi_entry.sort()).toEqual([
42
+ resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
43
+ resolve('app', 'packs', 'entrypoints', 'multi_entry.js')
44
+ ])
45
+ expect(baseConfig.entry['generated/something']).toEqual(undefined)
46
+ })
47
+
48
+ test('should returns top level and nested entry points with config.nested_entries == true', () => {
49
+ process.env.WEBPACKER_CONFIG = 'config/webpacker_nested_entries.yml'
50
+ const config = require("../../config");
51
+ const baseConfig = require('../base')
52
+
53
+ expect(config.nested_entries).toEqual(true)
54
+
55
+ expect(baseConfig.entry.application).toEqual(
56
+ resolve('app', 'packs', 'entrypoints', 'application.js')
57
+ )
58
+ expect(baseConfig.entry.multi_entry.sort()).toEqual([
59
+ resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
60
+ resolve('app', 'packs', 'entrypoints', 'multi_entry.js')
61
+ ])
62
+ expect(baseConfig.entry['generated/something']).toEqual(
63
+ resolve('app', 'packs', 'entrypoints', 'generated', 'something.js')
64
+ )
65
+ })
66
+
67
+ test('should return output', () => {
68
+ expect(baseConfig.output.filename).toEqual('js/[name].js')
69
+ expect(baseConfig.output.chunkFilename).toEqual(
70
+ 'js/[name].chunk.js'
71
+ )
72
+ })
73
+
74
+ test('should return default loader rules for each file in config/loaders', () => {
75
+ const rules = require('../../rules')
76
+
77
+ const defaultRules = Object.keys(rules)
78
+ const configRules = baseConfig.module.rules
79
+
80
+ expect(defaultRules.length).toEqual(3)
81
+ expect(configRules.length).toEqual(3)
82
+ })
83
+
84
+ test('should return default plugins', () => {
85
+ expect(baseConfig.plugins.length).toEqual(2)
86
+ })
87
+
88
+ test('should return default resolveLoader', () => {
89
+ expect(baseConfig.resolveLoader.modules).toEqual(['node_modules'])
90
+ })
91
+
92
+ test('should return default resolve.modules with additions', () => {
93
+ expect(baseConfig.resolve.modules).toEqual([
94
+ resolve('app', 'packs'),
95
+ resolve('app/assets'),
96
+ resolve('/etc/yarn'),
97
+ resolve('some.config.js'),
98
+ resolve('app/elm'),
99
+ 'node_modules'
100
+ ])
101
+ })
102
+
103
+ test('returns plugins property as Array', () => {
104
+ expect(baseConfig.plugins).toBeInstanceOf(Array)
105
+ })
106
+ })
107
+ })
@@ -1,10 +1,11 @@
1
1
  /* global test expect, describe, afterAll, beforeEach */
2
2
 
3
- // environment.js expects to find config/webpacker.yml and resolved modules from
3
+ // environment.js expects to find config/shakapacker.yml and resolved modules from
4
4
  // the root of a Rails project
5
5
 
6
6
  const { chdirTestApp, chdirCwd, resetEnv } = require('../../utils/helpers')
7
7
 
8
+ const rootPath = process.cwd()
8
9
  chdirTestApp()
9
10
 
10
11
  const { resolve } = require('path')
@@ -14,13 +15,12 @@ const config = require("../../config");
14
15
 
15
16
  describe('Base config', () => {
16
17
  beforeEach(() => jest.resetModules() && resetEnv())
17
-
18
- afterAll(chdirCwd)
18
+ afterAll(() => process.chdir(rootPath))
19
19
 
20
20
  describe('config', () => {
21
21
  test('should return entry', () => {
22
22
  expect(baseConfig.entry.application).toEqual(
23
- resolve('app', 'packs', 'entrypoints', 'application.js')
23
+ resolve('app', 'javascript', 'entrypoints', 'application.js')
24
24
  )
25
25
  })
26
26
 
@@ -29,7 +29,7 @@ describe('Base config', () => {
29
29
  })
30
30
 
31
31
  test('should return true for css_extract_ignore_order_warnings when configured', () => {
32
- process.env.WEBPACKER_CONFIG = 'config/webpacker_css_extract_ignore_order_warnings.yml'
32
+ process.env.SHAKAPACKER_CONFIG = 'config/shakapacker_css_extract_ignore_order_warnings.yml'
33
33
  const config = require("../../config");
34
34
 
35
35
  expect(config.css_extract_ignore_order_warnings).toEqual(true)
@@ -39,28 +39,28 @@ describe('Base config', () => {
39
39
  expect(config.nested_entries).toEqual(false)
40
40
 
41
41
  expect(baseConfig.entry.multi_entry.sort()).toEqual([
42
- resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
43
- resolve('app', 'packs', 'entrypoints', 'multi_entry.js')
42
+ resolve('app', 'javascript', 'entrypoints', 'multi_entry.css'),
43
+ resolve('app', 'javascript', 'entrypoints', 'multi_entry.js')
44
44
  ])
45
45
  expect(baseConfig.entry['generated/something']).toEqual(undefined)
46
46
  })
47
47
 
48
48
  test('should returns top level and nested entry points with config.nested_entries == true', () => {
49
- process.env.WEBPACKER_CONFIG = 'config/webpacker_nested_entries.yml'
49
+ process.env.SHAKAPACKER_CONFIG = 'config/shakapacker_nested_entries.yml'
50
50
  const config = require("../../config");
51
51
  const baseConfig = require('../base')
52
52
 
53
53
  expect(config.nested_entries).toEqual(true)
54
54
 
55
55
  expect(baseConfig.entry.application).toEqual(
56
- resolve('app', 'packs', 'entrypoints', 'application.js')
56
+ resolve('app', 'javascript', 'entrypoints', 'application.js')
57
57
  )
58
58
  expect(baseConfig.entry.multi_entry.sort()).toEqual([
59
- resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
60
- resolve('app', 'packs', 'entrypoints', 'multi_entry.js')
59
+ resolve('app', 'javascript', 'entrypoints', 'multi_entry.css'),
60
+ resolve('app', 'javascript', 'entrypoints', 'multi_entry.js')
61
61
  ])
62
62
  expect(baseConfig.entry['generated/something']).toEqual(
63
- resolve('app', 'packs', 'entrypoints', 'generated', 'something.js')
63
+ resolve('app', 'javascript', 'entrypoints', 'generated', 'something.js')
64
64
  )
65
65
  })
66
66
 
@@ -91,7 +91,7 @@ describe('Base config', () => {
91
91
 
92
92
  test('should return default resolve.modules with additions', () => {
93
93
  expect(baseConfig.resolve.modules).toEqual([
94
- resolve('app', 'packs'),
94
+ resolve('app', 'javascript'),
95
95
  resolve('app/assets'),
96
96
  resolve('/etc/yarn'),
97
97
  resolve('some.config.js'),
@@ -16,7 +16,7 @@ const getEntryObject = () => {
16
16
  const rootPath = join(config.source_path, config.source_entry_path)
17
17
  if (config.source_entry_path === '/' && config.nested_entries) {
18
18
  throw new Error(
19
- "Your webpacker config specified using a source_entry_path of '/' with 'nested_entries' == " +
19
+ "Your shakapacker config specified using a source_entry_path of '/' with 'nested_entries' == " +
20
20
  "'true'. Doing this would result in packs for every one of your source files"
21
21
  )
22
22
  }
@@ -1,55 +1,13 @@
1
1
  const { merge } = require('webpack-merge')
2
2
 
3
3
  const baseConfig = require('./base')
4
- const devServer = require('../dev_server')
4
+ const webpackDevServerConfig = require('../webpackDevServerConfig')
5
5
  const { runningWebpackDevServer } = require('../env')
6
6
 
7
- const { outputPath: contentBase, publicPath } = require('../config')
8
-
9
- let devConfig = {
7
+ const devConfig = {
10
8
  mode: 'development',
11
- devtool: 'cheap-module-source-map'
12
- }
13
-
14
- if (runningWebpackDevServer) {
15
- const liveReload = devServer.live_reload !== undefined ? devServer.live_reload : !devServer.hmr
16
-
17
- const devServerConfig = {
18
- devMiddleware: {
19
- publicPath
20
- },
21
- compress: devServer.compress,
22
- allowedHosts: devServer.allowed_hosts,
23
- host: devServer.host,
24
- port: devServer.port,
25
- https: devServer.https,
26
- hot: devServer.hmr,
27
- liveReload,
28
- historyApiFallback: { disableDotRule: true },
29
- headers: devServer.headers,
30
- static: {
31
- publicPath: contentBase
32
- }
33
- }
34
-
35
- if (devServer.static) {
36
- devServerConfig.static = { ...devServerConfig.static, ...devServer.static }
37
- }
38
-
39
- if (devServer.client) {
40
- devServerConfig.client = devServer.client
41
- }
42
-
43
- devConfig = merge(devConfig, {
44
- stats: {
45
- colors: true,
46
- entrypoints: false,
47
- errorDetails: true,
48
- modules: false,
49
- moduleTrace: false
50
- },
51
- devServer: devServerConfig
52
- })
9
+ devtool: 'cheap-module-source-map',
10
+ ...(runningWebpackDevServer && { devServer: webpackDevServerConfig() })
53
11
  }
54
12
 
55
13
  module.exports = merge(baseConfig, devConfig)
@@ -52,7 +52,7 @@ const productionConfig = {
52
52
  minimizer: [
53
53
  tryCssMinimizer(),
54
54
  new TerserPlugin({
55
- parallel: Number.parseInt(process.env.WEBPACKER_PARALLEL, 10) || true,
55
+ parallel: Number.parseInt(process.env.SHAKAPACKER_PARALLEL, 10) || true,
56
56
  terserOptions: {
57
57
  parse: {
58
58
  // Let terser parse ecma 8 code but always output
data/package/index.js CHANGED
@@ -10,19 +10,26 @@ const config = require('./config')
10
10
  const devServer = require('./dev_server')
11
11
  const env = require('./env')
12
12
  const { moduleExists, canProcess } = require('./utils/helpers')
13
- const inliningCss = require('./inliningCss')
13
+ const inliningCss = require('./utils/inliningCss')
14
14
 
15
- const webpackConfig = () => {
15
+ const globalMutableWebpackConfig = () => {
16
16
  const { nodeEnv } = env
17
17
  const path = resolve(__dirname, 'environments', `${nodeEnv}.js`)
18
18
  const environmentConfig = existsSync(path) ? require(path) : baseConfig
19
19
  return environmentConfig
20
20
  }
21
21
 
22
+ const generateWebpackConfig = () => {
23
+ const environmentConfig = globalMutableWebpackConfig()
24
+ const immutable = webpackMerge.merge({}, environmentConfig)
25
+ return immutable
26
+ }
27
+
22
28
  module.exports = {
23
- config,
29
+ config, // shakapacker.yml
24
30
  devServer,
25
- webpackConfig: webpackConfig(),
31
+ generateWebpackConfig,
32
+ globalMutableWebpackConfig: globalMutableWebpackConfig(),
26
33
  baseConfig,
27
34
  env,
28
35
  rules,
@@ -16,7 +16,7 @@ const createTrackLoader = () => {
16
16
 
17
17
  const node_modules = path.resolve("node_modules");
18
18
  const node_modules_included = path.resolve("node_modules/included");
19
- const app_javascript = path.resolve("app/packs");
19
+ const app_javascript = path.resolve("app/javascript");
20
20
 
21
21
  const createInMemoryFs = () => {
22
22
  const fs = new MemoryFS();
@@ -32,4 +32,31 @@ describe('file', () => {
32
32
  ]
33
33
  types.forEach(type => expect(file.exclude.test(type)).toBe(true))
34
34
  })
35
+
36
+ test('correct generated output path is returned for top level files', () => {
37
+ const pathData = {
38
+ filename: 'app/javascript/image.svg',
39
+ };
40
+ expect(file.generator.filename(pathData)).toEqual(
41
+ 'static/[name]-[hash][ext][query]'
42
+ );
43
+ });
44
+
45
+ test('correct generated output path is returned for nested files', () => {
46
+ const pathData = {
47
+ filename: 'app/javascript/images/image.svg',
48
+ };
49
+ expect(file.generator.filename(pathData)).toEqual(
50
+ 'static/images/[name]-[hash][ext][query]'
51
+ );
52
+ })
53
+
54
+ test('correct generated output path is returned for deeply nested files', () => {
55
+ const pathData = {
56
+ filename: 'app/javascript/images/nested/deeply/image.svg',
57
+ };
58
+ expect(file.generator.filename(pathData)).toEqual(
59
+ 'static/images/nested/deeply/[name]-[hash][ext][query]'
60
+ );
61
+ });
35
62
  })
@@ -1,4 +1,3 @@
1
- const path = require("path");
2
1
  const {
3
2
  app_javascript,
4
3
  node_modules,
@@ -36,7 +35,7 @@ const createWebpackConfig = (file, use) => {
36
35
  };
37
36
 
38
37
  describe("swc", () => {
39
- test("process source path", async () => {
38
+ test("process files in source_path", async () => {
40
39
  const normalPath = `${app_javascript}/a.js`;
41
40
  const [tracked, loader] = createTrackLoader();
42
41
  const compiler = createTestCompiler(
@@ -8,9 +8,9 @@ module.exports = {
8
8
  generator: {
9
9
  filename: (pathData) => {
10
10
  const folders = dirname(pathData.filename)
11
- .replace(`${sourcePath}/`, '')
11
+ .replace(`${sourcePath}`, '')
12
12
  .split('/')
13
- .slice(1)
13
+ .filter(Boolean)
14
14
 
15
15
  const foldersWithStatic = ['static', ...folders].join('/')
16
16
  return `${foldersWithStatic}/[name]-[hash][ext][query]`
@@ -0,0 +1,19 @@
1
+ const fs = require('fs')
2
+ const { resolve } = require('path')
3
+ const { setShakapackerEnvVariablesForBackwardCompatibility } = require('./helpers')
4
+
5
+ setShakapackerEnvVariablesForBackwardCompatibility()
6
+
7
+ // For backward compatibility
8
+ const resolveToPhysicalFilePath = () => {
9
+ const shakapackerConfigPath = resolve('config', 'shakapacker.yml')
10
+ const webpackerConfigPath = resolve('config', 'webpacker.yml')
11
+
12
+ if (fs.existsSync(shakapackerConfigPath)) return shakapackerConfigPath
13
+ if (fs.existsSync(webpackerConfigPath)) return webpackerConfigPath
14
+
15
+ // If neither of files exist, try to resolve to shakapacker.yml to get more relevant error
16
+ return shakapackerConfigPath
17
+ }
18
+
19
+ module.exports = process.env.SHAKAPACKER_CONFIG || resolveToPhysicalFilePath()
@@ -0,0 +1,2 @@
1
+ const path = require.resolve('../../lib/install/config/shakapacker.yml')
2
+ module.exports = path
@@ -1,6 +1,6 @@
1
1
  /* eslint global-require: 0 */
2
2
  const { canProcess, moduleExists } = require('./helpers')
3
- const inliningCss = require('../inliningCss')
3
+ const inliningCss = require('./inliningCss')
4
4
 
5
5
  const getStyleRule = (test, preprocessors = []) => {
6
6
  if (moduleExists('css-loader')) {
@@ -18,7 +18,10 @@ const getStyleRule = (test, preprocessors = []) => {
18
18
  loader: require.resolve('css-loader'),
19
19
  options: {
20
20
  sourceMap: true,
21
- importLoaders: 2
21
+ importLoaders: 2,
22
+ modules: {
23
+ auto: true
24
+ }
22
25
  }
23
26
  },
24
27
  tryPostcss(),
@@ -8,6 +8,15 @@ const chdirTestApp = () => {
8
8
  }
9
9
  }
10
10
 
11
+ // For backward compatibility
12
+ const chdirWebpackerTestApp = () => {
13
+ try {
14
+ return process.chdir('spec/backward_compatibility_specs/webpacker_test_app')
15
+ } catch (e) {
16
+ return null
17
+ }
18
+ }
19
+
11
20
  const chdirCwd = () => process.chdir(process.cwd())
12
21
 
13
22
  const resetEnv = () => {
@@ -48,15 +57,29 @@ const loaderMatches = (configLoader, loaderToCheck, fn) => {
48
57
 
49
58
  if (!moduleExists(loaderName)) {
50
59
  throw new Error(
51
- `Your webpacker config specified using ${configLoader}, but ${loaderName} package is not installed. Please install ${loaderName} first.`
60
+ `Your Shakapacker config specified using ${configLoader}, but ${loaderName} package is not installed. Please install ${loaderName} first.`
52
61
  )
53
62
  }
54
63
 
55
64
  return fn()
56
65
  }
57
66
 
67
+ // For backward compatibility
68
+ // Set SHAKAPACKER_XYZ only if SHAKAPACKER_XYZ is not defined but WEBPACKER_XYZ is.
69
+ const setShakapackerEnvVariablesForBackwardCompatibility = () => {
70
+ const webpackerEnvVariables = Object.entries(process.env).filter((key) => /^WEBPACKER_/.test(key))
71
+ webpackerEnvVariables.forEach(([webpackerEnvKey, webpackerEnvValue]) => {
72
+ const shakapackerKey = webpackerEnvKey.replace(/^WEBPACKER/, 'SHAKAPACKER')
73
+ if (!process.env[shakapackerKey]) {
74
+ process.env[shakapackerKey] = webpackerEnvValue
75
+ }
76
+ })
77
+ }
78
+
58
79
  module.exports = {
59
80
  chdirTestApp,
81
+ chdirWebpackerTestApp,
82
+ setShakapackerEnvVariablesForBackwardCompatibility,
60
83
  chdirCwd,
61
84
  isArray,
62
85
  isBoolean,
@@ -0,0 +1,7 @@
1
+ const { runningWebpackDevServer } = require('../env')
2
+ const devServer = require('../dev_server')
3
+
4
+ // This logic is tied to lib/shakapacker/instance.rb
5
+ const inliningCss = runningWebpackDevServer && devServer.hmr && devServer.inline_css !== false
6
+
7
+ module.exports = inliningCss
@@ -0,0 +1,7 @@
1
+ function snakeToCamelCase(s) {
2
+ return s.replace(/(_\w)/g, function (match) {
3
+ return match[1].toUpperCase()
4
+ })
5
+ }
6
+
7
+ module.exports = snakeToCamelCase