shakapacker 9.2.0 → 9.3.0.beta.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +6 -9
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
  4. data/.github/workflows/claude-code-review.yml +4 -5
  5. data/.github/workflows/claude.yml +1 -2
  6. data/.github/workflows/dummy.yml +4 -4
  7. data/.github/workflows/generator.yml +9 -9
  8. data/.github/workflows/node.yml +11 -2
  9. data/.github/workflows/ruby.yml +16 -16
  10. data/.github/workflows/test-bundlers.yml +9 -9
  11. data/.gitignore +4 -0
  12. data/CHANGELOG.md +19 -4
  13. data/CLAUDE.md +6 -1
  14. data/CONTRIBUTING.md +0 -1
  15. data/Gemfile.lock +1 -1
  16. data/README.md +14 -14
  17. data/TODO.md +10 -2
  18. data/TODO_v9.md +13 -3
  19. data/bin/export-bundler-config +1 -1
  20. data/conductor-setup.sh +1 -1
  21. data/conductor.json +1 -1
  22. data/docs/cdn_setup.md +13 -8
  23. data/docs/common-upgrades.md +2 -1
  24. data/docs/configuration.md +630 -0
  25. data/docs/css-modules-export-mode.md +120 -100
  26. data/docs/customizing_babel_config.md +16 -16
  27. data/docs/deployment.md +18 -0
  28. data/docs/developing_shakapacker.md +6 -0
  29. data/docs/optional-peer-dependencies.md +9 -4
  30. data/docs/peer-dependencies.md +17 -6
  31. data/docs/precompile_hook.md +342 -0
  32. data/docs/react.md +57 -47
  33. data/docs/releasing.md +0 -2
  34. data/docs/rspack.md +25 -21
  35. data/docs/rspack_migration_guide.md +335 -8
  36. data/docs/sprockets.md +1 -0
  37. data/docs/style_loader_vs_mini_css.md +12 -12
  38. data/docs/subresource_integrity.md +13 -7
  39. data/docs/transpiler-performance.md +40 -19
  40. data/docs/troubleshooting.md +0 -2
  41. data/docs/typescript-migration.md +48 -39
  42. data/docs/typescript.md +12 -8
  43. data/docs/using_esbuild_loader.md +10 -10
  44. data/docs/v6_upgrade.md +33 -20
  45. data/docs/v7_upgrade.md +8 -6
  46. data/docs/v8_upgrade.md +13 -12
  47. data/docs/v9_upgrade.md +2 -1
  48. data/eslint.config.fast.js +134 -0
  49. data/eslint.config.js +140 -0
  50. data/knip.ts +54 -0
  51. data/lib/install/bin/export-bundler-config +1 -1
  52. data/lib/install/config/shakapacker.yml +16 -5
  53. data/lib/shakapacker/compiler.rb +80 -0
  54. data/lib/shakapacker/configuration.rb +33 -5
  55. data/lib/shakapacker/dev_server_runner.rb +140 -1
  56. data/lib/shakapacker/doctor.rb +294 -65
  57. data/lib/shakapacker/instance.rb +8 -3
  58. data/lib/shakapacker/runner.rb +244 -8
  59. data/lib/shakapacker/version.rb +1 -1
  60. data/lib/tasks/shakapacker/doctor.rake +42 -2
  61. data/package/babel/preset.ts +7 -4
  62. data/package/config.ts +42 -30
  63. data/package/configExporter/cli.ts +799 -208
  64. data/package/configExporter/configFile.ts +520 -0
  65. data/package/configExporter/fileWriter.ts +12 -8
  66. data/package/configExporter/index.ts +9 -1
  67. data/package/configExporter/types.ts +36 -2
  68. data/package/configExporter/yamlSerializer.ts +22 -8
  69. data/package/dev_server.ts +1 -1
  70. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +11 -5
  71. data/package/environments/base.ts +18 -13
  72. data/package/environments/development.ts +1 -1
  73. data/package/environments/production.ts +4 -1
  74. data/package/index.d.ts +50 -3
  75. data/package/index.d.ts.template +50 -0
  76. data/package/index.ts +7 -7
  77. data/package/loaders.d.ts +2 -2
  78. data/package/optimization/rspack.ts +1 -1
  79. data/package/plugins/rspack.ts +15 -4
  80. data/package/plugins/webpack.ts +7 -3
  81. data/package/rspack/index.ts +10 -2
  82. data/package/rules/raw.ts +3 -2
  83. data/package/rules/sass.ts +1 -1
  84. data/package/types/README.md +15 -13
  85. data/package/types/index.ts +5 -5
  86. data/package/types.ts +0 -1
  87. data/package/utils/defaultConfigPath.ts +4 -1
  88. data/package/utils/errorCodes.ts +129 -100
  89. data/package/utils/errorHelpers.ts +34 -29
  90. data/package/utils/getStyleRule.ts +5 -2
  91. data/package/utils/helpers.ts +21 -11
  92. data/package/utils/pathValidation.ts +43 -35
  93. data/package/utils/requireOrError.ts +1 -1
  94. data/package/utils/snakeToCamelCase.ts +1 -1
  95. data/package/utils/typeGuards.ts +132 -83
  96. data/package/utils/validateDependencies.ts +1 -1
  97. data/package/webpack-types.d.ts +3 -3
  98. data/package/webpackDevServerConfig.ts +22 -10
  99. data/package-lock.json +2 -2
  100. data/package.json +36 -28
  101. data/scripts/type-check-no-emit.js +1 -1
  102. data/test/configExporter/configFile.test.js +392 -0
  103. data/test/configExporter/integration.test.js +275 -0
  104. data/test/helpers.js +1 -1
  105. data/test/package/configExporter.test.js +154 -0
  106. data/test/package/helpers.test.js +2 -2
  107. data/test/package/rules/sass-version-parsing.test.js +71 -0
  108. data/test/package/rules/sass.test.js +2 -4
  109. data/test/package/rules/sass1.test.js +1 -3
  110. data/test/package/rules/sass16.test.js +23 -0
  111. data/tools/README.md +15 -5
  112. data/tsconfig.eslint.json +2 -9
  113. data/yarn.lock +1894 -1492
  114. metadata +19 -3
  115. data/.eslintignore +0 -5
