create-clojurific 0.12.6 → 0.12.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.
- package/README.md +10 -4
- package/create.js +1 -1
- package/index.js +3 -2
- package/package.json +1 -1
- package/prompts.js +8 -3
- package/templates/hono/README.md +25 -0
- package/templates/hono/_gitignore +8 -0
- package/templates/hono/deps.edn +3 -0
- package/templates/hono/package.json +22 -0
- package/templates/hono/src/{{nsDir}}/core.cljs +14 -0
- package/templates/hono/vite.config.mjs +33 -0
- package/templates/reagent/vite.config.mjs +2 -2
- package/templates/uix/vite.config.mjs +2 -2
- package/templates/vanilla/vite.config.mjs +2 -2
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@ Scaffolds a ClojureScript project compiled by
|
|
|
8
8
|
npm create clojurific@latest
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
It asks for the project's name, a framework (Vanilla, [Reagent](https://reagent-project.github.io)
|
|
12
|
-
|
|
13
|
-
dependencies and start the dev server. The project's namespace comes from its
|
|
11
|
+
It asks for the project's name, a framework (Vanilla, [Reagent](https://reagent-project.github.io/),
|
|
12
|
+
[UIx](https://uix-cljs.dev/), or [Hono](https://hono.dev/) for a backend), and
|
|
13
|
+
whether to install the dependencies and start the dev server. The project's namespace comes from its
|
|
14
14
|
name: `my-app` gets `src/my_app/core.cljs`, `my-app.core`. The compiler needs
|
|
15
15
|
Node.js 20 and Java 17 or later; when Java is missing, it offers to download
|
|
16
16
|
Eclipse Temurin before starting the dev server.
|
|
@@ -19,16 +19,22 @@ Projects have the scripts `dev` (Vite's dev server, hot reloading), `build`,
|
|
|
19
19
|
`preview`, and `repl`, a ClojureScript REPL evaluating in the pages the dev
|
|
20
20
|
server runs (`cljf repl`, through the dev server's nREPL server).
|
|
21
21
|
|
|
22
|
+
The Hono project is a backend without pages: its app is a namespace the dev
|
|
23
|
+
server runs with [`@hono/vite-dev-server`](https://github.com/honojs/vite-plugins),
|
|
24
|
+
hot reloading it, and its REPL evaluates there. `build` bundles it into a
|
|
25
|
+
Node.js server, `dist/index.js`, which `start` runs.
|
|
26
|
+
|
|
22
27
|
The options answer the questions, i.e. in scripts:
|
|
23
28
|
|
|
24
29
|
```sh
|
|
25
30
|
npm create clojurific@latest my-app -- --template reagent
|
|
26
31
|
npm create clojurific@latest my-app -- --template uix --immediate
|
|
32
|
+
npm create clojurific@latest my-api -- --template hono
|
|
27
33
|
```
|
|
28
34
|
|
|
29
35
|
| Option | |
|
|
30
36
|
|---|---|
|
|
31
|
-
| `-t`, `--template <name>` | `vanilla`, `reagent` or `
|
|
37
|
+
| `-t`, `--template <name>` | `vanilla`, `reagent`, `uix` or `hono` |
|
|
32
38
|
| `--overwrite` | remove the target directory's files |
|
|
33
39
|
| `-i`, `--immediate` | install the dependencies and start the dev server |
|
|
34
40
|
| `--no-interactive` | don't ask, use the defaults (`vanilla`, no install) |
|
package/create.js
CHANGED
|
@@ -12,7 +12,7 @@ export const version = JSON.parse(readFileSync(path.join(packageRoot, 'package.j
|
|
|
12
12
|
|
|
13
13
|
export const templatesDir = path.join(packageRoot, 'templates');
|
|
14
14
|
|
|
15
|
-
export const TEMPLATES = ['vanilla', 'reagent', 'uix'];
|
|
15
|
+
export const TEMPLATES = ['vanilla', 'reagent', 'uix', 'hono'];
|
|
16
16
|
|
|
17
17
|
export const DEFAULT_PROJECT = 'clojurific-project';
|
|
18
18
|
|
package/index.js
CHANGED
|
@@ -27,8 +27,9 @@ Options:
|
|
|
27
27
|
|
|
28
28
|
const FRAMEWORKS = [
|
|
29
29
|
{ value: 'vanilla', label: 'Vanilla', color: c.yellow },
|
|
30
|
-
{ value: 'reagent', label: 'Reagent', color: c.cyan },
|
|
31
|
-
{ value: 'uix', label: 'UIx', color: c.magenta },
|
|
30
|
+
{ value: 'reagent', label: 'Reagent', color: c.cyan, hint: 'https://reagent-project.github.io/' },
|
|
31
|
+
{ value: 'uix', label: 'UIx', color: c.magenta, hint: 'https://uix-cljs.dev/' },
|
|
32
|
+
{ value: 'hono', label: 'Hono (backend only)', color: c.red, hint: 'https://hono.dev/' },
|
|
32
33
|
];
|
|
33
34
|
|
|
34
35
|
function parse(argv) {
|
package/package.json
CHANGED
package/prompts.js
CHANGED
|
@@ -129,9 +129,14 @@ export function text({ message, placeholder = '', defaultValue = '' }) {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
/** One of options ({value, label, color}), initialValue first. */
|
|
132
|
+
/** One of options ({value, label, color, hint}), initialValue first. */
|
|
133
133
|
export function select({ message, options, initialValue }) {
|
|
134
134
|
const paint = option => (option.color ? option.color(option.label) : option.label);
|
|
135
|
+
// hints (i.e. links) aligned after the longest label
|
|
136
|
+
const width = Math.max(...options.map(o => o.label.length));
|
|
137
|
+
const line = option => (option.hint
|
|
138
|
+
? `${paint(option)}${' '.repeat(width - option.label.length + 2)}${c.dim(option.hint)}`
|
|
139
|
+
: paint(option));
|
|
135
140
|
return prompt({
|
|
136
141
|
state: { index: Math.max(0, options.findIndex(o => o.value === initialValue)) },
|
|
137
142
|
value: s => options[s.index].value,
|
|
@@ -142,8 +147,8 @@ export function select({ message, options, initialValue }) {
|
|
|
142
147
|
},
|
|
143
148
|
render(s, status) {
|
|
144
149
|
const lines = options.map((option, i) => (i === s.index
|
|
145
|
-
? `${c.green(S.radioOn)} ${
|
|
146
|
-
: `${c.dim(S.radioOff)} ${c.dim(
|
|
150
|
+
? `${c.green(S.radioOn)} ${line(option)}`
|
|
151
|
+
: `${c.dim(S.radioOff)} ${c.dim(line(option))}`));
|
|
147
152
|
lines.push(`${c.dim('↑/↓')} to navigate ${c.dim('•')} ${c.dim('Enter:')} confirm`);
|
|
148
153
|
return title(message, status) + body(status, lines, paint(options[s.index]));
|
|
149
154
|
},
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# {{name}}
|
|
2
|
+
|
|
3
|
+
A [Hono](https://hono.dev) backend in ClojureScript, compiled by
|
|
4
|
+
[Clojurific](https://github.com/WhimsicalCode/clojurific) and bundled by
|
|
5
|
+
[Vite](https://vite.dev).
|
|
6
|
+
|
|
7
|
+
- `npm run dev` starts the dev server, which hot reloads changed namespaces
|
|
8
|
+
- `npm run repl` starts a ClojureScript REPL evaluating in the backend the dev
|
|
9
|
+
server runs (start `npm run dev` first)
|
|
10
|
+
- `npm run build` bundles the backend into `dist/index.js`, a Node.js server
|
|
11
|
+
(no `node_modules` needed)
|
|
12
|
+
- `npm start` runs it (on port 3000)
|
|
13
|
+
|
|
14
|
+
The app is `src/{{nsDir}}/core.cljs`. It's compiled as a `:js-entries` module
|
|
15
|
+
exporting the app (see `vite.config.mjs`), which
|
|
16
|
+
[`@hono/vite-dev-server`](https://github.com/honojs/vite-plugins) serves and
|
|
17
|
+
`@hono/vite-build` bundles. Changed namespaces are hot reloaded in place:
|
|
18
|
+
`defonce` keeps its value.
|
|
19
|
+
|
|
20
|
+
ClojureScript dependencies go in `deps.edn`, npm packages in `package.json`.
|
|
21
|
+
The compiler needs Java 17 or later: `npx cljf setup-java` downloads one.
|
|
22
|
+
|
|
23
|
+
Editors connect to the dev server's nREPL server, its port in `.nrepl-port`
|
|
24
|
+
(i.e. Calva's "Connect to a running REPL", CIDER's `cider-connect-clj`), and
|
|
25
|
+
evaluate `(cljf.esm.repl/repl)` to switch the session to ClojureScript.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clojurific-project",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"repl": "cljf repl"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@hono/node-server": "^2.1.4",
|
|
14
|
+
"hono": "^4.13.13"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@hono/vite-build": "^1.11.1",
|
|
18
|
+
"@hono/vite-dev-server": "^0.26.1",
|
|
19
|
+
"clojurific": "*",
|
|
20
|
+
"vite": "^8.3.3"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(ns {{ns}}
|
|
2
|
+
(:require ["hono" :refer [Hono]]))
|
|
3
|
+
|
|
4
|
+
;; kept across hot reloads
|
|
5
|
+
(defonce clicks (atom 0))
|
|
6
|
+
|
|
7
|
+
(defn- state [c]
|
|
8
|
+
(.json c #js {:clicks @clicks}))
|
|
9
|
+
|
|
10
|
+
(def app
|
|
11
|
+
(doto (Hono.)
|
|
12
|
+
(.get "/" (fn [c] (.text c "Hello Hono! Edit src/{{nsDir}}/core.cljs and save to hot reload")))
|
|
13
|
+
(.get "/clicks" state)
|
|
14
|
+
(.post "/clicks" (fn [c] (swap! clicks inc) (state c)))))
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import cljf from 'clojurific/vite';
|
|
2
|
+
import devServer from '@hono/vite-dev-server';
|
|
3
|
+
import build from '@hono/vite-build/node';
|
|
4
|
+
|
|
5
|
+
// the backend: a module exporting the Hono app (:js-entries below)
|
|
6
|
+
const entry = 'target/cljs/cljs-esm-entries/server.js';
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
plugins: [
|
|
10
|
+
cljf({
|
|
11
|
+
outputDir: 'target/cljs',
|
|
12
|
+
compilerOptions: {
|
|
13
|
+
'js-entries': { server: { exports: { default: "'{{ns}}/app" } } },
|
|
14
|
+
// the dev server starts an nREPL server, its port in .nrepl-port
|
|
15
|
+
repl: { 'nrepl-port': 0 },
|
|
16
|
+
},
|
|
17
|
+
// the dev server runs the backend once compiled, not on its first
|
|
18
|
+
// request: the REPL evaluates in it
|
|
19
|
+
ssrEntries: ['server'],
|
|
20
|
+
// no pages, no manifest of their scripts
|
|
21
|
+
manifest: false,
|
|
22
|
+
}),
|
|
23
|
+
devServer({
|
|
24
|
+
entry,
|
|
25
|
+
// ssrLoadModule's runner has no HMR, it would re-run a changed module
|
|
26
|
+
// (and its importers), the ssr environment's runner hot reloads
|
|
27
|
+
// namespaces in place: defonce keeps its value
|
|
28
|
+
loadModule: async (server, entry) => (await server.environments.ssr.runner.import(entry)).default,
|
|
29
|
+
}),
|
|
30
|
+
// the cljf plugin minifies, after pruning unused protocol implementations
|
|
31
|
+
build({ entry, emptyOutDir: true, minify: false }),
|
|
32
|
+
],
|
|
33
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import cljf from 'clojurific/vite';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
plugins: [
|
|
5
|
-
|
|
5
|
+
cljf({
|
|
6
6
|
outputDir: 'target/cljs',
|
|
7
7
|
// the dev server starts an nREPL server, its port in .nrepl-port
|
|
8
8
|
compilerOptions: { repl: { 'nrepl-port': 0 } },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import cljf from 'clojurific/vite';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
plugins: [
|
|
5
|
-
|
|
5
|
+
cljf({
|
|
6
6
|
outputDir: 'target/cljs',
|
|
7
7
|
// the dev server starts an nREPL server, its port in .nrepl-port
|
|
8
8
|
compilerOptions: { repl: { 'nrepl-port': 0 } },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import cljf from 'clojurific/vite';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
plugins: [
|
|
5
|
-
|
|
5
|
+
cljf({
|
|
6
6
|
outputDir: 'target/cljs',
|
|
7
7
|
// the dev server starts an nREPL server, its port in .nrepl-port
|
|
8
8
|
compilerOptions: { repl: { 'nrepl-port': 0 } },
|