shakapacker 9.0.0.beta.7 → 9.0.0.beta.8

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.fast.js +40 -0
  3. data/.eslintrc.js +48 -0
  4. data/.gitignore +1 -3
  5. data/.npmignore +1 -0
  6. data/CHANGELOG.md +64 -1
  7. data/CONTRIBUTING.md +75 -21
  8. data/Gemfile.lock +1 -1
  9. data/TODO.md +15 -16
  10. data/lib/shakapacker/version.rb +1 -1
  11. data/package/babel/preset.ts +56 -0
  12. data/package/esbuild/index.ts +42 -0
  13. data/package/optimization/rspack.ts +36 -0
  14. data/package/optimization/{webpack.js → webpack.ts} +12 -4
  15. data/package/plugins/{rspack.js → rspack.ts} +20 -5
  16. data/package/plugins/{webpack.js → webpack.ts} +2 -2
  17. data/package/rspack/{index.js → index.ts} +17 -10
  18. data/package/rules/{babel.js → babel.ts} +1 -1
  19. data/package/rules/{coffee.js → coffee.ts} +1 -1
  20. data/package/rules/{css.js → css.ts} +1 -1
  21. data/package/rules/{erb.js → erb.ts} +1 -1
  22. data/package/rules/{esbuild.js → esbuild.ts} +2 -2
  23. data/package/rules/{file.js → file.ts} +11 -6
  24. data/package/rules/{jscommon.js → jscommon.ts} +4 -4
  25. data/package/rules/{less.js → less.ts} +3 -3
  26. data/package/rules/raw.ts +25 -0
  27. data/package/rules/{rspack.js → rspack.ts} +21 -11
  28. data/package/rules/{sass.js → sass.ts} +1 -1
  29. data/package/rules/{stylus.js → stylus.ts} +3 -7
  30. data/package/rules/{swc.js → swc.ts} +2 -2
  31. data/package/rules/{webpack.js → webpack.ts} +1 -1
  32. data/package/swc/index.ts +54 -0
  33. data/package.json +22 -2
  34. data/scripts/type-check-no-emit.js +27 -0
  35. data/test/package/rules/raw.test.js +40 -7
  36. data/test/package/rules/webpack.test.js +21 -2
  37. data/tsconfig.eslint.json +16 -0
  38. data/tsconfig.json +9 -10
  39. data/yarn.lock +415 -6
  40. metadata +27 -24
  41. data/package/babel/preset.js +0 -48
  42. data/package/esbuild/index.js +0 -40
  43. data/package/optimization/rspack.js +0 -29
  44. data/package/rules/raw.js +0 -15
  45. data/package/swc/index.js +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca5207ce21d40303f0a0250d140763ca93000a318ba28a9ac8efff358ce59310
4
- data.tar.gz: f494c9a43b2c9fc704ca6dc1e3110f0c7048759a13e3f8254c44735e91a58da0
3
+ metadata.gz: 6b968c57e16cafe6ddb6fb317b442db6b96682ee075498f3b8bc60f43f87d7bd
4
+ data.tar.gz: a3bf4f39a4c6b869e3301723423387577a78a0818403c1bb31efd42f9bc0ac7c
5
5
  SHA512:
