shakapacker 8.4.0 → 9.7.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.
- checksums.yaml +4 -4
- data/.claude/commands/address-review.md +206 -0
- data/.claude/commands/update-changelog.md +354 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +6 -9
- data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
- data/.github/STATUS.md +1 -0
- data/.github/actionlint-matcher.json +17 -0
- data/.github/workflows/claude-code-review.yml +45 -0
- data/.github/workflows/claude.yml +55 -0
- data/.github/workflows/dummy.yml +18 -5
- data/.github/workflows/eslint-validation.yml +46 -0
- data/.github/workflows/generator.yml +38 -22
- data/.github/workflows/node.yml +116 -2
- data/.github/workflows/ruby.yml +57 -15
- data/.github/workflows/test-bundlers.yml +180 -0
- data/.gitignore +27 -0
- data/.husky/pre-commit +2 -0
- data/.npmignore +56 -0
- data/.prettierignore +7 -0
- data/.rubocop.yml +2 -0
- data/.yalcignore +26 -0
- data/CHANGELOG.md +487 -19
- data/CLAUDE.md +63 -0
- data/CONTRIBUTING.md +268 -21
- data/ESLINT_TECHNICAL_DEBT.md +165 -0
- data/README.md +497 -137
- data/Rakefile +44 -4
- data/TODO.md +58 -0
- data/TODO_v9.md +97 -0
- data/bin/conductor-exec +24 -0
- data/bin/shakapacker-config +11 -0
- data/conductor-setup.sh +147 -0
- data/conductor.json +9 -0
- data/docs/api-reference.md +519 -0
- data/docs/cdn_setup.md +384 -0
- data/docs/common-upgrades.md +695 -0
- data/docs/configuration.md +845 -0
- data/docs/css-modules-export-mode.md +566 -0
- data/docs/customizing_babel_config.md +16 -16
- data/docs/deployment.md +78 -7
- data/docs/developing_shakapacker.md +6 -0
- data/docs/early_hints.md +433 -0
- data/docs/early_hints_manual_api.md +454 -0
- data/docs/feature_testing.md +492 -0
- data/docs/node_package_api.md +70 -0
- data/docs/optional-peer-dependencies.md +203 -0
- data/docs/peer-dependencies.md +71 -0
- data/docs/precompile_hook.md +486 -0
- data/docs/preventing_fouc.md +132 -0
- data/docs/react.md +58 -48
- data/docs/releasing.md +288 -0
- data/docs/rspack.md +218 -0
- data/docs/rspack_migration_guide.md +862 -0
- data/docs/sprockets.md +1 -0
- data/docs/style_loader_vs_mini_css.md +12 -12
- data/docs/subresource_integrity.md +13 -7
- data/docs/transpiler-migration.md +212 -0
- data/docs/transpiler-performance.md +200 -0
- data/docs/troubleshooting.md +272 -24
- data/docs/typescript-migration.md +388 -0
- data/docs/typescript.md +103 -0
- data/docs/using_esbuild_loader.md +12 -12
- data/docs/using_swc_loader.md +121 -16
- data/docs/v6_upgrade.md +42 -19
- data/docs/v7_upgrade.md +8 -6
- data/docs/v8_upgrade.md +13 -12
- data/docs/v9_upgrade.md +616 -0
- data/eslint.config.fast.js +254 -0
- data/eslint.config.js +309 -0
- data/jest.config.js +8 -1
- data/knip.ts +61 -0
- data/lib/install/bin/shakapacker +4 -6
- data/lib/install/bin/shakapacker-config +11 -0
- data/lib/install/bin/shakapacker-dev-server +1 -1
- data/lib/install/binstubs.rb +6 -2
- data/lib/install/config/rspack/rspack.config.js +6 -0
- data/lib/install/config/rspack/rspack.config.ts +7 -0
- data/lib/install/config/shakapacker.yml +75 -12
- data/lib/install/config/webpack/webpack.config.ts +7 -0
- data/lib/install/package.json +38 -0
- data/lib/install/template.rb +207 -45
- data/lib/shakapacker/build_config_loader.rb +147 -0
- data/lib/shakapacker/bundler_switcher.rb +415 -0
- data/lib/shakapacker/compiler.rb +87 -0
- data/lib/shakapacker/configuration.rb +475 -6
- data/lib/shakapacker/dev_server.rb +88 -1
- data/lib/shakapacker/dev_server_runner.rb +240 -6
- data/lib/shakapacker/doctor.rb +1191 -0
- data/lib/shakapacker/env.rb +19 -3
- data/lib/shakapacker/helper.rb +411 -14
- data/lib/shakapacker/install/env.rb +33 -0
- data/lib/shakapacker/instance.rb +93 -4
- data/lib/shakapacker/manifest.rb +167 -30
- data/lib/shakapacker/railtie.rb +4 -0
- data/lib/shakapacker/rspack_runner.rb +19 -0
- data/lib/shakapacker/runner.rb +668 -9
- data/lib/shakapacker/swc_migrator.rb +384 -0
- data/lib/shakapacker/utils/manager.rb +2 -0
- data/lib/shakapacker/utils/version_syntax_converter.rb +1 -1
- data/lib/shakapacker/version.rb +1 -1
- data/lib/shakapacker/version_checker.rb +1 -1
- data/lib/shakapacker/webpack_runner.rb +4 -42
- data/lib/shakapacker.rb +159 -1
- data/lib/tasks/shakapacker/binstubs.rake +4 -2
- data/lib/tasks/shakapacker/check_binstubs.rake +2 -2
- data/lib/tasks/shakapacker/doctor.rake +48 -0
- data/lib/tasks/shakapacker/export_bundler_config.rake +68 -0
- data/lib/tasks/shakapacker/install.rake +16 -4
- data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
- data/lib/tasks/shakapacker/switch_bundler.rake +72 -0
- data/lib/tasks/shakapacker.rake +2 -0
- data/package/.npmignore +4 -0
- data/package/babel/preset.ts +59 -0
- data/package/config.ts +189 -0
- data/package/configExporter/buildValidator.ts +906 -0
- data/package/configExporter/cli.ts +1748 -0
- data/package/configExporter/configDocs.ts +102 -0
- data/package/configExporter/configFile.ts +663 -0
- data/package/configExporter/fileWriter.ts +112 -0
- data/package/configExporter/index.ts +15 -0
- data/package/configExporter/types.ts +159 -0
- data/package/configExporter/yamlSerializer.ts +391 -0
- data/package/dev_server.ts +27 -0
- data/package/env.ts +92 -0
- data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +36 -0
- data/package/environments/base.ts +147 -0
- data/package/environments/development.ts +88 -0
- data/package/environments/production.ts +82 -0
- data/package/environments/test.ts +55 -0
- data/package/environments/types.ts +98 -0
- data/package/esbuild/index.ts +40 -0
- data/package/index.d.ts +68 -93
- data/package/index.d.ts.template +72 -0
- data/package/index.ts +104 -0
- data/package/loaders.d.ts +28 -0
- data/package/optimization/rspack.ts +36 -0
- data/package/optimization/webpack.ts +55 -0
- data/package/plugins/envFilter.ts +82 -0
- data/package/plugins/rspack.ts +119 -0
- data/package/plugins/webpack.ts +82 -0
- data/package/rspack/index.ts +91 -0
- data/package/rules/{babel.js → babel.ts} +2 -2
- data/package/rules/{coffee.js → coffee.ts} +1 -1
- data/package/rules/css.ts +3 -0
- data/package/rules/{erb.js → erb.ts} +1 -1
- data/package/rules/esbuild.ts +10 -0
- data/package/rules/file.ts +41 -0
- data/package/rules/{jscommon.js → jscommon.ts} +5 -4
- data/package/rules/{less.js → less.ts} +4 -4
- data/package/rules/raw.ts +28 -0
- data/package/rules/rspack.ts +174 -0
- data/package/rules/sass.ts +21 -0
- data/package/rules/{stylus.js → stylus.ts} +4 -8
- data/package/rules/swc.ts +10 -0
- data/package/rules/{index.js → webpack.ts} +1 -2
- data/package/swc/index.ts +54 -0
- data/package/types/README.md +90 -0
- data/package/types/index.ts +69 -0
- data/package/types.ts +105 -0
- data/package/utils/bundlerUtils.ts +232 -0
- data/package/utils/configPath.ts +6 -0
- data/package/utils/debug.ts +45 -0
- data/package/utils/defaultConfigPath.ts +7 -0
- data/package/utils/ensureManifestExists.ts +17 -0
- data/package/utils/errorCodes.ts +249 -0
- data/package/utils/errorHelpers.ts +152 -0
- data/package/utils/getStyleRule.ts +75 -0
- data/package/utils/helpers.ts +99 -0
- data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
- data/package/utils/pathValidation.ts +207 -0
- data/package/utils/requireOrError.ts +24 -0
- data/package/utils/snakeToCamelCase.ts +5 -0
- data/package/utils/typeGuards.ts +388 -0
- data/package/utils/validateDependencies.ts +61 -0
- data/package/webpack-types.d.ts +33 -0
- data/package/webpackDevServerConfig.ts +130 -0
- data/package.json +157 -18
- data/scripts/remove-use-strict.js +44 -0
- data/scripts/type-check-no-emit.js +27 -0
- data/shakapacker.gemspec +4 -2
- data/sig/shakapacker/commands.rbs +35 -0
- data/sig/shakapacker/compiler.rbs +65 -0
- data/sig/shakapacker/compiler_strategy.rbs +41 -0
- data/sig/shakapacker/configuration.rbs +140 -0
- data/sig/shakapacker/dev_server.rbs +56 -0
- data/sig/shakapacker/env.rbs +25 -0
- data/sig/shakapacker/helper.rbs +98 -0
- data/sig/shakapacker/instance.rbs +46 -0
- data/sig/shakapacker/manifest.rbs +69 -0
- data/sig/shakapacker/version.rbs +4 -0
- data/sig/shakapacker.rbs +66 -0
- data/test/configExporter/buildValidator.test.js +1295 -0
- data/test/configExporter/configFile.test.js +393 -0
- data/test/configExporter/integration.test.js +262 -0
- data/test/helpers.js +1 -1
- data/test/package/bundlerUtils.rspack.test.js +145 -0
- data/test/package/bundlerUtils.test.js +97 -0
- data/test/package/config.test.js +14 -0
- data/test/package/configExporter/cli.test.js +440 -0
- data/test/package/configExporter/types.test.js +163 -0
- data/test/package/configExporter.test.js +491 -0
- data/test/package/env.test.js +42 -7
- data/test/package/environments/base.test.js +14 -4
- data/test/package/helpers.test.js +2 -2
- data/test/package/plugins/envFiltering.test.js +453 -0
- data/test/package/plugins/webpackSubresourceIntegrity.test.js +89 -0
- data/test/package/rspack/index.test.js +293 -0
- data/test/package/rspack/optimization.test.js +86 -0
- data/test/package/rspack/plugins.test.js +185 -0
- data/test/package/rspack/rules.test.js +229 -0
- data/test/package/rules/babel.test.js +65 -38
- data/test/package/rules/esbuild.test.js +13 -4
- data/test/package/rules/file.test.js +7 -1
- data/test/package/rules/raw.test.js +40 -7
- data/test/package/rules/sass-version-parsing.test.js +71 -0
- data/test/package/rules/sass.test.js +11 -6
- data/test/package/rules/sass1.test.js +8 -5
- data/test/package/rules/sass16.test.js +24 -0
- data/test/package/rules/swc.test.js +50 -39
- data/test/package/rules/webpack.test.js +35 -0
- data/test/package/staging.test.js +4 -3
- data/test/package/transpiler-defaults.test.js +169 -0
- data/test/package/utils/ensureManifestExists.test.js +51 -0
- data/test/package/yamlSerializer.test.js +204 -0
- data/test/peer-dependencies.sh +85 -0
- data/test/resolver.js +34 -3
- data/test/scripts/remove-use-strict.test.js +125 -0
- data/test/typescript/build.test.js +118 -0
- data/test/typescript/environments.test.js +107 -0
- data/test/typescript/pathValidation.test.js +186 -0
- data/test/typescript/requireOrError.test.js +49 -0
- data/test/typescript/securityValidation.test.js +182 -0
- data/tools/README.md +134 -0
- data/tools/css-modules-v9-codemod.js +179 -0
- data/tsconfig.eslint.json +9 -0
- data/tsconfig.json +38 -0
- data/yarn.lock +3202 -1097
- metadata +212 -44
- data/.eslintignore +0 -4
- data/.eslintrc.js +0 -36
- data/Gemfile.lock +0 -251
- data/package/babel/preset.js +0 -48
- data/package/config.js +0 -56
- data/package/dev_server.js +0 -23
- data/package/env.js +0 -48
- data/package/environments/base.js +0 -171
- data/package/environments/development.js +0 -13
- data/package/environments/production.js +0 -88
- data/package/environments/test.js +0 -3
- data/package/esbuild/index.js +0 -40
- data/package/index.js +0 -40
- data/package/rules/css.js +0 -3
- data/package/rules/esbuild.js +0 -10
- data/package/rules/file.js +0 -29
- data/package/rules/raw.js +0 -5
- data/package/rules/sass.js +0 -18
- data/package/rules/swc.js +0 -10
- data/package/swc/index.js +0 -50
- data/package/utils/configPath.js +0 -4
- data/package/utils/defaultConfigPath.js +0 -2
- data/package/utils/getStyleRule.js +0 -40
- data/package/utils/helpers.js +0 -62
- data/package/utils/snakeToCamelCase.js +0 -5
- data/package/webpackDevServerConfig.js +0 -71
- data/test/package/rules/index.test.js +0 -16
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Shakapacker Project Guidelines
|
|
2
|
+
|
|
3
|
+
## Critical Requirements
|
|
4
|
+
|
|
5
|
+
- **ALWAYS end all files with a trailing newline character.** This is required by the project's linting rules.
|
|
6
|
+
- **ALWAYS use `bundle exec` prefix when running Ruby commands** (rubocop, rspec, rake, etc.)
|
|
7
|
+
- **ALWAYS run `bundle exec rubocop` before committing Ruby changes**
|
|
8
|
+
- **ALWAYS run `yarn lint` before committing JavaScript changes**
|
|
9
|
+
|
|
10
|
+
## Testing
|
|
11
|
+
|
|
12
|
+
- Run corresponding RSpec tests when changing source files
|
|
13
|
+
- For example, when changing `lib/shakapacker/foo.rb`, run `spec/shakapacker/foo_spec.rb`
|
|
14
|
+
- Run the full test suite with `bundle exec rspec` before pushing
|
|
15
|
+
- **Use explicit RSpec spy assertions** - prefer `have_received`/`not_to have_received` over indirect counter patterns
|
|
16
|
+
- Good: `expect(Open3).to have_received(:capture3).with(anything, hook_command, anything)`
|
|
17
|
+
- Good: `expect(Open3).not_to have_received(:capture3).with(anything, hook_command, anything)`
|
|
18
|
+
- Avoid: `call_count += 1` followed by `expect(call_count).to eq(1)`
|
|
19
|
+
|
|
20
|
+
## Code Style
|
|
21
|
+
|
|
22
|
+
- Follow existing code conventions in the file you're editing
|
|
23
|
+
- Use the project's existing patterns and utilities
|
|
24
|
+
- No unnecessary comments unless requested
|
|
25
|
+
- Keep changes focused and minimal - avoid extraneous diffs
|
|
26
|
+
|
|
27
|
+
## Git Workflow
|
|
28
|
+
|
|
29
|
+
- Create feature branches for all changes
|
|
30
|
+
- Never push directly to main branch
|
|
31
|
+
- Create small, focused PRs that are easy to review
|
|
32
|
+
- Always create a PR immediately after pushing changes
|
|
33
|
+
|
|
34
|
+
## Changelog
|
|
35
|
+
|
|
36
|
+
- **Update CHANGELOG.md for user-visible changes only** (features, bug fixes, breaking changes, deprecations, performance improvements)
|
|
37
|
+
- **Do NOT add entries for**: linting, formatting, refactoring, tests, or documentation fixes
|
|
38
|
+
- **Format**: `[PR #123](https://github.com/shakacode/shakapacker/pull/123) by [username](https://github.com/username)` (Shakapacker uses `#` in PR links)
|
|
39
|
+
- **Use `/update-changelog` command** for guided changelog updates with automatic formatting
|
|
40
|
+
- **Version management**: Run `bundle exec rake update_changelog` after releases to update version headers
|
|
41
|
+
- **Examples**: Run `grep -A 3 "^### " CHANGELOG.md | head -30` to see real formatting examples
|
|
42
|
+
|
|
43
|
+
## Open Source Maintainability
|
|
44
|
+
|
|
45
|
+
- **Prefer removing complexity over adding configuration.** If a default causes problems, consider removing the default rather than adding an option to disable it.
|
|
46
|
+
- **Every config option is maintenance surface.** Prefer convention over configuration. Don't add options for <10% of users — let them customize via existing extension points (e.g., custom webpack config).
|
|
47
|
+
- **"No is temporary, yes is forever."** Adding a feature creates a permanent maintenance obligation. Reject features that solve one user's niche problem but add complexity for everyone.
|
|
48
|
+
- **Security-safe defaults over convenient defaults.** Don't ship permissive defaults (e.g., `Access-Control-Allow-Origin: *`) just for convenience — make users opt in to less-secure configurations.
|
|
49
|
+
- **Don't refactor adjacent code in feature PRs.** Keep PRs focused. If you spot something to clean up, do it in a separate PR.
|
|
50
|
+
|
|
51
|
+
## Shakapacker-Specific
|
|
52
|
+
|
|
53
|
+
- This gem supports both webpack and rspack configurations
|
|
54
|
+
- Test changes with both bundlers when modifying core functionality
|
|
55
|
+
- Be aware of the dual package.json/Gemfile dependency management
|
|
56
|
+
|
|
57
|
+
## Conductor Environment
|
|
58
|
+
|
|
59
|
+
- **Version manager support**: The setup script detects mise, asdf, or direct PATH tools (rbenv/nvm/nodenv)
|
|
60
|
+
- **bin/conductor-exec**: Use this wrapper for commands when tool versions aren't detected correctly in Conductor's non-interactive shell
|
|
61
|
+
- Example: `bin/conductor-exec bundle exec rubocop`
|
|
62
|
+
- The wrapper uses `mise exec` if mise is available, otherwise falls back to direct execution
|
|
63
|
+
- **conductor.json scripts** already use this wrapper, so you typically don't need to use it manually
|
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,46 +11,218 @@ 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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
|
30
|
+
- Update RBS type signatures in `sig/` directory if you modify public APIs.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Git Hooks (Optional)
|
|
35
|
+
|
|
36
|
+
This project includes configuration for git hooks via `husky` and `lint-staged`, but they are **opt-in for contributors**.
|
|
37
|
+
|
|
38
|
+
**Why are hooks optional?** As a library project, we don't enforce git hooks because:
|
|
39
|
+
|
|
40
|
+
- Different contributors may have different workflows
|
|
41
|
+
- Forcing hooks can interfere with contributor tooling
|
|
42
|
+
- CI/CD handles the final validation
|
|
43
|
+
|
|
44
|
+
To enable pre-commit hooks locally:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx husky install
|
|
48
|
+
npx husky add .husky/pre-commit "npx lint-staged"
|
|
49
|
+
```
|
|
27
50
|
|
|
28
51
|
---
|
|
52
|
+
|
|
53
|
+
## RBS Type Signatures
|
|
54
|
+
|
|
55
|
+
Shakapacker includes RBS type signatures for all public APIs in the `sig/` directory. These signatures provide static type checking and improved IDE support.
|
|
56
|
+
|
|
57
|
+
### When to Update RBS Files
|
|
58
|
+
|
|
59
|
+
Update RBS signatures when you:
|
|
60
|
+
|
|
61
|
+
- Add new public methods or classes
|
|
62
|
+
- Change method signatures (parameters, return types)
|
|
63
|
+
- Modify public APIs
|
|
64
|
+
- Add or remove public attributes
|
|
65
|
+
|
|
66
|
+
### RBS File Structure
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
sig/
|
|
70
|
+
├── shakapacker.rbs # Main Shakapacker module
|
|
71
|
+
└── shakapacker/
|
|
72
|
+
├── configuration.rbs # Configuration class
|
|
73
|
+
├── helper.rbs # View helper module
|
|
74
|
+
├── manifest.rbs # Manifest class
|
|
75
|
+
├── compiler.rbs # Compiler class
|
|
76
|
+
└── ... # Other components
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Validating RBS Signatures
|
|
80
|
+
|
|
81
|
+
To validate your RBS signatures:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Install RBS if not already installed
|
|
85
|
+
gem install rbs
|
|
86
|
+
|
|
87
|
+
# Validate all signatures
|
|
88
|
+
rbs validate
|
|
89
|
+
|
|
90
|
+
# Check a specific file
|
|
91
|
+
rbs validate sig/shakapacker/configuration.rbs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### RBS Best Practices
|
|
95
|
+
|
|
96
|
+
1. **Use specific types** instead of `untyped` when possible
|
|
97
|
+
2. **Document optional parameters** with `?` prefix
|
|
98
|
+
3. **Use union types** for methods that can return multiple types (e.g., `String | nil`)
|
|
99
|
+
4. **Keep signatures in sync** with implementation changes
|
|
100
|
+
5. **Test with type checkers** like [Steep](https://github.com/soutaro/steep) when possible
|
|
101
|
+
6. **Use `void` vs `nil` appropriately**:
|
|
102
|
+
- Use `void` when the return value is expected to be discarded (e.g., `initialize`)
|
|
103
|
+
- Use `nil` when a method explicitly returns nil as a meaningful value
|
|
104
|
+
7. **Module singleton methods**: For modules using `extend self`, use `module ModuleName : _Singleton` to indicate all methods are module-level singleton methods
|
|
105
|
+
|
|
106
|
+
### Example RBS Signature
|
|
107
|
+
|
|
108
|
+
```rbs
|
|
109
|
+
# Good: Specific types with documentation
|
|
110
|
+
class Shakapacker::Configuration
|
|
111
|
+
def initialize: (
|
|
112
|
+
root_path: Pathname,
|
|
113
|
+
config_path: Pathname,
|
|
114
|
+
env: ActiveSupport::StringInquirer,
|
|
115
|
+
?bundler_override: String?
|
|
116
|
+
) -> void
|
|
117
|
+
|
|
118
|
+
def source_path: () -> Pathname
|
|
119
|
+
def webpack?: () -> bool
|
|
120
|
+
def assets_bundler: () -> String
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Module with singleton methods (using extend self)
|
|
124
|
+
module Shakapacker : _Singleton
|
|
125
|
+
def self.config: () -> Configuration
|
|
126
|
+
def self.compile: () -> bool
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Avoid: Overly generic types
|
|
130
|
+
class Shakapacker::Configuration
|
|
131
|
+
def initialize: (**untyped) -> void
|
|
132
|
+
def source_path: () -> untyped
|
|
133
|
+
end
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Linting and Code Quality
|
|
139
|
+
|
|
140
|
+
### Running Linters
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Full linting with type checking (slower but thorough)
|
|
144
|
+
yarn lint
|
|
145
|
+
|
|
146
|
+
# Fast linting without type checking (for quick feedback)
|
|
147
|
+
yarn lint:fast
|
|
148
|
+
|
|
149
|
+
# With caching for better performance
|
|
150
|
+
yarn lint --cache
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**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.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
29
157
|
## Setting Up a Development Environment
|
|
30
158
|
|
|
31
|
-
1. Install [Yarn](https://classic.yarnpkg.com/)
|
|
159
|
+
1. Install [Yarn](https://classic.yarnpkg.com/) & [yalc](https://github.com/wclr/yalc)
|
|
32
160
|
2. To test your changes on a Rails test project do the following steps:
|
|
33
161
|
- For Ruby gem, update `Gemfile` and point the `shakapacker` to the locally developing Shakapacker project:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
162
|
+
```ruby
|
|
163
|
+
gem 'shakapacker', path: "relative_or_absolute_path_to_local_shakapacker"
|
|
164
|
+
```
|
|
37
165
|
- For npm package, use `yalc` with following steps:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# In Shakapacker root directory
|
|
169
|
+
yalc publish
|
|
170
|
+
# In Rails app for testing
|
|
171
|
+
yalc link shakapacker
|
|
172
|
+
|
|
173
|
+
# After every change in shakapacker, run the following in Shakapacker directory
|
|
174
|
+
yalc push # or yalc publish --push
|
|
175
|
+
```
|
|
176
|
+
|
|
47
177
|
3. Run the following commands to set up the development environment.
|
|
48
178
|
```
|
|
49
179
|
bundle install
|
|
50
180
|
yarn install
|
|
181
|
+
yarn prepare:husky # Set up pre-commit hooks for linting
|
|
51
182
|
```
|
|
52
183
|
|
|
184
|
+
## Understanding Optional Peer Dependencies
|
|
185
|
+
|
|
186
|
+
Shakapacker uses optional peer dependencies (via `peerDependenciesMeta`) for maximum flexibility:
|
|
187
|
+
|
|
188
|
+
- **All peer dependencies are optional** - Users only install what they need
|
|
189
|
+
- **No installation warnings** - Package managers won't warn about missing optional dependencies
|
|
190
|
+
- **Version constraints still apply** - When a package is installed, version compatibility is enforced
|
|
191
|
+
|
|
192
|
+
### TypeScript Declaration Files and Optional Dependencies
|
|
193
|
+
|
|
194
|
+
When importing types from optional peer dependencies, we use `@ts-ignore` directives:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// @ts-ignore: webpack is an optional peer dependency (using type-only import)
|
|
198
|
+
import type { Configuration } from "webpack"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This ensures that typecheck downstream won't fail if lib checks are on regardless of if `webpack` is available.
|
|
202
|
+
|
|
203
|
+
### When modifying dependencies:
|
|
204
|
+
|
|
205
|
+
1. Add new peer dependencies to both `peerDependencies` and `peerDependenciesMeta` (marking as optional)
|
|
206
|
+
2. Keep version ranges synchronized between `devDependencies` and `peerDependencies`
|
|
207
|
+
3. Test with multiple package managers: `npm`, `yarn`, and `pnpm`
|
|
208
|
+
4. If adding type-only imports from optional dependencies, use the `@ts-ignore` pattern shown above
|
|
209
|
+
|
|
210
|
+
### Testing peer dependency changes:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Test with npm (no warnings expected)
|
|
214
|
+
cd /tmp && mkdir test-npm && cd test-npm
|
|
215
|
+
npm init -y && npm install /path/to/shakapacker
|
|
216
|
+
|
|
217
|
+
# Test with yarn (no warnings expected)
|
|
218
|
+
cd /tmp && mkdir test-yarn && cd test-yarn
|
|
219
|
+
yarn init -y && yarn add /path/to/shakapacker
|
|
220
|
+
|
|
221
|
+
# Test with pnpm (no warnings expected)
|
|
222
|
+
cd /tmp && mkdir test-pnpm && cd test-pnpm
|
|
223
|
+
pnpm init && pnpm add /path/to/shakapacker
|
|
224
|
+
```
|
|
225
|
+
|
|
53
226
|
## Making sure your changes pass all tests
|
|
54
227
|
|
|
55
228
|
There are several specs, covering different aspects of Shakapacker gem. You may run them locally or rely on GitHub CI actions configured to test the gem functionality if different Ruby, Rails, and Node environment.
|
|
@@ -101,6 +274,7 @@ bundle exec rake run_spec:gem
|
|
|
101
274
|
```
|
|
102
275
|
|
|
103
276
|
#### 4.4 Run only Shakapacker gem specs for backward compatibility
|
|
277
|
+
|
|
104
278
|
These specs are to check Shakapacker v7 backward compatibility with v6.x
|
|
105
279
|
|
|
106
280
|
```
|
|
@@ -108,6 +282,7 @@ bundle exec rake run_spec:gem_bc
|
|
|
108
282
|
```
|
|
109
283
|
|
|
110
284
|
#### 4.5 Run dummy app test
|
|
285
|
+
|
|
111
286
|
For this, you need `yalc` to be installed on your local machine
|
|
112
287
|
|
|
113
288
|
```
|
|
@@ -115,6 +290,7 @@ bundle exec rake run_spec:dummy
|
|
|
115
290
|
```
|
|
116
291
|
|
|
117
292
|
#### 4.6 Testing the installer
|
|
293
|
+
|
|
118
294
|
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:
|
|
119
295
|
|
|
120
296
|
1. Update the `Gemfile` so that gem `shakapacker` has a line like this, pointing to your developing Shakapacker:
|
|
@@ -124,4 +300,75 @@ To ensure that your installer works as expected, either you can run `bundle exec
|
|
|
124
300
|
2. Run `bundle install` to install the updated gem.
|
|
125
301
|
3. Run `bundle exec rails shakapacker:install` to confirm that you got the right changes.
|
|
126
302
|
|
|
127
|
-
|
|
303
|
+
**Note:** Ensure that you use bundle exec otherwise the installed shakapacker gem will run and not the one you are working on.
|
|
304
|
+
|
|
305
|
+
## CI Workflows
|
|
306
|
+
|
|
307
|
+
Shakapacker uses GitHub Actions for continuous integration. The CI workflows use **Yarn** as the package manager for consistency and reliability.
|
|
308
|
+
|
|
309
|
+
### Package Manager Choice
|
|
310
|
+
|
|
311
|
+
The project uses Yarn in CI workflows for the following reasons:
|
|
312
|
+
|
|
313
|
+
- Deterministic dependency resolution with `yarn.lock`
|
|
314
|
+
- Faster installation with offline mirror support
|
|
315
|
+
- Better workspace support for monorepo-style testing
|
|
316
|
+
- Consistent behavior across different Node.js versions
|
|
317
|
+
|
|
318
|
+
### Key CI Workflow Files
|
|
319
|
+
|
|
320
|
+
- `.github/workflows/test-bundlers.yml` - Tests webpack, rspack, and bundler switching
|
|
321
|
+
- `.github/workflows/ruby.yml` - Ruby test suite across Ruby/Rails versions
|
|
322
|
+
- `.github/workflows/node.yml` - Node.js test suite across Node versions
|
|
323
|
+
- `.github/workflows/generator.yml` - Generator installation tests
|
|
324
|
+
- `.github/workflows/dummy.yml` - Dummy app integration tests
|
|
325
|
+
- `.github/workflows/eslint-validation.yml` - ESLint configuration validation
|
|
326
|
+
|
|
327
|
+
All workflows use:
|
|
328
|
+
|
|
329
|
+
```yaml
|
|
330
|
+
- uses: actions/setup-node@v4
|
|
331
|
+
with:
|
|
332
|
+
cache: "yarn"
|
|
333
|
+
cache-dependency-path: spec/dummy/yarn.lock
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
And install dependencies with:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
yarn install
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### CI Optimization: Path Filtering
|
|
343
|
+
|
|
344
|
+
To reduce CI costs and execution time, workflows use **path filtering** to run only when relevant files change:
|
|
345
|
+
|
|
346
|
+
- **Ruby workflow** - Only runs when Ruby files, gemspecs, Gemfile, or RuboCop config changes
|
|
347
|
+
- **Node workflow** - Only runs when JS/TS files, package.json, or Node config changes
|
|
348
|
+
- **Generator specs** - Only runs when generator-related files change
|
|
349
|
+
- **Dummy specs** - Only runs when dummy app or lib files change
|
|
350
|
+
- **Test bundlers** - Only runs when code affecting bundler integration changes
|
|
351
|
+
|
|
352
|
+
This means documentation-only PRs (e.g., only changing `README.md`) will skip all test workflows entirely.
|
|
353
|
+
|
|
354
|
+
**Important:** The full test suite always runs on pushes to the `main` branch to ensure the main branch is always thoroughly tested.
|
|
355
|
+
|
|
356
|
+
### Manual Workflow Execution
|
|
357
|
+
|
|
358
|
+
All workflows can be triggered manually via the GitHub Actions UI using the "Run workflow" button. This is useful for:
|
|
359
|
+
|
|
360
|
+
- Re-running tests after a temporary CI failure
|
|
361
|
+
- Testing workflows on specific branches without creating a PR
|
|
362
|
+
- Running full test suites on PRs that would normally skip certain workflows
|
|
363
|
+
|
|
364
|
+
### Conditional Linting
|
|
365
|
+
|
|
366
|
+
The Node workflow includes conditional execution of actionlint (GitHub Actions linter):
|
|
367
|
+
|
|
368
|
+
- Only downloads and runs when `.github/workflows/*` files change
|
|
369
|
+
- Saves time by skipping on most PRs
|
|
370
|
+
- Includes caching for faster execution when needed
|
|
371
|
+
|
|
372
|
+
### Testing with Other Package Managers
|
|
373
|
+
|
|
374
|
+
While CI uses Yarn, the gem supports all major package managers (npm, yarn, pnpm, bun). Generator specs test against all package managers to ensure compatibility.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ESLint Technical Debt Documentation
|
|
2
|
+
|
|
3
|
+
This document tracks the ESLint errors currently suppressed in the codebase and outlines the plan to address them.
|
|
4
|
+
|
|
5
|
+
## Current Approach
|
|
6
|
+
|
|
7
|
+
**As of 2025-10-14**: All TypeScript files in `package/` directory are temporarily excluded from linting via the ignore pattern `package/**/*.ts` in `eslint.config.js`. This allows the project to adopt ESLint configuration without requiring immediate fixes to all existing issues.
|
|
8
|
+
|
|
9
|
+
**Latest Update**: Auto-fixed 28 style violations in `package/configExporter/cli.ts` including unnecessary type assertions, string concatenation to template literals, and object destructuring (reduced from 77 to 49 errors).
|
|
10
|
+
|
|
11
|
+
## Current Linting Status
|
|
12
|
+
|
|
13
|
+
**Files currently linted** (`test/**/*.js`, `scripts/*.js`):
|
|
14
|
+
|
|
15
|
+
- ✅ **0 errors** (CI passing)
|
|
16
|
+
- ⚠️ **3 warnings** (acceptable, won't block CI)
|
|
17
|
+
- 1x unused eslint-disable directive in `scripts/remove-use-strict.js`
|
|
18
|
+
- 2x jest/no-disabled-tests in test files (expected for conditional test skipping)
|
|
19
|
+
|
|
20
|
+
**TypeScript files** (currently ignored via `package/**/*.ts`):
|
|
21
|
+
|
|
22
|
+
- **Estimated suppressed errors: ~163** (from sample analysis)
|
|
23
|
+
- TypeScript type-safety issues: ~114 (70%)
|
|
24
|
+
- Style/convention issues: ~49 (30%)
|
|
25
|
+
|
|
26
|
+
**Target**: Reduce suppressed errors by 50% within Q1 2025
|
|
27
|
+
**Last Updated**: 2025-10-18
|
|
28
|
+
|
|
29
|
+
## Priority Matrix
|
|
30
|
+
|
|
31
|
+
| Category | Impact | Effort | Priority | Count |
|
|
32
|
+
| ------------------------------------ | ------ | ------ | -------- | ----- |
|
|
33
|
+
| `@typescript-eslint/no-explicit-any` | High | High | P1 | 22 |
|
|
34
|
+
| `@typescript-eslint/no-unsafe-*` | High | High | P1 | 85 |
|
|
35
|
+
| `config.ts` type safety | High | Medium | P1 | 7 |
|
|
36
|
+
| `no-param-reassign` | Medium | Low | P2 | 0 |
|
|
37
|
+
| `class-methods-use-this` | Low | Low | P3 | 0 |
|
|
38
|
+
| `no-nested-ternary` | Low | Low | P3 | 0 |
|
|
39
|
+
| `import/prefer-default-export` | Low | Medium | P3 | 9 |
|
|
40
|
+
| `global-require` | Medium | High | P2 | 3 |
|
|
41
|
+
| Other style issues | Low | Low | P3 | 31 |
|
|
42
|
+
|
|
43
|
+
## Categories of Suppressed Errors
|
|
44
|
+
|
|
45
|
+
### 1. TypeScript Type Safety (Requires Major Refactoring)
|
|
46
|
+
|
|
47
|
+
#### `@typescript-eslint/no-explicit-any` (22 instances)
|
|
48
|
+
|
|
49
|
+
**Files affected:** `configExporter/`, `config.ts`, `utils/`
|
|
50
|
+
**Why suppressed:** These require careful type definitions and potentially breaking API changes
|
|
51
|
+
**Fix strategy:** Create proper type definitions for configuration objects and YAML parsing
|
|
52
|
+
|
|
53
|
+
#### `@typescript-eslint/no-unsafe-*` (85 instances)
|
|
54
|
+
|
|
55
|
+
- `no-unsafe-assignment`: 47 instances
|
|
56
|
+
- `no-unsafe-member-access`: 20 instances
|
|
57
|
+
- `no-unsafe-call`: 8 instances
|
|
58
|
+
- `no-unsafe-return`: 8 instances
|
|
59
|
+
- `no-unsafe-argument`: 7 instances
|
|
60
|
+
**Why suppressed:** These stem from `any` types and dynamic property access
|
|
61
|
+
**Fix strategy:** Requires comprehensive type refactoring alongside `no-explicit-any` fixes
|
|
62
|
+
|
|
63
|
+
### 2. Module System (Potential Breaking Changes)
|
|
64
|
+
|
|
65
|
+
#### `global-require` (3 instances)
|
|
66
|
+
|
|
67
|
+
**Files affected:** `configExporter/cli.ts`
|
|
68
|
+
**Why suppressed:** Dynamic require calls are needed for conditional module loading
|
|
69
|
+
**Fix strategy:** Would require converting to ES modules with dynamic imports
|
|
70
|
+
|
|
71
|
+
#### `import/prefer-default-export` (9 instances)
|
|
72
|
+
|
|
73
|
+
**Files affected:** Multiple single-export modules
|
|
74
|
+
**Why suppressed:** Adding default exports alongside named exports could break consumers
|
|
75
|
+
**Fix strategy:** Can be fixed non-breaking by adding default exports that match named exports
|
|
76
|
+
|
|
77
|
+
### 3. Code Style (Can Be Fixed)
|
|
78
|
+
|
|
79
|
+
#### `class-methods-use-this` (0 instances)
|
|
80
|
+
|
|
81
|
+
✅ **FIXED** - All FileWriter methods that didn't use instance state have been converted to static methods
|
|
82
|
+
|
|
83
|
+
#### `no-nested-ternary` (0 instances)
|
|
84
|
+
|
|
85
|
+
✅ **FIXED** - All nested ternary expressions have been refactored to if-else statements for better readability
|
|
86
|
+
|
|
87
|
+
#### `no-param-reassign` (0 instances)
|
|
88
|
+
|
|
89
|
+
✅ **FIXED** - Refactored `applyDefaults` function to return new objects instead of mutating parameters
|
|
90
|
+
|
|
91
|
+
#### `no-underscore-dangle` (2 instances)
|
|
92
|
+
|
|
93
|
+
**Fix strategy:** Rename variables or add exceptions for Node internals
|
|
94
|
+
|
|
95
|
+
### 4. Control Flow
|
|
96
|
+
|
|
97
|
+
#### `no-await-in-loop` (1 instance)
|
|
98
|
+
|
|
99
|
+
**Fix strategy:** Use `Promise.all()` for parallel execution
|
|
100
|
+
|
|
101
|
+
#### `no-continue` (1 instance)
|
|
102
|
+
|
|
103
|
+
**Fix strategy:** Refactor loop logic
|
|
104
|
+
|
|
105
|
+
## Recommended Approach
|
|
106
|
+
|
|
107
|
+
### Phase 1: Non-Breaking Fixes
|
|
108
|
+
|
|
109
|
+
✅ Completed:
|
|
110
|
+
|
|
111
|
+
- Fixed `no-use-before-define` by reordering functions
|
|
112
|
+
- Fixed redundant type constituents with `string & {}` pattern
|
|
113
|
+
- Added proper type annotations for `requireOrError` calls
|
|
114
|
+
- Configured appropriate global rule disables (`no-console`, `no-restricted-syntax`)
|
|
115
|
+
- ✅ **Fixed `class-methods-use-this`** - Converted FileWriter methods to static methods
|
|
116
|
+
- ✅ **Fixed `no-nested-ternary`** - Refactored to if-else statements for better readability
|
|
117
|
+
- ✅ **Fixed `no-param-reassign`** - Refactored `applyDefaults` to return new objects instead of mutating parameters
|
|
118
|
+
- ✅ **Auto-fixed style violations in cli.ts** (2025-10-18):
|
|
119
|
+
- Removed unnecessary type assertions (`@typescript-eslint/no-unnecessary-type-assertion`)
|
|
120
|
+
- Used object destructuring (`prefer-destructuring`)
|
|
121
|
+
- Converted string concatenation to template literals (`prefer-template`)
|
|
122
|
+
- Removed unused eslint-disable directives
|
|
123
|
+
- Fixed `no-else-return` violations
|
|
124
|
+
|
|
125
|
+
🔧 Could still fix (low risk):
|
|
126
|
+
|
|
127
|
+
- `no-useless-escape` - Remove unnecessary escapes
|
|
128
|
+
- Unused variables - Remove or prefix with underscore
|
|
129
|
+
|
|
130
|
+
### Phase 2: Follow-up PRs (Non-Breaking)
|
|
131
|
+
|
|
132
|
+
- Systematic type safety improvements file by file
|
|
133
|
+
- Add explicit type definitions for configuration objects
|
|
134
|
+
- Replace `any` with `unknown` where possible
|
|
135
|
+
|
|
136
|
+
### Phase 3: Future Major Version (Breaking Changes)
|
|
137
|
+
|
|
138
|
+
- Convert `export =` to `export default`
|
|
139
|
+
- Convert `require()` to ES6 imports
|
|
140
|
+
- Full TypeScript strict mode compliance
|
|
141
|
+
- Provide codemod for automatic migration
|
|
142
|
+
|
|
143
|
+
## Configuration Strategy
|
|
144
|
+
|
|
145
|
+
The current approach uses file-specific overrides to suppress errors in affected files while maintaining strict checking elsewhere. This allows:
|
|
146
|
+
|
|
147
|
+
1. New code to follow strict standards
|
|
148
|
+
2. Gradual refactoring of existing code
|
|
149
|
+
3. Clear visibility of technical debt
|
|
150
|
+
|
|
151
|
+
## Issue Tracking
|
|
152
|
+
|
|
153
|
+
GitHub issues should be created for each category:
|
|
154
|
+
|
|
155
|
+
1. [ ] Issue: Type safety refactoring for configExporter module
|
|
156
|
+
2. [ ] Issue: Type safety for dynamic config loading
|
|
157
|
+
3. [ ] Issue: Convert class methods to static where appropriate
|
|
158
|
+
4. [ ] Issue: Module system modernization (ES6 modules)
|
|
159
|
+
5. [ ] Issue: Create codemod for breaking changes migration
|
|
160
|
+
|
|
161
|
+
## Notes
|
|
162
|
+
|
|
163
|
+
- All suppressed errors are documented in `eslint.config.js` with TODO comments
|
|
164
|
+
- The suppressions are scoped to specific files to prevent spreading technical debt
|
|
165
|
+
- New code should not add to these suppressions
|