rspack_rails 0.1.0 → 0.2.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/CHANGELOG.md +10 -0
- data/README.md +28 -1
- data/lib/install/rspack.config.mjs +28 -1
- data/lib/install/stimulus/autoload.js +3 -3
- data/lib/install/typescript/tsconfig.json +14 -0
- data/lib/install/typescript.rb +19 -0
- data/lib/rspack_rails/doctor.rb +13 -2
- data/lib/rspack_rails/helper.rb +8 -3
- data/lib/rspack_rails/version.rb +1 -1
- data/lib/tasks/rspack_rails.rake +7 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7f84e6f9280bcf6d3fbd54f2a3a267a817e7c333d4c89a70c8e171b477f3e85
|
|
4
|
+
data.tar.gz: '09e2d5eb77331777f33a1b58478ba1bac7774ffe83308b0f97236653fb80f534'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 79928a7186a0b752296a5d82cf5e570ce87730a24ce2c1c515c4490be4585fe512790b68b4bdef81f9a76c608a73a615d4db75d7891889092f1a8a56a7a76e66
|
|
7
|
+
data.tar.gz: 11660d1b0a381e43a789b8b5b2b92593784755cbfda2d00f32f1646b784dd39d959329fa2845febf900e4e6af38e4879c816832ecb5f2c944e1f8d6241ffbe47
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-11-13
|
|
4
|
+
|
|
5
|
+
- CSS imported from JavaScript is extracted to `app/assets/builds/<entry>.bundle.css` and hot-reloaded under `rspack serve`; `*.module.css` are CSS modules
|
|
6
|
+
- **Changed:** `rspack_stylesheet_tag "application"` now links `application.bundle.css` (was `application.css`)
|
|
7
|
+
- TypeScript: `.ts` files and `*_controller.ts` Stimulus controllers compile with the built-in SWC loader
|
|
8
|
+
- `rspack:install:typescript` adds `tsconfig.json`, `typescript` and a `typecheck` script
|
|
9
|
+
- Dev server writes bundles to disk so `app/assets/builds` stays current
|
|
10
|
+
- `rspack:doctor` warns when `application.bundle.css` is built but not linked
|
|
11
|
+
- Existing apps: re-run `bin/rails rspack:install` (and `rspack:install:stimulus`) and accept the new `rspack.config.mjs` / `autoload.js`
|
|
12
|
+
|
|
3
13
|
## [0.1.0] - 2026-11-13
|
|
4
14
|
|
|
5
15
|
- `rspack:doctor`: checks Node.js against rspack's `engines`, packages, config, entry, build output, layout, Procfile.dev, Stimulus and the dev server
|
data/README.md
CHANGED
|
@@ -57,17 +57,44 @@ end
|
|
|
57
57
|
bin/rails rspack:install:stimulus
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
This installs `@hotwired/stimulus` and adds `app/javascript/controllers/autoload.js`, imported from `application.js`. Every `*_controller.js` under `app/javascript/controllers` is registered automatically, with the usual naming (`admin/user_card_controller.js` becomes `admin--user-card`). There is no manifest to keep up to date.
|
|
60
|
+
This installs `@hotwired/stimulus` and adds `app/javascript/controllers/autoload.js`, imported from `application.js`. Every `*_controller.js` (or `.ts`) under `app/javascript/controllers` is registered automatically, with the usual naming (`admin/user_card_controller.js` becomes `admin--user-card`). There is no manifest to keep up to date.
|
|
61
61
|
|
|
62
62
|
Under `rspack serve`, editing a controller or adding a new one hot-swaps it in the open page without a reload, so form input and other page state survive.
|
|
63
63
|
|
|
64
64
|
If `application.js` imported `./controllers` (the stimulus-rails index), the installer switches it to `./controllers/autoload`. stimulus-rails may still rewrite `controllers/index.js` when you run `bin/rails generate stimulus`, but nothing imports that file any more.
|
|
65
65
|
|
|
66
|
+
### CSS
|
|
67
|
+
|
|
68
|
+
Import CSS from your JavaScript and rspack extracts it to `app/assets/builds/<entry>.bundle.css`:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
// app/javascript/application.js
|
|
72
|
+
import "./styles/application.css"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```erb
|
|
76
|
+
<%= rspack_stylesheet_tag "application" %>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`*.module.css` files are compiled as CSS modules. Under `rspack serve`, CSS changes are applied without a page reload.
|
|
80
|
+
|
|
81
|
+
The `.bundle` suffix keeps the output from clashing with `app/assets/stylesheets/application.css`. Rails 8's default `stylesheet_link_tag :app` links every CSS file under `app/assets`, so it also links the bundle. That is harmless: the dev server keeps `app/assets/builds` up to date and its own link comes later in the cascade. A rule you delete keeps applying until the next reload.
|
|
82
|
+
|
|
83
|
+
### TypeScript
|
|
84
|
+
|
|
85
|
+
`.ts` files compile out of the box with Rspack's built-in SWC loader, including Stimulus controllers (`*_controller.ts`). SWC strips types without checking them. For type checking:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
bin/rails rspack:install:typescript # tsconfig.json, typescript, "typecheck" script
|
|
89
|
+
npm run typecheck
|
|
90
|
+
```
|
|
91
|
+
|
|
66
92
|
### Tasks
|
|
67
93
|
|
|
68
94
|
| Task | What it does |
|
|
69
95
|
|---|---|
|
|
70
96
|
| `bin/rails rspack:install:stimulus` | Sets up Stimulus with controller autoloading |
|
|
97
|
+
| `bin/rails rspack:install:typescript` | Adds tsconfig.json, typescript and a `typecheck` script |
|
|
71
98
|
| `bin/rails rspack:doctor` | Checks Node.js, packages, config, layout, Procfile and dev server |
|
|
72
99
|
| `bin/rails rspack:build` | Installs JS dependencies, then runs `build` |
|
|
73
100
|
| `bin/rails rspack:clobber` | Removes rspack output from `app/assets/builds` |
|
|
@@ -22,14 +22,41 @@ export default defineConfig({
|
|
|
22
22
|
path: path.resolve(root, "app/assets/builds"),
|
|
23
23
|
filename: "[name].js",
|
|
24
24
|
// ".digested" tells Propshaft the file is already fingerprinted.
|
|
25
|
-
|
|
25
|
+
chunkFilename: "[name]-[contenthash].digested.js",
|
|
26
|
+
// CSS imported from JavaScript. ".bundle" avoids clashing with
|
|
27
|
+
// app/assets/stylesheets/application.css in Propshaft.
|
|
28
|
+
cssFilename: "[name].bundle.css",
|
|
29
|
+
cssChunkFilename: "[name]-[contenthash].digested.css",
|
|
26
30
|
// Under `rspack serve`, chunks and hot updates load from the dev server.
|
|
27
31
|
publicPath: isDevServer ? `http://${host}:${port}/` : "/assets/",
|
|
28
32
|
},
|
|
33
|
+
resolve: {
|
|
34
|
+
extensions: ["...", ".ts"],
|
|
35
|
+
},
|
|
36
|
+
module: {
|
|
37
|
+
rules: [
|
|
38
|
+
{
|
|
39
|
+
// Transpile TypeScript with Rspack's built-in SWC (no type checking).
|
|
40
|
+
test: /\.ts$/,
|
|
41
|
+
exclude: /node_modules/,
|
|
42
|
+
loader: "builtin:swc-loader",
|
|
43
|
+
options: { jsc: { parser: { syntax: "typescript" } } },
|
|
44
|
+
type: "javascript/auto",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
// Native CSS; *.module.css files become CSS modules.
|
|
48
|
+
test: /\.css$/,
|
|
49
|
+
type: "css/auto",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
29
53
|
devServer: {
|
|
30
54
|
host,
|
|
31
55
|
port,
|
|
32
56
|
hot: true,
|
|
57
|
+
// Keep app/assets/builds current while the dev server runs, so Propshaft
|
|
58
|
+
// (and `stylesheet_link_tag :app`) never serve a stale bundle.
|
|
59
|
+
devMiddleware: { writeToDisk: true },
|
|
33
60
|
allowedHosts: "all",
|
|
34
61
|
headers: { "Access-Control-Allow-Origin": "*" },
|
|
35
62
|
client: {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
// Registers every app/javascript/controllers/**/*_controller.js with Stimulus.
|
|
1
|
+
// Registers every app/javascript/controllers/**/*_controller.{js,ts} with Stimulus.
|
|
2
2
|
// Managed by rspack_rails: new controllers need no manual import, and edited
|
|
3
3
|
// controllers are hot-swapped under `rspack serve` without a page reload.
|
|
4
4
|
import { application } from "./application"
|
|
5
5
|
|
|
6
6
|
const controllers = () =>
|
|
7
|
-
import.meta.webpackContext("./", { recursive: true, regExp: /_controller\.
|
|
7
|
+
import.meta.webpackContext("./", { recursive: true, regExp: /_controller\.[jt]s$/ })
|
|
8
8
|
|
|
9
9
|
// "./users/profile_controller.js" -> "users--profile"
|
|
10
10
|
const identifierFor = (key) =>
|
|
11
11
|
key
|
|
12
12
|
.replace(/^\.\//, "")
|
|
13
|
-
.replace(/_controller\.
|
|
13
|
+
.replace(/_controller\.[jt]s$/, "")
|
|
14
14
|
.replace(/\//g, "--")
|
|
15
15
|
.replace(/_/g, "-")
|
|
16
16
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"types": ["@rspack/core/module"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"skipLibCheck": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["app/javascript/**/*.ts"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Rails application template run by `bin/rails rspack:install:typescript`.
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
pm = RspackRails::PackageManager.detect(Rails.root)
|
|
7
|
+
|
|
8
|
+
say "Adding tsconfig.json"
|
|
9
|
+
copy_file "#{__dir__}/typescript/tsconfig.json", "tsconfig.json"
|
|
10
|
+
|
|
11
|
+
say "Adding typecheck script"
|
|
12
|
+
package = JSON.parse(File.read("package.json"))
|
|
13
|
+
(package["scripts"] ||= {})["typecheck"] = "tsc --noEmit"
|
|
14
|
+
File.write("package.json", "#{JSON.pretty_generate(package)}\n")
|
|
15
|
+
|
|
16
|
+
say "Installing typescript"
|
|
17
|
+
run pm.add_dev_command("typescript")
|
|
18
|
+
|
|
19
|
+
say "TypeScript ready. Rspack compiles .ts files; run `#{pm.run_command("typecheck")}` to type-check.", :green
|
data/lib/rspack_rails/doctor.rb
CHANGED
|
@@ -9,6 +9,7 @@ module RspackRails
|
|
|
9
9
|
# Inspects a Rails app's rspack setup and reports what is missing.
|
|
10
10
|
class Doctor
|
|
11
11
|
Check = Struct.new(:status, :name, :detail, :hint)
|
|
12
|
+
LAYOUT = "app/views/layouts/application.html.erb"
|
|
12
13
|
SYMBOLS = { ok: "✓", warn: "!", error: "✗" }.freeze
|
|
13
14
|
|
|
14
15
|
def initialize(root, config: RspackRails.config, dev_server: RspackRails.dev_server, node_version: nil)
|
|
@@ -21,7 +22,7 @@ module RspackRails
|
|
|
21
22
|
def checks
|
|
22
23
|
@checks ||= [
|
|
23
24
|
node_check, package_check(:cli), package_check(:core), package_check(:"dev-server"),
|
|
24
|
-
config_check, scripts_check, entry_check, build_check, layout_check, procfile_check,
|
|
25
|
+
config_check, scripts_check, entry_check, build_check, layout_check, stylesheet_check, procfile_check,
|
|
25
26
|
stimulus_check, dev_server_check
|
|
26
27
|
].compact
|
|
27
28
|
end
|
|
@@ -105,7 +106,7 @@ module RspackRails
|
|
|
105
106
|
end
|
|
106
107
|
|
|
107
108
|
def layout_check
|
|
108
|
-
layout = read(
|
|
109
|
+
layout = read(LAYOUT)
|
|
109
110
|
return Check.new(:warn, "Layout", "app/views/layouts/application.html.erb not found") unless layout
|
|
110
111
|
|
|
111
112
|
if layout.include?("javascript_importmap_tags")
|
|
@@ -118,6 +119,16 @@ module RspackRails
|
|
|
118
119
|
%(Add <%= rspack_javascript_tag "application" %> to get the dev server and HMR))
|
|
119
120
|
end
|
|
120
121
|
|
|
122
|
+
def stylesheet_check
|
|
123
|
+
return unless exist?("app/assets/builds/application.bundle.css")
|
|
124
|
+
|
|
125
|
+
linked = read(LAYOUT)&.include?("rspack_stylesheet_tag")
|
|
126
|
+
return Check.new(:ok, "Stylesheet", "uses rspack_stylesheet_tag") if linked
|
|
127
|
+
|
|
128
|
+
Check.new(:warn, "Stylesheet", "application.bundle.css is built but not linked",
|
|
129
|
+
%(Add <%= rspack_stylesheet_tag "application" %> to your layout))
|
|
130
|
+
end
|
|
131
|
+
|
|
121
132
|
def procfile_check
|
|
122
133
|
procfile = read("Procfile.dev")
|
|
123
134
|
if procfile&.match?(/^js: .*\bdev$/)
|
data/lib/rspack_rails/helper.rb
CHANGED
|
@@ -12,11 +12,16 @@ module RspackRails
|
|
|
12
12
|
"\n")
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Links the CSS that rspack extracts from an entry's imports
|
|
16
|
+
# (app/assets/builds/<entry>.bundle.css).
|
|
15
17
|
def rspack_stylesheet_tag(*entries, **options)
|
|
16
|
-
|
|
18
|
+
unless RspackRails.dev_server.running?
|
|
19
|
+
return stylesheet_link_tag(*entries.map { |entry| "#{entry}.bundle" }, **options)
|
|
20
|
+
end
|
|
17
21
|
|
|
18
|
-
safe_join(entries.map
|
|
19
|
-
|
|
22
|
+
safe_join(entries.map do |entry|
|
|
23
|
+
stylesheet_link_tag(RspackRails.dev_server.url("#{entry}.bundle.css"), **options)
|
|
24
|
+
end, "\n")
|
|
20
25
|
end
|
|
21
26
|
end
|
|
22
27
|
end
|
data/lib/rspack_rails/version.rb
CHANGED
data/lib/tasks/rspack_rails.rake
CHANGED
|
@@ -15,6 +15,13 @@ namespace :rspack do
|
|
|
15
15
|
system(RbConfig.ruby, "./bin/rails", "app:template", "LOCATION=#{template}") ||
|
|
16
16
|
raise(RspackRails::Error, "rspack:install:stimulus failed")
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
desc "Set up TypeScript type checking (tsconfig.json, typescript, typecheck script)"
|
|
20
|
+
task :typescript do
|
|
21
|
+
template = File.expand_path("../install/typescript.rb", __dir__)
|
|
22
|
+
system(RbConfig.ruby, "./bin/rails", "app:template", "LOCATION=#{template}") ||
|
|
23
|
+
raise(RspackRails::Error, "rspack:install:typescript failed")
|
|
24
|
+
end
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
desc "Check the rspack setup of this app"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rspack_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tungnt
|
|
@@ -51,6 +51,8 @@ files:
|
|
|
51
51
|
- lib/install/stimulus/application.js
|
|
52
52
|
- lib/install/stimulus/autoload.js
|
|
53
53
|
- lib/install/stimulus/hello_controller.js
|
|
54
|
+
- lib/install/typescript.rb
|
|
55
|
+
- lib/install/typescript/tsconfig.json
|
|
54
56
|
- lib/rspack_rails.rb
|
|
55
57
|
- lib/rspack_rails/configuration.rb
|
|
56
58
|
- lib/rspack_rails/dev_server.rb
|