shakapacker 9.0.0.beta.6 → 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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.fast.js +40 -0
  3. data/.eslintrc.js +48 -0
  4. data/.github/workflows/generator.yml +6 -0
  5. data/.gitignore +1 -4
  6. data/.npmignore +56 -0
  7. data/CHANGELOG.md +64 -1
  8. data/CONTRIBUTING.md +75 -21
  9. data/Gemfile.lock +1 -1
  10. data/README.md +4 -0
  11. data/TODO.md +15 -16
  12. data/docs/transpiler-migration.md +191 -0
  13. data/docs/typescript-migration.md +378 -0
  14. data/lib/install/template.rb +54 -7
  15. data/lib/shakapacker/version.rb +1 -1
  16. data/package/.npmignore +4 -0
  17. data/package/babel/preset.ts +56 -0
  18. data/package/config.ts +23 -10
  19. data/package/env.ts +15 -2
  20. data/package/environments/{development.js → development.ts} +30 -8
  21. data/package/environments/{production.js → production.ts} +18 -4
  22. data/package/environments/test.ts +53 -0
  23. data/package/environments/types.ts +90 -0
  24. data/package/esbuild/index.ts +42 -0
  25. data/package/optimization/rspack.ts +36 -0
  26. data/package/optimization/{webpack.js → webpack.ts} +12 -4
  27. data/package/plugins/{rspack.js → rspack.ts} +20 -5
  28. data/package/plugins/{webpack.js → webpack.ts} +2 -2
  29. data/package/rspack/{index.js → index.ts} +17 -10
  30. data/package/rules/{babel.js → babel.ts} +1 -1
  31. data/package/rules/{coffee.js → coffee.ts} +1 -1
  32. data/package/rules/{css.js → css.ts} +1 -1
  33. data/package/rules/{erb.js → erb.ts} +1 -1
  34. data/package/rules/{esbuild.js → esbuild.ts} +2 -2
  35. data/package/rules/{file.js → file.ts} +11 -6
  36. data/package/rules/{jscommon.js → jscommon.ts} +4 -4
  37. data/package/rules/{less.js → less.ts} +3 -3
  38. data/package/rules/raw.ts +25 -0
  39. data/package/rules/{rspack.js → rspack.ts} +21 -11
  40. data/package/rules/{sass.js → sass.ts} +1 -1
  41. data/package/rules/{stylus.js → stylus.ts} +3 -7
  42. data/package/rules/{swc.js → swc.ts} +2 -2
  43. data/package/rules/{webpack.js → webpack.ts} +1 -1
  44. data/package/swc/index.ts +54 -0
  45. data/package/types/README.md +87 -0
  46. data/package/types/index.ts +60 -0
  47. data/package/utils/errorCodes.ts +219 -0
  48. data/package/utils/errorHelpers.ts +68 -2
  49. data/package/utils/pathValidation.ts +139 -0
  50. data/package/utils/typeGuards.ts +161 -47
  51. data/package.json +26 -4
  52. data/scripts/remove-use-strict.js +45 -0
  53. data/scripts/type-check-no-emit.js +27 -0
  54. data/test/package/rules/raw.test.js +40 -7
  55. data/test/package/rules/webpack.test.js +21 -2
  56. data/test/package/transpiler-defaults.test.js +127 -0
  57. data/test/scripts/remove-use-strict.test.js +125 -0
  58. data/test/typescript/build.test.js +3 -2
  59. data/test/typescript/environments.test.js +107 -0
  60. data/test/typescript/pathValidation.test.js +142 -0
  61. data/test/typescript/securityValidation.test.js +182 -0
  62. data/tsconfig.eslint.json +16 -0
  63. data/tsconfig.json +9 -10
  64. data/yarn.lock +415 -6
  65. metadata +50 -28
  66. data/package/babel/preset.js +0 -48
  67. data/package/environments/base.js +0 -103
  68. data/package/environments/test.js +0 -19
  69. data/package/esbuild/index.js +0 -40
  70. data/package/optimization/rspack.js +0 -29
  71. data/package/rules/raw.js +0 -15
  72. data/package/swc/index.js +0 -50