6
- metadata.gz: a13fd3b73ffb91546e25c8226731efd4cdf6e8024893011795e32f379d2c3ffd14a4b5286b2a32499447405a01624b50805aafd6749112538e560ab21bc58e7e
7
- data.tar.gz: d9911ec4c3a53a6baf3598e48b29e74684113a6514e979c73b69479905399e94abc67c0792a51c1cf12c5961a771c9de1f19e1800991f9a638dfab5ebcd1e606
6
+ metadata.gz: ebfa33ceea921c0c66f9a9affb4eb1c736c981696d87523e4a55f82311e6779a28b3b9ca0b8b8a270fb00dbd04302be57928091f4b7c7b580ee66d2585c98f4f
7
+ data.tar.gz: 61a683b023eec46e7beb3a294db371b28ac1d8668744d7212ab938eb5a0a1fe53dba7763f5f9e90374ed329cb2f6ae07a232f3b0970e3bb4d504f4b79ea9eaeb
data/.eslintrc.fast.js ADDED
@@ -0,0 +1,40 @@
1
+ // Fast ESLint config for quick development feedback
2
+ // Skips type-aware rules that require TypeScript compilation
3
+
4
+ const baseConfig = require("./.eslintrc.js")
5
+
6
+ module.exports = {
7
+ ...baseConfig,
8
+ overrides: [
9
+ ...baseConfig.overrides.filter((o) => !o.files.includes("**/*.{ts,tsx}")),
10
+ {
11
+ files: ["**/*.{ts,tsx}"],
12
+ parser: "@typescript-eslint/parser",
13
+ parserOptions: {
14
+ // No project specified - disables type-aware linting
15
+ ecmaVersion: 2020,
16
+ sourceType: "module"
17
+ },
18
+ extends: [
19
+ "plugin:@typescript-eslint/recommended",
20
+ // Skip the "recommended-requiring-type-checking" preset
21
+ "plugin:prettier/recommended"
22
+ ],
23
+ plugins: ["@typescript-eslint"],
24
+ rules: {
25
+ // Same rules as main config minus type-aware ones
26
+ "import/no-unresolved": "off",
27
+ "import/no-extraneous-dependencies": "off",
28
+ "import/extensions": "off",
29
+ "no-use-before-define": "off",
30
+ "@typescript-eslint/no-use-before-define": ["error"],
31
+ "@typescript-eslint/no-unused-vars": [
32
+ "error",
33
+ { argsIgnorePattern: "^_" }
34
+ ],
35
+ "@typescript-eslint/no-explicit-any": "error",
36
+ "@typescript-eslint/explicit-module-boundary-types": "off"
37
+ }
38
+ }
39
+ ]
40
+ }
data/.eslintrc.js CHANGED
@@ -1,11 +1,22 @@
1
1
  module.exports = {
2
+ root: true, // Prevent ESLint from looking in parent directories
2
3
  extends: ["airbnb", "plugin:prettier/recommended"],
3
4
  rules: {
5
+ // Webpack handles module resolution, not ESLint
4
6
  "import/no-unresolved": "off",
7
+ // Allow importing devDependencies in config/test files
5
8
  "import/no-extraneous-dependencies": "off",
9
+ // TypeScript handles extensions, not needed for JS imports
6
10
  "import/extensions": "off",
7
11
  indent: ["error", 2]
8
12
  },
13
+ settings: {
14
+ react: {
15
+ // Suppress "react package not installed" warning
16
+ // This project doesn't use React but airbnb config requires react-plugin
17
+ version: "999.999.999"
18
+ }
19
+ },
9
20
  env: {
10
21
  browser: true,
11
22
  node: true
@@ -31,6 +42,43 @@ module.exports = {
31
42
  "jest/prefer-strict-equal": "error",
32
43
  "jest/prefer-todo": "error"
33
44
  }
45
+ },
46
+ {
47
+ files: ["**/*.{ts,tsx}"],
48
+ parser: "@typescript-eslint/parser",
49
+ parserOptions: {
50
+ // Enables type-aware linting for better type safety
51
+ // Note: This can slow down linting on large codebases
52
+ // Consider using --cache flag with ESLint if performance degrades
53
+ project: "./tsconfig.eslint.json",
54
+ tsconfigRootDir: __dirname
55
+ },
56
+ extends: [
57
+ "plugin:@typescript-eslint/recommended",
58
+ "plugin:@typescript-eslint/recommended-requiring-type-checking",
59
+ "plugin:prettier/recommended"
60
+ ],
61
+ plugins: ["@typescript-eslint"],
62
+ rules: {
63
+ // TypeScript compiler handles module resolution
64
+ "import/no-unresolved": "off",
65
+ // Allow importing devDependencies in TypeScript files
66
+ "import/no-extraneous-dependencies": "off",
67
+ // TypeScript handles file extensions via moduleResolution
68
+ "import/extensions": "off",
69
+ // Disable base rule in favor of TypeScript version
70
+ "no-use-before-define": "off",
71
+ "@typescript-eslint/no-use-before-define": ["error"],
72
+ // Allow unused vars if they start with underscore (convention for ignored params)
73
+ "@typescript-eslint/no-unused-vars": [
74
+ "error",
75
+ { argsIgnorePattern: "^_" }
76
+ ],
77
+ // Strict: no 'any' types allowed - use 'unknown' or specific types instead
78
+ "@typescript-eslint/no-explicit-any": "error",
79
+ // Allow implicit return types - TypeScript can infer them
80
+ "@typescript-eslint/explicit-module-boundary-types": "off"
81
+ }
34
82
  }
35
83
  ]