data/docs/v6_upgrade.md CHANGED
@@ -13,41 +13,47 @@ Webpacker used to configure Webpack indirectly, which lead to a [complicated sec
13
13
  While you have to configure integration with frameworks yourself, [`webpack-merge`](https://github.com/survivejs/webpack-merge) helps with this. See this example for [Vue](https://github.com/shakacode/shakapacker#other-frameworks) and scroll to the bottom for [more examples](#examples-of-v5-to-v6).
14
14
 
15
15
  ## webpacker v6.0.0.rc.6 to shakapacker v6.0.0
16
+
16
17
  See an example migration here: [PR 27](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/pull/27).
17
18
 
18
19
  ### Update to v6.5.2
20
+
19
21
  1. Remove setting the NODE_ENV in your `bin/webpacker` and `bin/webpacker-dev-server` bin stubs as these are not set in the webpack runner file.
20
22
 
21
23
  ### Update Steps to v6.0.0 from v6.0.0.rc.6
24
+
22
25
  _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from v5](#how-to-upgrade-to-webpacker-v600rc6-from-v5) to get to v6.0.0.rc.6 first._
23
26
 
24
27
  1. Change the gem name from `webpacker` to `shakapacker` and the NPM package from `@rails/webpacker` to `shakapacker`.
25
28
  1. Install the peer dependencies. Run `yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server`. You may have old versions of libraries. Run `yarn install` and check for warnings like `warning " > shakapacker@6.1.1" has incorrect peer dependency "compression-webpack-plugin@^9.0.0"` and `file-loader@1.1.11" has incorrect peer dependency "webpack@^2.0.0 || ^3.0.0 || ^4.0.0"`. In other words, warnings like these are **serious** and will cause considerable confusion if not respected.
26
29
  1. Update any scripts that called `bin/webpack` or `bin/webpack-dev-server` to `bin/webpacker` or `bin/webpacker-dev-server`
27
30
  1. Update your webpack config for a single config file, `config/webpack/webpack.config.js`. If you want to use the prior style of having a separate file for each NODE_ENV, you can use this shim for `config/webpack/webpack.config.js`. WARNING, previously, if you did not set `NODE_ENV`, `NODE_ENV` defaulted to `development`. Thus, you might expect `config/webpack/development.js` to run, but you'll instead be using the the configuration file that corresponds to your `RAILS_ENV`. If your `RAILS_ENV` is `test`, you'd be running `config/webpack/test.js`.
31
+
28
32
  ```js
29
33
  // name this file config/webpack/webpack.config.js
30
- const { env, webpackConfig } = require('shakapacker')
31
- const { existsSync } = require('fs')
32
- const { resolve } = require('path')
34
+ const { env, webpackConfig } = require("shakapacker")
35
+ const { existsSync } = require("fs")
36
+ const { resolve } = require("path")
33
37
 
34
38
  const envSpecificConfig = () => {
35
39
  const path = resolve(__dirname, `${env.nodeEnv}.js`)
36
40
  if (existsSync(path)) {
37
41
  console.log(`Loading ENV specific webpack configuration file ${path}`)
38
42
  return require(path)
39
- } else {
43
+ } else {
40
44
  // Probably an error if the file for the NODE_ENV does not exist
41
- throw new Error(`Got Error with NODE_ENV = ${env.nodeEnv}`);
45
+ throw new Error(`Got Error with NODE_ENV = ${env.nodeEnv}`)
42
46
  }
43
47
  }
44
48
 
45
49
  module.exports = envSpecificConfig()
46
50
  ```
51
+
47
52
  1. Update `babel.config.js` if you need JSX support. See [Customizing Babel Config](./customizing_babel_config.md)
48
53
  1. If you are using the view helper called `asset_pack_path`, change "media/" in path to "static/" or consider using the `image_pack_path`.
49
54
 
50
55
  ## How to upgrade to Webpacker v6.0.0.rc.6 from v5
56
+
51
57
  1. Ensure you have a clean working git branch. You will be overwriting all your files and reverting the changes that you don't want.
52
58
 
53
59
  1. **Ensure no nested directories in your `source_entry_path`.** Check if you had any entry point files in child directories of your `source_entry_path`. Files for entry points in child directories are not supported by shakacode/shakapacker v6. Move those files to the top level, adjusting any imports in those files.
@@ -80,67 +86,73 @@ _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from
80
86
  Overwrite all files and check what changed.
81
87
 
82
88
  Note, the webpacker:install will install the peer dependencies:
89
+
83
90
  ```bash
84
91
  yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server
85
92
  ```
86
93
 
87
94
  1. Review the new default's changes to `webpacker.yml`. Consider each suggested change carefully, especially the change to have your `source_entry_path` be at the top level of your `source_path`.
88
95
  The v5 default used `packs` for `source_entry_path`:
96
+
89
97
  ```yml
90
98
  source_path: app/javascript
91
99
  source_entry_path: packs
92
100
  ```
101
+
93
102
  The v6 default uses the top level directory.
103
+
94
104
  ```yml
95
105
  source_path: app/javascript
96
106
  source_entry_path: /
97
107
  ```
108
+
98
109
  If you prefer this configuration, then you will move your `app/javascript/packs/*` (including `application.js`) to `app/javascript/` and update the configuration file.
99
110
 
100
111
  Note, moving your files is optional, as you can still keep your entries in a separate directory, called something like `packs`, or `entries`. This directory is defined with the `source_path`.
101
112
 
102
113
  1. Update `webpack-dev-server` to the current version, greater than 4.2, updating `package.json`.
103
114
 
104
- **Important:** If you encounter the error `[webpack-cli] Invalid options object. Dev Server has been initialized using an options object that does not match the API schema` with an unknown property `_assetEmittingPreviousFiles`, this indicates your webpack-dev-server configuration contains deprecated options.
105
-
115
+ **Important:** If you encounter the error `[webpack-cli] Invalid options object. Dev Server has been initialized using an options object that does not match the API schema` with an unknown property `_assetEmittingPreviousFiles`, this indicates your webpack-dev-server configuration contains deprecated options.
116
+
106
117
  To resolve this issue:
107
118
  - Ensure you're using webpack-cli >= 4.7.0 with webpack-dev-server 5.x (webpack-cli 4.7+ is compatible with webpack-dev-server v5)
108
119
  - Check your current versions: `npm list webpack-cli webpack-dev-server`
109
120
  - Remove any legacy options like `_assetEmittingPreviousFiles` from your dev-server configuration
110
121
  - Review the [webpack-dev-server migration guide](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md) for proper v4 to v5 migration steps
111
-
122
+
112
123
  See [issue #526](https://github.com/shakacode/shakapacker/issues/526) for more details.
113
124
 
114
- 1. Update API usage of the view helpers by changing `javascript_packs_with_chunks_tag` and `stylesheet_packs_with_chunks_tag` to `javascript_pack_tag` and `stylesheet_pack_tag`. Ensure that your layouts and views will only have **at most one call** to `javascript_pack_tag` and **at most one call** to `stylesheet_pack_tag`. You can now pass multiple bundles to these view helper methods. If you fail to changes this, you may experience performance issues, and other bugs related to multiple copies of React, like [issue 2932](https://github.com/rails/webpacker/issues/2932). If you expose jquery globally with `expose-loader` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/javascript/application.js`, pass the option `defer: false` to your `javascript_pack_tag`.
125
+ 1. Update API usage of the view helpers by changing `javascript_packs_with_chunks_tag` and `stylesheet_packs_with_chunks_tag` to `javascript_pack_tag` and `stylesheet_pack_tag`. Ensure that your layouts and views will only have **at most one call** to `javascript_pack_tag` and **at most one call** to `stylesheet_pack_tag`. You can now pass multiple bundles to these view helper methods. If you fail to changes this, you may experience performance issues, and other bugs related to multiple copies of React, like [issue 2932](https://github.com/rails/webpacker/issues/2932). If you expose jquery globally with `expose-loader` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/javascript/application.js`, pass the option `defer: false` to your `javascript_pack_tag`.
115
126
 
116
127
  1. If you are using any integrations like `css`, `postcss`, `React` or `TypeScript`. Please see https://github.com/shakacode/shakapacker#integrations section on how they work in v6.
117
128
 
118
129
  1. `config/webpack/environment.js` was changed to `config/webpack/base.js` and exports a native webpack config so no need to call `toWebpackConfig`.
119
130
  Use `merge` to make changes:
120
-
131
+
121
132
  ```js
122
133
  // config/webpack/base.js
123
- const { webpackConfig, merge } = require('@rails/webpacker');
134
+ const { webpackConfig, merge } = require("@rails/webpacker")
124
135
  const customConfig = {
125
136
  module: {
126
137
  rules: [
127
138
  {
128
- test: require.resolve('jquery'),
129
- loader: 'expose-loader',
139
+ test: require.resolve("jquery"),
140
+ loader: "expose-loader",
130
141
  options: {
131
- exposes: ['$', 'jQuery']
142
+ exposes: ["$", "jQuery"]
132
143
  }
133
144
  }
134
145
  ]
135
146
  }
136
- };
137
-
138
- module.exports = merge(webpackConfig, customConfig);
147
+ }
148
+
149
+ module.exports = merge(webpackConfig, customConfig)
139
150
  ```
140
-
151
+
141
152
  1. Copy over custom browserlist config from `.browserslistrc` if it exists into the `"browserslist"` key in `package.json` and remove `.browserslistrc`.
142
153
 
143
154
  1. Remove `babel.config.js` if you never changed it. Configure your `package.json` to use the default:
155
+
144
156
  ```json
145
157
  "babel": {
146
158
  "presets": [
@@ -148,6 +160,7 @@ _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from
148
160
  ]
149
161
  }
150
162
  ```
163
+
151
164
  See customization example the [Customizing Babel Config](./customizing_babel_config.md) for React configuration.
152
165
 
153
166
  1. `extensions` was removed from the `webpacker.yml` file. Move custom extensions to your configuration by merging an object like this. For more details, see docs for [Webpack Configuration](https://github.com/shakacode/shakapacker/blob/main/README.md#webpack-configuration)
@@ -155,10 +168,11 @@ _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from
155
168
  ```js
156
169
  {
157
170
  resolve: {
158
- extensions: ['.ts', '.tsx', '.vue', '.css']
171
+ extensions: [".ts", ".tsx", ".vue", ".css"]
159
172
  }
160
173
  }
161
174
  ```
175
+
162
176
  1. In `webpacker.yml`, check if you had `watched_paths`. That is now `additional_paths`.
163
177
 
164
178
  1. Some dependencies were removed in [PR 3056](https://github.com/rails/webpacker/pull/3056). If you see the error: `Error: Cannot find module 'babel-plugin-macros'`, or similar, then you need to `yarn add <dependency>` where <dependency> might include: `babel-plugin-macros`, `case-sensitive-paths-webpack-plugin`, `core-js`, `regenerator-runtime`. Or you might want to remove your dependency on those.
@@ -175,7 +189,6 @@ _If you're on webpacker v5, follow [how to upgrade to webpacker v6.0.0.rc.6 from
175
189
 
176
190
  1. Now, follow the steps above to get to shakapacker v6 from webpacker v6.0.0.rc.6
177
191
 
178
-
179
192
  ## Examples of v5 to v6
180
193
 
181
194
  1. [React on Rails Project with HMR and SSR](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/compare/webpacker-5.x...61e897f2c604085f45b9ab5e23642501e430fb28)
data/docs/v7_upgrade.md CHANGED
@@ -14,7 +14,7 @@ Just so you know, Shakapacker v8 will remove any backward compatibility for spel
14
14
 
15
15
  **Note:** At each step of changing the version, ensure that you update both gem and npm versions to the same "exact" version (like `x.y.z` and not `^x.y.z` or `>= x.y.z`).
16
16
 
17
- 1. Upgrade Shakapacker to the latest 6.x version and make sure there are no issues running your application.
17
+ 1. Upgrade Shakapacker to the latest 6.x version and make sure there are no issues running your application.
18
18
  2. Upgrade Shakapacker to version 7.
19
19
  3. Run `rake shakapacker:binstubs` to get the new files in place. Then delete the `bin/webpacker` and `bin/webpacker-dev-server` ones.
20
20
  4. Change spelling from Webpacker to Shakapacker in the code
@@ -23,8 +23,8 @@ Just so you know, Shakapacker v8 will remove any backward compatibility for spel
23
23
  - Rename`Shakapacker.config.webpacker_precompile?` method, replace it with `Shakapacker.config.shakapacker_precompile?`
24
24
  - `--debug-webpacker` is now `--debug-shakapacker` for your shakapacker binstubs.
25
25
  5. Rename files
26
- - Rename `config/webpacker.yml` to `config/shakapacker.yml`.
27
- - Rename environment variables from `WEBPACKER_XYZ` to `SHAKAPACKER_XYZ`.
26
+ - Rename `config/webpacker.yml` to `config/shakapacker.yml`.
27
+ - Rename environment variables from `WEBPACKER_XYZ` to `SHAKAPACKER_XYZ`.
28
28
  6. Where you have used webpackConfig, you must create a new instance with `generateWebpackConfig`. Alternatively, you can rename the import to globalMutableWebpackConfig, which retains the v6 behavior of a global, mutable object.
29
29
  7. You may need to upgrade dependencies in package.json. You should use `yarn upgrade-interactive`.
30
30
 
@@ -35,25 +35,27 @@ When generating file paths for static assets, a top-level directory will no long
35
35
  ## The `webpackConfig` property is changed
36
36
 
37
37
  The `webpackConfig` property in the `shakapacker` module has been changed. The shakapacker module has two options:
38
+
38
39
  1. `generateWebpackConfig`: a function that returns a new webpack configuration object, which ensures that any modifications made to it will not affect any other usage of the webpack configuration.
39
40
  2. `globalMutableWebpackConfig`: if a project still desires the old mutable object. You can rename your imports of `webpackConfig` with `globalMutableWebpackConfig`.
40
41
 
41
42
  ## Example Upgrade
43
+
42
44
  If you started with:
43
45
 
44
46
  ```js
45
- const { webpackConfig } = require('shakapacker')
47
+ const { webpackConfig } = require("shakapacker")
46
48
  ```
47
49
 
48
50
  Switch to:
49
51
 
50
52
  ```js
51
- const { generateWebpackConfig } = require('shakapacker')
53
+ const { generateWebpackConfig } = require("shakapacker")
52
54
  const webpackConfig = generateWebpackConfig()
53
55
  ```
54
56
 
55
57
  or use `globalMutableWebpackConfig` if the project desires to use a globally mutable object.
56
58
 
57
59
  ```js
58
- const { globalMutableWebpackConfig: webpackConfig } = require('shakapacker')
60
+ const { globalMutableWebpackConfig: webpackConfig } = require("shakapacker")
59
61
  ```
data/docs/v8_upgrade.md CHANGED
@@ -18,6 +18,7 @@ If you are not using CDN, then this change will have no effect on your setup.
18
18
  If you are using CDN and your CDN host is static, `config.asset_host` setting in Rails will be respected during compilation and when referencing assets through view helpers.
19
19
 
20
20
  If your host might differ, between various environments for example, you will either need to:
21
+
21
22
  - Ensure the assets are specifically rebuilt for each environment (Heroku pipeline promote feature for example does not do that by default).
22
23
  - Make sure the assets are compiled with `SHAKAPACKER_ASSET_HOST=''` ENV variable to avoid hardcording URLs in packs output.
23
24
 
@@ -131,41 +132,41 @@ The function will return the same object with less risk:
131
132
 
132
133
  ```js
133
134
  // before
134
- const { globalMutableWebpackConfig, merge } = require('shakapacker');
135
+ const { globalMutableWebpackConfig, merge } = require("shakapacker")
135
136
 
136
137
  const customConfig = {
137
138
  module: {
138
139
  rules: [
139
140
  {
140
- test: require.resolve('jquery'),
141
- loader: 'expose-loader',
142
- options: { exposes: ['$', 'jQuery'] }
141
+ test: require.resolve("jquery"),
142
+ loader: "expose-loader",
143
+ options: { exposes: ["$", "jQuery"] }
143
144
  }
144
145
  ]
145
146
  }
146
- };
147
+ }
147
148
 
148
- module.exports = merge(globalMutableWebpackConfig, customConfig);
149
+ module.exports = merge(globalMutableWebpackConfig, customConfig)
149
150
  ```
150
151
 
151
152
  ```js
152
153
  // after
153
- const { generateWebpackConfig, merge } = require('shakapacker');
154
+ const { generateWebpackConfig, merge } = require("shakapacker")
154
155
 
155
156
  const customConfig = {
156
157
  module: {
157
158
  rules: [
158
159
  {
159
- test: require.resolve('jquery'),
160
- loader: 'expose-loader',
161
- options: { exposes: ['$', 'jQuery'] }
160
+ test: require.resolve("jquery"),
161
+ loader: "expose-loader",
162
+ options: { exposes: ["$", "jQuery"] }
162
163
  }
163
164
  ]
164
165
  }
165
- };
166
+ }
166
167
 
167
168
  // you can also pass your config directly to the generator function to have it merged in!
168
- module.exports = merge(generateWebpackConfig(), customConfig);
169
+ module.exports = merge(generateWebpackConfig(), customConfig)
169
170
  ```
170
171
 
171
172
  ## `additional_paths` are now stripped just like with `source_path`
data/docs/v9_upgrade.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This guide outlines new features, breaking changes, and migration steps for upgrading from Shakapacker v8 to v9.
4
4
 
5
+ **📖 For detailed configuration options, see the [Configuration Guide](./configuration.md)**
6
+
5
7
  > **⚠️ Important for v9.1.0 Users:** If you're upgrading to v9.1.0 or later, please note the [SWC Configuration Breaking Change](#swc-loose-mode-breaking-change-v910) below. This affects users who previously configured SWC in v9.0.0.
6
8
 
7
9
  ## New Features
@@ -130,7 +132,6 @@ import * as styles from './Component.module.css';
130
132
  **Migration Options:**
131
133
 
132
134
  1. **Update your code** (Recommended):
133
-
134
135
  - JavaScript: Change to named imports (`import { className }`)
135
136
  - TypeScript: Change to namespace imports (`import * as styles`)
136
137
  - Kebab-case class names are automatically converted to camelCase
@@ -0,0 +1,134 @@
1
+ // Fast ESLint config for quick development feedback
2
+ // Skips type-aware rules that require TypeScript compilation
3
+
4
+ const { FlatCompat } = require("@eslint/eslintrc")
5
+ const js = require("@eslint/js")
6
+ const typescriptParser = require("@typescript-eslint/parser")
7
+ const typescriptPlugin = require("@typescript-eslint/eslint-plugin")
8
+ const jestPlugin = require("eslint-plugin-jest")
9
+ const prettierConfig = require("eslint-config-prettier")
10
+
11
+ const compat = new FlatCompat({
12
+ baseDirectory: __dirname,
13
+ recommendedConfig: js.configs.recommended
14
+ })
15
+
16
+ module.exports = [
17
+ // Global ignores (replaces .eslintignore)
18
+ {
19
+ ignores: [
20
+ "lib/**",
21
+ "**/node_modules/**",
22
+ "vendor/**",
23
+ "spec/**",
24
+ "package/**" // TODO: Remove after issue #644 is resolved (lints package/ TS source files)
25
+ ]
26
+ },
27
+
28
+ // Base config for all JS files
29
+ ...compat.extends("airbnb"),
30
+ {
31
+ languageOptions: {
32
+ ecmaVersion: 2020,
33
+ sourceType: "module",
34
+ globals: {
35
+ // Browser globals
36
+ window: "readonly",
37
+ document: "readonly",
38
+ navigator: "readonly",
39
+ console: "readonly",
40
+ // Node globals
41
+ process: "readonly",
42
+ __dirname: "readonly",
43
+ __filename: "readonly",
44
+ module: "readonly",
45
+ require: "readonly",
46
+ exports: "readonly",
47
+ global: "readonly",
48
+ Buffer: "readonly"
49
+ }
50
+ },
51
+ rules: {
52
+ // Webpack handles module resolution, not ESLint
53
+ "import/no-unresolved": "off",
54
+ // Allow importing devDependencies in config/test files
55
+ "import/no-extraneous-dependencies": "off",
56
+ // TypeScript handles extensions, not needed for JS imports
57
+ "import/extensions": "off",
58
+ indent: ["error", 2]
59
+ },
60
+ settings: {
61
+ react: {
62
+ // Suppress "react package not installed" warning
63
+ // This project doesn't use React but airbnb config requires react-plugin
64
+ version: "999.999.999"
65
+ }
66
+ }
67
+ },
68
+
69
+ // Jest test files
70
+ {
71
+ files: ["test/**"],
72
+ plugins: {
73
+ jest: jestPlugin
74
+ },
75
+ languageOptions: {
76
+ globals: {
77
+ ...jestPlugin.environments.globals.globals
78
+ }
79
+ },
80
+ rules: {
81
+ ...jestPlugin.configs.recommended.rules,
82
+ ...jestPlugin.configs.style.rules,
83
+ "global-require": "off",
84
+ "jest/prefer-called-with": "error",
85
+ "jest/no-conditional-in-test": "error",
86
+ "jest/no-test-return-statement": "error",
87
+ "jest/prefer-expect-resolves": "error",
88
+ "jest/require-to-throw-message": "error",
89
+ "jest/require-top-level-describe": "error",
90
+ "jest/prefer-hooks-on-top": "error",
91
+ "jest/prefer-lowercase-title": [
92
+ "error",
93
+ { ignoreTopLevelDescribe: true }
94
+ ],
95
+ "jest/prefer-spy-on": "error",
96
+ "jest/prefer-strict-equal": "error",
97
+ "jest/prefer-todo": "error"
98
+ }
99
+ },
100
+
101
+ // TypeScript files - fast mode without type-aware linting
102
+ {
103
+ files: ["**/*.ts", "**/*.tsx"],
104
+ languageOptions: {
105
+ parser: typescriptParser,
106
+ parserOptions: {
107
+ // No project specified - disables type-aware linting
108
+ ecmaVersion: 2020,
109
+ sourceType: "module"
110
+ }
111
+ },
112
+ plugins: {
113
+ "@typescript-eslint": typescriptPlugin
114
+ },
115
+ rules: {
116
+ ...typescriptPlugin.configs.recommended.rules,
117
+ // Same rules as main config minus type-aware ones
118
+ "import/no-unresolved": "off",
119
+ "import/no-extraneous-dependencies": "off",
120
+ "import/extensions": "off",
121
+ "no-use-before-define": "off",
122
+ "@typescript-eslint/no-use-before-define": ["error"],
123
+ "@typescript-eslint/no-unused-vars": [
124
+ "error",
125
+ { argsIgnorePattern: "^_" }
126
+ ],
127
+ "@typescript-eslint/no-explicit-any": "error",
128
+ "@typescript-eslint/explicit-module-boundary-types": "off"
129
+ }
130
+ },
131
+
132
+ // Prettier config must be last to override other configs
133
+ prettierConfig
134
+ ]
data/eslint.config.js ADDED
@@ -0,0 +1,140 @@
1
+ const { FlatCompat } = require("@eslint/eslintrc")
2
+ const js = require("@eslint/js")
3
+ const typescriptParser = require("@typescript-eslint/parser")
4
+ const typescriptPlugin = require("@typescript-eslint/eslint-plugin")
5
+ const jestPlugin = require("eslint-plugin-jest")
6
+ const prettierConfig = require("eslint-config-prettier")
7
+
8
+ const compat = new FlatCompat({
9
+ baseDirectory: __dirname,
10
+ recommendedConfig: js.configs.recommended
11
+ })
12
+
13
+ module.exports = [
14
+ // Global ignores (replaces .eslintignore)
15
+ {
16
+ ignores: [
17
+ "lib/**",
18
+ "**/node_modules/**",
19
+ "vendor/**",
20
+ "spec/**",
21
+ "package/**" // TODO: Remove after issue #644 is resolved (lints package/ TS source files)
22
+ ]
23
+ },
24
+
25
+ // Base config for all JS files
26
+ ...compat.extends("airbnb"),
27
+ {
28
+ languageOptions: {
29
+ ecmaVersion: 2020,
30
+ sourceType: "module",
31
+ globals: {
32
+ // Browser globals
33
+ window: "readonly",
34
+ document: "readonly",
35
+ navigator: "readonly",
36
+ console: "readonly",
37
+ // Node globals
38
+ process: "readonly",
39
+ __dirname: "readonly",
40
+ __filename: "readonly",
41
+ module: "readonly",
42
+ require: "readonly",
43
+ exports: "readonly",
44
+ global: "readonly",
45
+ Buffer: "readonly"
46
+ }
47
+ },
48
+ rules: {
49
+ // Webpack handles module resolution, not ESLint
50
+ "import/no-unresolved": "off",
51
+ // Allow importing devDependencies in config/test files
52
+ "import/no-extraneous-dependencies": "off",
53
+ // TypeScript handles extensions, not needed for JS imports
54
+ "import/extensions": "off",
55
+ indent: ["error", 2]
56
+ },
57
+ settings: {
58
+ react: {
59
+ // Suppress "react package not installed" warning
60
+ // This project doesn't use React but airbnb config requires react-plugin
61
+ version: "999.999.999"
62
+ }
63
+ }
64
+ },
65
+
66
+ // Jest test files
67
+ {
68
+ files: ["test/**"],
69
+ plugins: {
70
+ jest: jestPlugin
71
+ },
72
+ languageOptions: {
73
+ globals: {
74
+ ...jestPlugin.environments.globals.globals
75
+ }
76
+ },
77
+ rules: {
78
+ ...jestPlugin.configs.recommended.rules,
79
+ ...jestPlugin.configs.style.rules,
80
+ "global-require": "off",
81
+ "jest/prefer-called-with": "error",
82
+ "jest/no-conditional-in-test": "error",
83
+ "jest/no-test-return-statement": "error",
84
+ "jest/prefer-expect-resolves": "error",
85
+ "jest/require-to-throw-message": "error",
86
+ "jest/require-top-level-describe": "error",
87
+ "jest/prefer-hooks-on-top": "error",
88
+ "jest/prefer-lowercase-title": [
89
+ "error",
90
+ { ignoreTopLevelDescribe: true }
91
+ ],
92
+ "jest/prefer-spy-on": "error",
93
+ "jest/prefer-strict-equal": "error",
94
+ "jest/prefer-todo": "error"
95
+ }
96
+ },
97
+
98
+ // TypeScript files
99
+ {
100
+ files: ["**/*.ts", "**/*.tsx"],
101
+ languageOptions: {
102
+ parser: typescriptParser,
103
+ parserOptions: {
104
+ // Enables type-aware linting for better type safety
105
+ // Note: This can slow down linting on large codebases
106
+ // Consider using --cache flag with ESLint if performance degrades
107
+ project: "./tsconfig.eslint.json",
108
+ tsconfigRootDir: __dirname
109
+ }
110
+ },
111
+ plugins: {
112
+ "@typescript-eslint": typescriptPlugin
113
+ },
114
+ rules: {
115
+ ...typescriptPlugin.configs.recommended.rules,
116
+ ...typescriptPlugin.configs["recommended-requiring-type-checking"].rules,
117
+ // TypeScript compiler handles module resolution
118
+ "import/no-unresolved": "off",
119
+ // Allow importing devDependencies in TypeScript files
120
+ "import/no-extraneous-dependencies": "off",
121
+ // TypeScript handles file extensions via moduleResolution
122
+ "import/extensions": "off",
123
+ // Disable base rule in favor of TypeScript version
124
+ "no-use-before-define": "off",
125
+ "@typescript-eslint/no-use-before-define": ["error"],
126
+ // Allow unused vars if they start with underscore (convention for ignored params)
127
+ "@typescript-eslint/no-unused-vars": [
128
+ "error",
129
+ { argsIgnorePattern: "^_" }
130
+ ],
131
+ // Strict: no 'any' types allowed - use 'unknown' or specific types instead
132
+ "@typescript-eslint/no-explicit-any": "error",
133
+ // Allow implicit return types - TypeScript can infer them
134
+ "@typescript-eslint/explicit-module-boundary-types": "off"
135
+ }
136
+ },
137
+
138
+ // Prettier config must be last to override other configs
139
+ prettierConfig
140
+ ]
data/knip.ts ADDED
@@ -0,0 +1,54 @@
1
+ import type { KnipConfig } from "knip"
2
+
3
+ const config: KnipConfig = {
4
+ project: ["package/**/*.{ts,js}", "test/**/*.{ts,js}", "scripts/**/*.js"],
5
+ ignore: [
6
+ "package/**/*.d.ts",
7
+ "package/**/*.js",
8
+ "package/**/*.js.map",
9
+ "package/**/*.d.ts.map",
10
+ "test/fixtures/**",
11
+ "test/helpers.js", // Test utility file used by jest
12
+ "spec/**",
13
+ "gemfiles/**"
14
+ ],
15
+ ignoreBinaries: ["sed"],
16
+ ignoreDependencies: [
17
+ // These are peer dependencies that may not be directly imported
18
+ "@babel/core",
19
+ "@types/babel__core",
20
+ "@types/webpack",
21
+ "webpack-dev-server",
22
+ // Test/build tooling
23
+ "memory-fs",
24
+ "thenify",
25
+ // Used in type tests but not directly imported
26
+ "@rspack/plugin-react-refresh",
27
+ // CLI tools used by developers
28
+ "@rspack/cli",
29
+ "webpack-cli",
30
+ "husky",
31
+ // Optional dependencies used in webpack/rspack configs
32
+ "mini-css-extract-plugin",
33
+ "webpack-assets-manifest",
34
+ "webpack-subresource-integrity",
35
+ "rspack-manifest-plugin",
36
+ "sass-loader",
37
+ // Package merger utility
38
+ "@types/webpack-merge",
39
+ // Optional runtime dependencies
40
+ "ts-node",
41
+ "@pmmmwh/react-refresh-webpack-plugin",
42
+ // Optional peer dependencies referenced in code
43
+ "@rspack/core",
44
+ "@swc/core",
45
+ "babel-loader",
46
+ "compression-webpack-plugin",
47
+ "css-loader",
48
+ "esbuild-loader",
49
+ "swc-loader",
50
+ "webpack"
51
+ ]
52
+ }
53
+
54
+ export default config
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // Minimal shim - all logic is in the TypeScript module
4
- const { run } = require('shakapacker/configExporter')
4
+ const { run } = require("shakapacker/configExporter")
5
5
 
6
6
  run(process.argv.slice(2))
7
7
  .then((exitCode) => process.exit(exitCode))