@@ -0,0 +1,191 @@
1
+ # JavaScript Transpiler Configuration
2
+
3
+ ## Default Transpilers
4
+
5
+ Shakapacker uses different default JavaScript transpilers based on the bundler:
6
+
7
+ - **Webpack**: `babel` (default) - Maintains backward compatibility
8
+ - **Rspack**: `swc` (default) - Modern, faster transpiler for new bundler
9
+
10
+ ## Available Transpilers
11
+
12
+ - `babel` - Traditional JavaScript transpiler with wide ecosystem support
13
+ - `swc` - Rust-based transpiler, 20-70x faster than Babel
14
+ - `esbuild` - Go-based transpiler, extremely fast
15
+ - `none` - No transpilation (use native JavaScript)
16
+
17
+ ## Configuration
18
+
19
+ Set the transpiler in your `config/shakapacker.yml`:
20
+
21
+ ```yaml
22
+ default: &default
23
+ # For webpack users (babel is default, no change needed)
24
+ javascript_transpiler: babel
25
+
26
+ # To opt-in to SWC for better performance
27
+ javascript_transpiler: swc
28
+
29
+ # For rspack users (swc is default, no change needed)
30
+ assets_bundler: rspack
31
+ javascript_transpiler: swc
32
+ ```
33
+
34
+ ## Migration Guide
35
+
36
+ ### Migrating from Babel to SWC
37
+
38
+ SWC offers significant performance improvements while maintaining high compatibility with Babel.
39
+
40
+ #### 1. Install SWC dependencies
41
+
42
+ ```bash
43
+ yarn add --dev @swc/core swc-loader
44
+ ```
45
+
46
+ #### 2. Update your configuration
47
+
48
+ ```yaml
49
+ # config/shakapacker.yml
50
+ default: &default
51
+ javascript_transpiler: swc
52
+ ```
53
+
54
+ #### 3. Create SWC configuration (optional)
55
+
56
+ If you need custom transpilation settings, create `.swcrc`:
57
+
58
+ ```json
59
+ {
60
+ "$schema": "https://json.schemastore.org/swcrc",
61
+ "jsc": {
62
+ "parser": {
63
+ "syntax": "ecmascript",
64
+ "jsx": true,
65
+ "dynamicImport": true
66
+ },
67
+ "transform": {
68
+ "react": {
69
+ "runtime": "automatic"
70
+ }
71
+ },
72
+ "target": "es2015"
73
+ },
74
+ "module": {
75
+ "type": "es6"
76
+ }
77
+ }
78
+ ```
79
+
80
+ #### 4. Update React configuration (if using React)
81
+
82
+ For React projects, ensure you have the correct refresh plugin:
83
+
84
+ ```bash
85
+ # For webpack
86
+ yarn add --dev @pmmmwh/react-refresh-webpack-plugin
87
+
88
+ # For rspack
89
+ yarn add --dev @rspack/plugin-react-refresh
90
+ ```
91
+
92
+ ### Performance Comparison
93
+
94
+ Typical build time improvements when migrating from Babel to SWC:
95
+
96
+ | Project Size | Babel | SWC | Improvement |
97
+ |-------------|-------|-----|-------------|
98
+ | Small (<100 files) | 5s | 1s | 5x faster |
99
+ | Medium (100-500 files) | 20s | 3s | 6.7x faster |
100
+ | Large (500+ files) | 60s | 8s | 7.5x faster |
101
+
102
+ ### Compatibility Notes
103
+
104
+ #### Babel Features Not Yet in SWC
105
+
106
+ - Some experimental/stage-0 proposals
107
+ - Custom Babel plugins (need SWC equivalents)
108
+ - Babel macros
109
+
110
+ #### Migration Checklist
111
+
112
+ - [ ] Back up your current configuration
113
+ - [ ] Install SWC dependencies
114
+ - [ ] Update `shakapacker.yml`
115
+ - [ ] Test your build locally
116
+ - [ ] Run your test suite
117
+ - [ ] Check browser compatibility
118
+ - [ ] Deploy to staging environment
119
+ - [ ] Monitor for any runtime issues
120
+
121
+ ### Rollback Plan
122
+
123
+ If you encounter issues, rolling back is simple:
124
+
125
+ ```yaml
126
+ # config/shakapacker.yml
127
+ default: &default
128
+ javascript_transpiler: babel # Revert to babel
129
+ ```
130
+
131
+ Then rebuild your application:
132
+
133
+ ```bash
134
+ bin/shakapacker clobber
135
+ bin/shakapacker compile
136
+ ```
137
+
138
+ ## Environment Variables
139
+
140
+ You can also control the transpiler via environment variables:
141
+
142
+ ```bash
143
+ # Override config file setting
144
+ SHAKAPACKER_JAVASCRIPT_TRANSPILER=swc bin/shakapacker compile
145
+
146
+ # For debugging
147
+ SHAKAPACKER_DEBUG_CACHE=true bin/shakapacker compile
148
+ ```
149
+
150
+ ## Troubleshooting
151
+
152
+ ### Issue: Build fails after switching to SWC
153
+
154
+ **Solution**: Ensure all SWC dependencies are installed:
155
+
156
+ ```bash
157
+ yarn add --dev @swc/core swc-loader
158
+ ```
159
+
160
+ ### Issue: React Fast Refresh not working
161
+
162
+ **Solution**: Install the correct refresh plugin for your bundler:
163
+
164
+ ```bash
165
+ # Webpack
166
+ yarn add --dev @pmmmwh/react-refresh-webpack-plugin
167
+
168
+ # Rspack
169
+ yarn add --dev @rspack/plugin-react-refresh
170
+ ```
171
+
172
+ ### Issue: Decorators not working
173
+
174
+ **Solution**: Enable decorator support in `.swcrc`:
175
+
176
+ ```json
177
+ {
178
+ "jsc": {
179
+ "parser": {
180
+ "decorators": true,
181
+ "decoratorsBeforeExport": true
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Further Reading
188
+
189
+ - [SWC Documentation](https://swc.rs/docs/getting-started)
190
+ - [Babel to SWC Migration Guide](https://swc.rs/docs/migrating-from-babel)
191
+ - [Rspack Configuration](https://www.rspack.dev/config/index)
@@ -0,0 +1,378 @@
1
+ # TypeScript Migration Guide for Shakapacker
2
+
3
+ This guide helps you adopt TypeScript types in your Shakapacker configuration files for better type safety and IDE support.
4
+
5
+ ## Table of Contents
6
+ - [Benefits](#benefits)
7
+ - [Quick Start](#quick-start)
8
+ - [Migration Steps](#migration-steps)
9
+ - [Common Patterns](#common-patterns)
10
+ - [Troubleshooting](#troubleshooting)
11
+
12
+ ## Benefits
13
+
14
+ Using TypeScript with Shakapacker provides:
15
+ - **Type Safety**: Catch configuration errors at compile time
16
+ - **IDE Support**: Get autocompletion and inline documentation
17
+ - **Better Refactoring**: Safely rename and restructure configurations
18
+ - **Self-documenting**: Types serve as inline documentation
19
+
20
+ ## Quick Start
21
+
22
+ ### 1. Install TypeScript Dependencies
23
+
24
+ ```bash
25
+ yarn add --dev typescript @types/node @types/webpack
26
+ # or
27
+ npm install --save-dev typescript @types/node @types/webpack
28
+ ```
29
+
30
+ ### 2. Create a tsconfig.json
31
+
32
+ ```json
33
+ {
34
+ "compilerOptions": {
35
+ "target": "ES2020",
36
+ "module": "commonjs",
37
+ "lib": ["ES2020"],
38
+ "strict": true,
39
+ "esModuleInterop": true,
40
+ "skipLibCheck": true,
41
+ "forceConsistentCasingInFileNames": true,
42
+ "resolveJsonModule": true,
43
+ "moduleResolution": "node",
44
+ "allowJs": true,
45
+ "checkJs": false,
46
+ "noEmit": true
47
+ },
48
+ "include": ["config/webpack/**/*"],
49
+ "exclude": ["node_modules"]
50
+ }
51
+ ```
52
+
53
+ ### 3. Convert Your Webpack Config to TypeScript
54
+
55
+ Rename `config/webpack/webpack.config.js` to `config/webpack/webpack.config.ts`:
56
+
57
+ ```typescript
58
+ // config/webpack/webpack.config.ts
59
+ import { generateWebpackConfig, merge } from 'shakapacker'
60
+ import type { WebpackConfigWithDevServer } from 'shakapacker/types'
61
+ import type { Configuration } from 'webpack'
62
+
63
+ const customConfig: Configuration = {
64
+ resolve: {
65
+ extensions: ['.css', '.ts', '.tsx']
66
+ }
67
+ }
68
+
69
+ const config: Configuration = generateWebpackConfig(customConfig)
70
+
71
+ export default config
72
+ ```
73
+
74
+ ## Migration Steps
75
+
76
+ ### Step 1: Import Types
77
+
78
+ Start by importing the types you need:
79
+
80
+ ```typescript
81
+ import type {
82
+ Config,
83
+ WebpackConfigWithDevServer,
84
+ RspackConfigWithDevServer,
85
+ CompressionPluginOptions
86
+ } from 'shakapacker/types'
87
+ ```
88
+
89
+ ### Step 2: Type Your Configuration Objects
90
+
91
+ Add type annotations to your configuration objects:
92
+
93
+ ```typescript
94
+ // Before (JavaScript)
95
+ const customConfig = {
96
+ resolve: {
97
+ extensions: ['.css', '.ts', '.tsx']
98
+ }
99
+ }
100
+
101
+ // After (TypeScript)
102
+ import type { Configuration } from 'webpack'
103
+
104
+ const customConfig: Configuration = {
105
+ resolve: {
106
+ extensions: ['.css', '.ts', '.tsx']
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### Step 3: Type Your Custom Functions
112
+
113
+ If you have custom configuration functions, add type annotations:
114
+
115
+ ```typescript
116
+ // Before (JavaScript)
117
+ function modifyConfig(config) {
118
+ config.plugins.push(new MyPlugin())
119
+ return config
120
+ }
121
+
122
+ // After (TypeScript)
123
+ import type { Configuration } from 'webpack'
124
+ import type { WebpackPluginInstance } from 'shakapacker/types'
125
+
126
+ function modifyConfig(config: Configuration): Configuration {
127
+ const plugins = config.plugins as WebpackPluginInstance[]
128
+ plugins.push(new MyPlugin())
129
+ return config
130
+ }
131
+ ```
132
+
133
+ ### Step 4: Handle Environment-Specific Configurations
134
+
135
+ ```typescript
136
+ // config/webpack/development.ts
137
+ import { generateWebpackConfig } from 'shakapacker'
138
+ import type { WebpackConfigWithDevServer } from 'shakapacker/types'
139
+
140
+ const developmentConfig: WebpackConfigWithDevServer = generateWebpackConfig({
141
+ devtool: 'eval-cheap-module-source-map',
142
+ devServer: {
143
+ hot: true,
144
+ port: 3035
145
+ }
146
+ })
147
+
148
+ export default developmentConfig
149
+ ```
150
+
151
+ ## Common Patterns
152
+
153
+ ### Pattern 1: Custom Loaders
154
+
155
+ ```typescript
156
+ import type { RuleSetRule } from 'webpack'
157
+
158
+ const customLoader: RuleSetRule = {
159
+ test: /\.svg$/,
160
+ use: ['@svgr/webpack']
161
+ }
162
+
163
+ const config: Configuration = generateWebpackConfig({
164
+ module: {
165
+ rules: [customLoader]
166
+ }
167
+ })
168
+ ```
169
+
170
+ ### Pattern 2: Plugin Configuration
171
+
172
+ ```typescript
173
+ import CompressionPlugin from 'compression-webpack-plugin'
174
+ import type { CompressionPluginOptions } from 'shakapacker/types'
175
+
176
+ const compressionOptions: CompressionPluginOptions = {
177
+ filename: '[path][base].gz',
178
+ algorithm: 'gzip',
179
+ test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
180
+ }
181
+
182
+ const config: Configuration = generateWebpackConfig({
183
+ plugins: [new CompressionPlugin(compressionOptions)]
184
+ })
185
+ ```
186
+
187
+ ### Pattern 3: Conditional Configuration
188
+
189
+ ```typescript
190
+ import type { Configuration } from 'webpack'
191
+ import { env } from 'shakapacker'
192
+
193
+ const config: Configuration = generateWebpackConfig()
194
+
195
+ if (env.isProduction) {
196
+ // TypeScript knows config.optimization exists
197
+ config.optimization = {
198
+ ...config.optimization,
199
+ minimize: true,
200
+ sideEffects: false
201
+ }
202
+ }
203
+
204
+ export default config
205
+ ```
206
+
207
+ ### Pattern 4: Rspack Configuration
208
+
209
+ ```typescript
210
+ // config/rspack/rspack.config.ts
211
+ import type { RspackConfigWithDevServer } from 'shakapacker/types'
212
+ import { generateWebpackConfig } from 'shakapacker'
213
+
214
+ const rspackConfig: RspackConfigWithDevServer = generateWebpackConfig({
215
+ mode: 'development',
216
+ devServer: {
217
+ hot: true,
218
+ port: 3036
219
+ }
220
+ })
221
+
222
+ export default rspackConfig
223
+ ```
224
+
225
+ ## Type-checking Your Configuration
226
+
227
+ Add a script to your package.json to type-check your configuration:
228
+
229
+ ```json
230
+ {
231
+ "scripts": {
232
+ "type-check": "tsc --noEmit",
233
+ "webpack:type-check": "tsc --noEmit config/webpack/*.ts"
234
+ }
235
+ }
236
+ ```
237
+
238
+ Run type checking:
239
+
240
+ ```bash
241
+ yarn type-check
242
+ # or
243
+ npm run type-check
244
+ ```
245
+
246
+ ## Available Types Reference
247
+
248
+ ### Core Types
249
+ - `Config` - Shakapacker configuration from shakapacker.yml
250
+ - `Env` - Environment variables and helpers
251
+ - `DevServerConfig` - Development server configuration
252
+
253
+ ### Webpack/Rspack Types
254
+ - `WebpackConfigWithDevServer` - Webpack configuration with dev server
255
+ - `RspackConfigWithDevServer` - Rspack configuration with dev server
256
+ - `WebpackPluginInstance` - Webpack plugin instance type
257
+ - `RspackPlugin` - Rspack plugin interface
258
+
259
+ ### Helper Types
260
+ - `CompressionPluginOptions` - Compression plugin configuration
261
+ - `ReactRefreshWebpackPlugin` - React refresh for Webpack
262
+ - `ReactRefreshRspackPlugin` - React refresh for Rspack
263
+
264
+ ## Troubleshooting
265
+
266
+ ### Issue: "Cannot find module 'shakapacker/types'"
267
+
268
+ **Solution**: Make sure you're using Shakapacker v9.0.0 or later:
269
+
270
+ ```bash
271
+ yarn upgrade shakapacker
272
+ ```
273
+
274
+ ### Issue: Type errors with plugins
275
+
276
+ **Solution**: Cast plugin arrays when needed:
277
+
278
+ ```typescript
279
+ const plugins = (config.plugins || []) as WebpackPluginInstance[]
280
+ plugins.push(new MyPlugin())
281
+ ```
282
+
283
+ ### Issue: Missing types for custom loaders
284
+
285
+ **Solution**: Install type definitions or declare them:
286
+
287
+ ```typescript
288
+ // If types aren't available, declare them
289
+ declare module 'my-custom-loader' {
290
+ const loader: any
291
+ export default loader
292
+ }
293
+ ```
294
+
295
+ ### Issue: Conflicting types between webpack versions
296
+
297
+ **Solution**: Ensure your webpack types match your webpack version:
298
+
299
+ ```bash
300
+ yarn add --dev @types/webpack@^5
301
+ ```
302
+
303
+ ## Gradual Migration
304
+
305
+ You don't need to convert everything at once. Start with:
306
+
307
+ 1. Convert your main webpack.config.js to TypeScript
308
+ 2. Add types to the most complex configurations
309
+ 3. Gradually type other configuration files
310
+ 4. Add type checking to your CI pipeline
311
+
312
+ ## Example: Full Configuration
313
+
314
+ Here's a complete example of a typed webpack configuration:
315
+
316
+ ```typescript
317
+ // config/webpack/webpack.config.ts
318
+ import { generateWebpackConfig, merge, config as shakapackerConfig } from 'shakapacker'
319
+ import type { Configuration } from 'webpack'
320
+ import type { WebpackConfigWithDevServer } from 'shakapacker/types'
321
+ import CompressionPlugin from 'compression-webpack-plugin'
322
+ import { resolve } from 'path'
323
+
324
+ // Type-safe custom configuration
325
+ const customConfig: Configuration = {
326
+ resolve: {
327
+ extensions: ['.css', '.ts', '.tsx'],
328
+ alias: {
329
+ '@': resolve(__dirname, '../../app/javascript'),
330
+ 'components': resolve(__dirname, '../../app/javascript/components'),
331
+ 'utils': resolve(__dirname, '../../app/javascript/utils')
332
+ }
333
+ },
334
+ module: {
335
+ rules: [
336
+ {
337
+ test: /\.svg$/,
338
+ use: ['@svgr/webpack'],
339
+ issuer: /\.(tsx?|jsx?)$/
340
+ }
341
+ ]
342
+ }
343
+ }
344
+
345
+ // Generate the final configuration
346
+ const webpackConfig: Configuration = generateWebpackConfig(customConfig)
347
+
348
+ // Type-safe modifications based on environment
349
+ if (shakapackerConfig.env === 'production') {
350
+ const plugins = (webpackConfig.plugins || []) as WebpackPluginInstance[]
351
+
352
+ plugins.push(
353
+ new CompressionPlugin({
354
+ filename: '[path][base].br',
355
+ algorithm: 'brotliCompress',
356
+ test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
357
+ })
358
+ )
359
+ }
360
+
361
+ export default webpackConfig
362
+ ```
363
+
364
+ ## Next Steps
365
+
366
+ After migrating to TypeScript:
367
+
368
+ 1. **Enable strict checks**: Gradually enable stricter TypeScript options
369
+ 2. **Add custom types**: Create type definitions for your application-specific configurations
370
+ 3. **Share types**: Export reusable configuration types for your team
371
+ 4. **Document with types**: Use JSDoc comments with your types for better documentation
372
+
373
+ ## Resources
374
+
375
+ - [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
376
+ - [Webpack TypeScript Configuration](https://webpack.js.org/configuration/configuration-languages/#typescript)
377
+ - [Shakapacker Types Documentation](./types/README.md)
378
+ - [Migration Examples](https://github.com/shakacode/shakapacker/tree/main/examples/typescript-config)
@@ -125,13 +125,60 @@ if (setup_path = Rails.root.join("bin/setup")).exist?
125
125
  end
126
126
 
127
127
  Dir.chdir(Rails.root) do
128
- npm_version = Shakapacker::Utils::VersionSyntaxConverter.new.rubygem_to_npm(Shakapacker::VERSION)
129
- say "Installing shakapacker@#{npm_version}"
130
- begin
131
- @package_json.manager.add!(["shakapacker@#{npm_version}"], type: :production)
132
- rescue PackageJson::Error
133
- say "Shakapacker installation failed 😭 See above for details.", :red
134
- exit 1
128
+ # In CI, use the pre-packed tarball if available
129
+ if ENV["SHAKAPACKER_NPM_PACKAGE"]
130
+ package_path = ENV["SHAKAPACKER_NPM_PACKAGE"]
131
+
132
+ # Validate package path to prevent directory traversal and invalid file types
133
+ begin
134
+ # Resolve to absolute path
135
+ absolute_path = File.expand_path(package_path)
136
+
137
+ # Reject paths containing directory traversal
138
+ if package_path.include?("..") || absolute_path.include?("..")
139
+ say "❌ Security Error: Package path contains directory traversal: #{package_path}", :red
140
+ exit 1
141
+ end
142
+
143
+ # Ensure filename ends with .tgz or .tar.gz
144
+ unless absolute_path.end_with?(".tgz", ".tar.gz")
145
+ say "❌ Security Error: Package must be a .tgz or .tar.gz file: #{package_path}", :red
146
+ exit 1
147
+ end
148
+
149
+ # Check existence only after validation
150
+ if File.exist?(absolute_path)
151
+ say "📦 Installing shakapacker from local package: #{absolute_path}", :cyan
152
+ begin
153
+ @package_json.manager.add!([absolute_path], type: :production)
154
+ rescue PackageJson::Error
155
+ say "Shakapacker installation failed 😭 See above for details.", :red
156
+ exit 1
157
+ end
158
+ else
159
+ say "⚠️ SHAKAPACKER_NPM_PACKAGE set but file not found: #{absolute_path}", :yellow
160
+ say "Falling back to npm registry...", :yellow
161
+ npm_version = Shakapacker::Utils::VersionSyntaxConverter.new.rubygem_to_npm(Shakapacker::VERSION)
162
+ begin
163
+ @package_json.manager.add!(["shakapacker@#{npm_version}"], type: :production)
164
+ rescue PackageJson::Error
165
+ say "Shakapacker installation failed 😭 See above for details.", :red
166
+ exit 1
167
+ end
168
+ end
169
+ rescue => e
170
+ say "❌ Error validating package path: #{e.message}", :red
171
+ exit 1
172
+ end
173
+ else
174
+ npm_version = Shakapacker::Utils::VersionSyntaxConverter.new.rubygem_to_npm(Shakapacker::VERSION)
175
+ say "Installing shakapacker@#{npm_version}"
176
+ begin
177
+ @package_json.manager.add!(["shakapacker@#{npm_version}"], type: :production)
178
+ rescue PackageJson::Error
179
+ say "Shakapacker installation failed 😭 See above for details.", :red
180
+ exit 1
181
+ end
135
182
  end
136
183
 
137
184
  @package_json.merge! do |pj|
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.0.0.beta.6".freeze
3
+ VERSION = "9.0.0.beta.8".freeze
4
4
  end
@@ -0,0 +1,4 @@
1
+ # Exclude TypeScript source files from the package directory
2
+ *.ts
3
+ # But keep the TypeScript declaration files
4
+ !*.d.ts
@@ -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
+ }