36
84
  }
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ yarn-error.log*
11
11
  /log
12
12
  gemfiles/*.lock
13
13
  .DS_Store
14
+ .eslintcache
14
15
 
15
16
  .yalc
16
17
  yalc.lock
@@ -25,11 +26,8 @@ package/**/*.js
25
26
  !package/index.d.ts
26
27
  !package/loaders.d.ts
27
28
  !package/webpack-types.d.ts
28
- !package/babel/preset.js
29
29
  !package/babel/preset-react.js
30
- !package/rules/*.js
31
30
  !package/loaders/*.js
32
- !package/plugins/*.js
33
31
  !package/__mocks__/*.js
34
32
  !package/utils/get_style_rule.js
35
33
  !package/utils/node_modules.js
data/.npmignore CHANGED
@@ -10,6 +10,7 @@
10
10
  /gemfiles
11
11
  /.github
12
12
  /.circleci
13
+ /.husky
13
14
  /.byebug_history
14
15
  .DS_Store
15
16
  yarn-debug.log*
data/CHANGELOG.md CHANGED
@@ -9,7 +9,70 @@
9
9
  ## [Unreleased]
10
10
  Changes since the last non-beta release.
11
11
 
12
- ## [v9.0.0-beta.4] - Unreleased
12
+ ### Added
13
+ - **Phase 5 TypeScript Migration - Framework-Specific Modules** by [justin808](https://github.com/justin808)
14
+ - Converted framework-specific modules to TypeScript
15
+ - Migrated package/rspack/index.js to TypeScript
16
+ - Migrated package/swc/index.js to TypeScript
17
+ - Migrated package/esbuild/index.js to TypeScript
18
+ - Migrated package/babel/preset.js to TypeScript
19
+ - Added @types/babel__core for enhanced type safety
20
+ - All 130 tests passing
21
+ - **Phase 6 TypeScript Migration - Final Cleanup** (by [justin808](https://github.com/justin808))
22
+ - Added TypeScript ESLint support with @typescript-eslint/parser and @typescript-eslint/eslint-plugin
23
+ - Configured TypeScript-specific linting rules for improved code quality
24
+ - Verified strict mode is enabled in TypeScript configuration
25
+ - Enhanced developer experience with TypeScript linting across the entire codebase
26
+
27
+ ## [v9.0.0-beta.7] - October 1, 2025
28
+
29
+ ### Added
30
+ - **Phase 2 TypeScript Migration - Core Modules** ([PR 608](https://github.com/shakacode/shakapacker/pull/608) by [justin808](https://github.com/justin808))
31
+ - Converted core modules to TypeScript: config.ts, env.ts, and utilities
32
+ - Enhanced type safety across the codebase
33
+ - Better IDE support and autocomplete
34
+ - **Phase 3 TypeScript Migration - Environment Files** ([PR 614](https://github.com/shakacode/shakapacker/pull/614) by [justin808](https://github.com/justin808))
35
+ - Converted all environment configuration files to TypeScript (development, production, test)
36
+ - Added centralized type exports for consumer use (import from "shakapacker/types")
37
+ - Created shared TypeScript interfaces for environment configurations
38
+ - Introduced structured error codes for programmatic error handling
39
+ - Exported shared types: WebpackConfig, RspackConfig, EnvironmentConfig
40
+ - **Optional Peer Dependencies** ([PR 615](https://github.com/shakacode/shakapacker/pull/615) by [justin808](https://github.com/justin808))
41
+ - Restored peer dependencies as optional to improve package version tracking
42
+ - Added peerDependenciesMeta marking all peers as optional
43
+ - Moved webpack-merge to direct dependencies (required at runtime)
44
+ - Prevents installation warnings while maintaining upgrade visibility
45
+ - **Migration Tooling Improvements** ([PR 613](https://github.com/shakacode/shakapacker/pull/613) by [justin808](https://github.com/justin808))
46
+ - Added SWC migration helper: rake shakapacker:migrate:to_swc
47
+ - Enhanced error messages for missing dependencies
48
+ - Improved doctor command output
49
+
50
+ ### Security
51
+ - **Path Validation Utilities** ([PR 614](https://github.com/shakacode/shakapacker/pull/614) by [justin808](https://github.com/justin808))
52
+ - Added validation to prevent directory traversal attacks
53
+ - Implemented environment variable sanitization to prevent injection
54
+ - Enforced strict port validation (reject strings with non-digits)
55
+ - Added SHAKAPACKER_NPM_PACKAGE path validation (only .tgz/.tar.gz allowed)
56
+ - Path traversal security checks now run regardless of validation mode
57
+
58
+ ### Changed
59
+ - **Build Process Improvements** ([PR 614](https://github.com/shakacode/shakapacker/pull/614) by [justin808](https://github.com/justin808))
60
+ - Environment JS files now generated during npm publish (not committed to git)
61
+ - Prevents TypeScript source and compiled JS from getting out of sync
62
+ - Auto-format compiled JavaScript during build process
63
+ - Enhanced .npmignore to exclude TypeScript sources, include compiled JS
64
+
65
+ ### Performance
66
+ - **Validation Caching** ([PR 614](https://github.com/shakacode/shakapacker/pull/614) by [justin808](https://github.com/justin808))
67
+ - Implemented TTL-based validation caching (5s watch, 1min dev, infinite prod)
68
+ - Made cache TTL configurable via SHAKAPACKER_CACHE_TTL environment variable
69
+ - Lazy-loaded and cached watch mode detection
70
+
71
+ ### Fixed
72
+ - Fixed clearValidationCache() to actually clear the cache ([PR 614](https://github.com/shakacode/shakapacker/pull/614) by [justin808](https://github.com/justin808))
73
+ - Fixed private_output_path configuration edge cases ([PR 604](https://github.com/shakacode/shakapacker/pull/604) by [justin808](https://github.com/justin808))
74
+
75
+ ## [v9.0.0-beta.4] - September 15, 2025
13
76
 
14
77
  ### ⚠️ Breaking Changes
15
78
 
data/CONTRIBUTING.md CHANGED
@@ -3,6 +3,7 @@
3
3
  Thank you for your interest in contributing to Shakapacker! We welcome all contributions that align with our project goals and values. To ensure a smooth and productive collaboration, please follow these guidelines.
4
4
 
5
5
  ## Contents
6
+
6
7
  - [Reporting Issues](#reporting-issues)
7
8
  - [Submitting Pull Requests](#submitting-pull-requests)
8
9
  - [Setting Up a Development Environment](#setting-up-a-development-environment)
@@ -10,44 +11,89 @@ Thank you for your interest in contributing to Shakapacker! We welcome all contr
10
11
  - [Testing the generator](#testing-the-generator)
11
12
 
12
13
  ## Reporting Issues
14
+
13
15
  If you encounter any issues with the project, please first check the existing issues (including closed ones). If the issues is not reported before, please opening an issue on our GitHub repository. Please provide a clear and detailed description of the issue, including steps to reproduce it. Creating a demo repository to demonstrate the issue would be ideal (and in some cases necessary).
14
16
 
15
17
  If looking to contribute to the project by fixing existing issues, we recommend looking at issues, particularly with the "[help wanted](https://github.com/shakacode/shakapacker/issues?q=is%3Aissue+label%3A%22help+wanted%22)" label.
16
18
 
17
19
  ## Submitting Pull Requests
20
+
18
21
  We welcome pull requests that fix bugs, add new features, or improve existing ones. Before submitting a pull request, please make sure to:
19
22
 
20
- - Open an issue about what you want to propose before start working on.
21
- - Fork the repository and create a new branch for your changes.
22
- - Write clear and concise commit messages.
23
- - Follow our code style guidelines.
24
- - Write tests for your changes and [make sure all tests pass](#making-sure-your-changes-pass-all-tests).
25
- - Update the documentation as needed.
26
- - Update CHANGELOG.md if the changes affect public behavior of the project.
23
+ - Open an issue about what you want to propose before start working on.
24
+ - Fork the repository and create a new branch for your changes.
25
+ - Write clear and concise commit messages.
26
+ - Follow our code style guidelines.
27
+ - Write tests for your changes and [make sure all tests pass](#making-sure-your-changes-pass-all-tests).
28
+ - Update the documentation as needed.
29
+ - Update CHANGELOG.md if the changes affect public behavior of the project.
27
30
 
28
31
  ---
32
+
33
+ ## Git Hooks (Optional)
34
+
35
+ This project includes configuration for git hooks via `husky` and `lint-staged`, but they are **opt-in for contributors**.
36
+
37
+ **Why are hooks optional?** As a library project, we don't enforce git hooks because:
38
+
39
+ - Different contributors may have different workflows
40
+ - Forcing hooks can interfere with contributor tooling
41
+ - CI/CD handles the final validation
42
+
43
+ To enable pre-commit hooks locally:
44
+
45
+ ```bash
46
+ npx husky install
47
+ npx husky add .husky/pre-commit "npx lint-staged"
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Linting and Code Quality
53
+
54
+ ### Running Linters
55
+
56
+ ```bash
57
+ # Full linting with type checking (slower but thorough)
58
+ yarn lint
59
+
60
+ # Fast linting without type checking (for quick feedback)
61
+ yarn lint:fast
62
+
63
+ # With caching for better performance
64
+ yarn lint --cache
65
+ ```
66
+
67
+ **Performance Note:** TypeScript ESLint uses type-aware linting for better type safety, which can be slower on large codebases. Use `yarn lint:fast` during development for quick feedback.
68
+
69
+ ---
70
+
29
71
  ## Setting Up a Development Environment
30
72
 
31
73
  1. Install [Yarn](https://classic.yarnpkg.com/)
32
74
  2. To test your changes on a Rails test project do the following steps:
75
+
33
76
  - For Ruby gem, update `Gemfile` and point the `shakapacker` to the locally developing Shakapacker project:
34
- ```ruby
35
- gem 'shakapacker', path: "relative_or_absolute_path_to_local_shakapacker"
36
- ```
77
+ ```ruby
78
+ gem 'shakapacker', path: "relative_or_absolute_path_to_local_shakapacker"
79
+ ```
37
80
  - For npm package, use `yalc` with following steps:
38
- ```bash
39
- # In Shakapacker root directory
40
- yalc publish
41
- # In Rails app for testing
42
- yalc link shakapacker
43
-
44
- # After every change in shakapacker, run the following in Shakapacker directory
45
- yalc push # or yalc publish --push
46
- ```
81
+
82
+ ```bash
83
+ # In Shakapacker root directory
84
+ yalc publish
85
+ # In Rails app for testing
86
+ yalc link shakapacker
87
+
88
+ # After every change in shakapacker, run the following in Shakapacker directory
89
+ yalc push # or yalc publish --push
90
+ ```
91
+
47
92
  3. Run the following commands to set up the development environment.
48
93
  ```
49
94
  bundle install
50
95
  yarn install
96
+ yarn prepare:husky # Set up pre-commit hooks for linting
51
97
  ```
52
98
 
53
99
  ## Understanding Optional Peer Dependencies
@@ -59,11 +105,13 @@ Shakapacker uses optional peer dependencies (via `peerDependenciesMeta`) for max
59
105
  - **Version constraints still apply** - When a package is installed, version compatibility is enforced
60
106
 
61
107
  ### When modifying dependencies:
108
+
62
109
  1. Add new peer dependencies to both `peerDependencies` and `peerDependenciesMeta` (marking as optional)
63
110
  2. Keep version ranges synchronized between `devDependencies` and `peerDependencies`
64
111
  3. Test with multiple package managers: `npm`, `yarn`, and `pnpm`
65
112
 
66
113
  ### Testing peer dependency changes:
114
+
67
115
  ```bash
68
116
  # Test with npm (no warnings expected)
69
117
  cd /tmp && mkdir test-npm && cd test-npm
@@ -129,6 +177,7 @@ bundle exec rake run_spec:gem
129
177
  ```
130
178
 
131
179
  #### 4.4 Run only Shakapacker gem specs for backward compatibility
180
+
132
181
  These specs are to check Shakapacker v7 backward compatibility with v6.x
133
182
 
134
183
  ```
@@ -136,6 +185,7 @@ bundle exec rake run_spec:gem_bc
136
185
  ```
137
186
 
138
187
  #### 4.5 Run dummy app test
188
+
139
189
  For this, you need `yalc` to be installed on your local machine
140
190
 
141
191
  ```
@@ -143,6 +193,7 @@ bundle exec rake run_spec:dummy
143
193
  ```
144
194
 
145
195
  #### 4.6 Testing the installer
196
+
146
197
  To ensure that your installer works as expected, either you can run `bundle exec rake run_spec:install`, or take the following manual testing steps:
147
198
 
148
199
  1. Update the `Gemfile` so that gem `shakapacker` has a line like this, pointing to your developing Shakapacker:
@@ -152,7 +203,7 @@ To ensure that your installer works as expected, either you can run `bundle exec
152
203
  2. Run `bundle install` to install the updated gem.
153
204
  3. Run `bundle exec rails shakapacker:install` to confirm that you got the right changes.
154
205
 
155
- **Note:** Ensure that you use bundle exec otherwise the installed shakapacker gem will run and not the one you are working on.
206
+ **Note:** Ensure that you use bundle exec otherwise the installed shakapacker gem will run and not the one you are working on.
156
207
 
157
208
  ## CI Workflows
158
209
 
@@ -161,6 +212,7 @@ Shakapacker uses GitHub Actions for continuous integration. The CI workflows use
161
212
  ### Package Manager Choice
162
213
 
163
214
  The project uses Yarn in CI workflows for the following reasons:
215
+
164
216
  - Deterministic dependency resolution with `yarn.lock`
165
217
  - Faster installation with offline mirror support
166
218
  - Better workspace support for monorepo-style testing
@@ -174,14 +226,16 @@ The project uses Yarn in CI workflows for the following reasons:
174
226
  - `.github/workflows/generator.yml` - Generator installation tests
175
227
 
176
228
  All workflows use:
229
+
177
230
  ```yaml
178
231
  - uses: actions/setup-node@v4
179
232
  with:
180
- cache: 'yarn'
233
+ cache: "yarn"
181
234
  cache-dependency-path: spec/dummy/yarn.lock
182
235
  ```
183
236
 
184
237
  And install dependencies with:
238
+
185
239
  ```bash
186
240
  yarn install
187
241
  ```
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (9.0.0.beta.7)
4
+ shakapacker (9.0.0.beta.8)
5
5
  activesupport (>= 5.2)
6
6
  package_json
7
7
  rack-proxy (>= 0.6.1)
data/TODO.md CHANGED
@@ -22,22 +22,21 @@
22
22
  - [ ] Convert dev_server.js
23
23
  - [ ] Convert webpackDevServerConfig.js
24
24
 
25
- ### Phase 4: Rules & Loaders
26
- - [ ] Convert all files in `package/rules/`
27
- - [ ] Convert all files in `package/plugins/`
28
- - [ ] Convert all files in `package/optimization/`
29
-
30
- ### Phase 5: Framework-Specific Modules
31
- - [ ] Convert rspack support files
32
- - [ ] Convert swc support files
33
- - [ ] Convert esbuild support files
34
- - [ ] Convert babel preset
35
-
36
- ### Phase 6: Final Cleanup
37
- - [ ] Convert remaining utilities
38
- - [ ] Add TypeScript linting
39
- - [ ] Enable strict mode
40
- - [ ] Update documentation
25
+ ### Phase 4: Rules & Loaders (PR #620) ✅
26
+ - [x] Convert all files in `package/rules/`
27
+ - [x] Convert all files in `package/plugins/`
28
+ - [x] Convert all files in `package/optimization/`
29
+
30
+ ### Phase 5: Framework-Specific Modules
31
+ - [x] Convert rspack support files
32
+ - [x] Convert swc support files
33
+ - [x] Convert esbuild support files
34
+ - [x] Convert babel preset
35
+
36
+ ### Phase 6: Final Cleanup
37
+ - [x] Add TypeScript linting with @typescript-eslint
38
+ - [x] Verify strict mode is enabled (already configured)
39
+ - [x] Update documentation
41
40
 
42
41
  ## Why Gradual Migration?
43
42
  - **Lower risk**: Each phase can be tested independently
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.0.0.beta.7".freeze
3
+ VERSION = "9.0.0.beta.8".freeze
4
4
  end
@@ -0,0 +1,56 @@
1
+ import { moduleExists, packageFullVersion } from "../utils/helpers"
2
+ import type { ConfigAPI, PluginItem } from "@babel/core"
3
+
4
+ const CORE_JS_VERSION_REGEX = /^\d+\.\d+/
5
+
6
+ const coreJsVersion = (): string => {
7
+ try {
8
+ const version = packageFullVersion("core-js").match(CORE_JS_VERSION_REGEX)
9
+ return version?.[0] ?? "3.8"
10
+ } catch (e) {
11
+ const error = e as NodeJS.ErrnoException
12
+ if (error.code !== "MODULE_NOT_FOUND") {
13
+ throw e
14
+ }
15
+
16
+ return "3.8"
17
+ }
18
+ }
19
+
20
+ export = function config(api: ConfigAPI): { presets: PluginItem[]; plugins: PluginItem[] } {
21
+ const validEnv = ["development", "test", "production"]
22
+ const currentEnv = api.env()
23
+ const isDevelopmentEnv = api.env("development")
24
+ const isProductionEnv = api.env("production")
25
+ const isTestEnv = api.env("test")
26
+
27
+ if (!validEnv.includes(currentEnv)) {
28
+ throw new Error(
29
+ `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${currentEnv}".`
30
+ )
31
+ }
32
+
33
+ const presets: PluginItem[] = [
34
+ isTestEnv && ["@babel/preset-env", { targets: { node: "current" } }],
35
+ (isProductionEnv || isDevelopmentEnv) && [
36
+ "@babel/preset-env",
37
+ {
38
+ useBuiltIns: "entry",
39
+ corejs: coreJsVersion(),
40
+ modules: "auto",
41
+ bugfixes: true,
42
+ exclude: ["transform-typeof-symbol"]
43
+ }
44
+ ],
45
+ moduleExists("@babel/preset-typescript") && "@babel/preset-typescript"
46
+ ].filter(Boolean) as PluginItem[]
47
+
48
+ const plugins: PluginItem[] = [["@babel/plugin-transform-runtime", { helpers: false }]].filter(
49
+ Boolean
50
+ ) as PluginItem[]
51
+
52
+ return {
53
+ presets,
54
+ plugins
55
+ }
56
+ }
@@ -0,0 +1,42 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ import { resolve } from "path"
5
+ import { existsSync } from "fs"
6
+ import { merge } from "webpack-merge"
7
+ import type { RuleSetRule } from "webpack"
8
+
9
+ const LOADER_EXT_REGEX = /\.([jt]sx?)(\.erb)?$/
10
+
11
+ const getLoaderExtension = (filename: string): string => {
12
+ const matchData = filename.match(LOADER_EXT_REGEX)
13
+
14
+ if (!matchData) {
15
+ return "js"
16
+ }
17
+
18
+ return matchData[1] ?? "js"
19
+ }
20
+
21
+ const getCustomConfig = (): Partial<RuleSetRule> => {
22
+ const path = resolve("config", "esbuild.config.js")
23
+ if (existsSync(path)) {
24
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
25
+ return require(path)
26
+ }
27
+ return {}
28
+ }
29
+
30
+ const getEsbuildLoaderConfig = (filenameToProcess: string): RuleSetRule => {
31
+ const customConfig = getCustomConfig()
32
+ const defaultConfig: RuleSetRule = {
33
+ loader: require.resolve("esbuild-loader"),
34
+ options: {
35
+ loader: getLoaderExtension(filenameToProcess)
36
+ }
37
+ }
38
+
39
+ return merge(defaultConfig, customConfig)
40
+ }
41
+
42
+ export { getEsbuildLoaderConfig }
@@ -0,0 +1,36 @@
1
+ const { requireOrError } = require("../utils/requireOrError")
2
+ const { error: logError } = require("../utils/debug")
3
+
4
+ const rspack = requireOrError("@rspack/core")
5
+
6
+ interface OptimizationConfig {
7
+ minimize: boolean
8
+ minimizer?: unknown[]
9
+ }
10
+
11
+ const getOptimization = (): OptimizationConfig => {
12
+ // Use Rspack's built-in minification instead of terser-webpack-plugin
13
+ const result: OptimizationConfig = { minimize: true }
14
+ try {
15
+ result.minimizer = [
16
+ new rspack.SwcJsMinimizerRspackPlugin(),
17
+ new rspack.LightningCssMinimizerRspackPlugin()
18
+ ]
19
+ } catch (error: unknown) {
20
+ const errorMessage = error instanceof Error ? error.message : String(error)
21
+ const errorStack = error instanceof Error ? error.stack : ''
22
+ // Log full error with stack trace
23
+ logError(
24
+ `Failed to configure Rspack minimizers: ${errorMessage}\n${errorStack}`
25
+ )
26
+ // Re-throw the error to properly propagate it
27
+ throw new Error(
28
+ `Could not configure Rspack minimizers: ${errorMessage}. Please check that @rspack/core is properly installed.`
29
+ )
30
+ }
31
+ return result
32
+ }
33
+
34
+ export = {
35
+ getOptimization
36
+ }
@@ -3,7 +3,7 @@ const { requireOrError } = require("../utils/requireOrError")
3
3
  const TerserPlugin = requireOrError("terser-webpack-plugin")
4
4
  const { moduleExists } = require("../utils/helpers")
5
5
 
6
- const tryCssMinimizer = () => {
6
+ const tryCssMinimizer = (): unknown | null => {
7
7
  if (
8
8
  moduleExists("css-loader") &&
9
9
  moduleExists("css-minimizer-webpack-plugin")
@@ -15,12 +15,20 @@ const tryCssMinimizer = () => {
15
15
  return null
16
16
  }
17
17
 
18
- const getOptimization = () => {
18
+ interface OptimizationConfig {
19
+ minimizer: unknown[]
20
+ }
21
+
22
+ const getOptimization = (): OptimizationConfig => {
19
23
  return {
20
24
  minimizer: [
21
25
  tryCssMinimizer(),
22
26
  new TerserPlugin({
23
- parallel: Number.parseInt(process.env.SHAKAPACKER_PARALLEL, 10) || true,
27
+ // SHAKAPACKER_PARALLEL env var: number of parallel workers, or true for auto (os.cpus().length - 1)
28
+ // If not set or invalid, defaults to true (automatic parallelization)
29
+ parallel: process.env.SHAKAPACKER_PARALLEL
30
+ ? Number.parseInt(process.env.SHAKAPACKER_PARALLEL, 10) || true
31
+ : true,
24
32
  terserOptions: {
25
33
  parse: {
26
34
  // Let terser parse ecma 8 code but always output
@@ -44,6 +52,6 @@ const getOptimization = () => {
44
52
  }
45
53
  }
46
54
 
47
- module.exports = {
55
+ export = {
48
56
  getOptimization
49
57
  }