@xh/hoist 76.0.0-SNAPSHOT.1755187001333 → 76.0.0-SNAPSHOT.1755394070476
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/docs/build-and-deploy.md +128 -119
- package/docs/development-environment.md +69 -55
- package/package.json +1 -1
package/docs/build-and-deploy.md
CHANGED
|
@@ -9,16 +9,17 @@ at the build process.
|
|
|
9
9
|
|
|
10
10
|
**_At a high level, the build process:_**
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
-
|
|
12
|
+
- Builds the Grails back-end via Gradle, producing a WAR file.
|
|
13
|
+
- Builds the JS front-end via Webpack, producing a set of production ready client assets.
|
|
14
|
+
- Copies both outputs into a pair of Docker containers and publishes those containers as the
|
|
15
|
+
end-product of the build.
|
|
16
|
+
- Deploys the new images, immediately or in a later step.
|
|
17
17
|
|
|
18
18
|
Hoist does not mandate the use of any particular CI system, although we recommend and use
|
|
19
19
|
[Jetbrains Teamcity](https://www.jetbrains.com/teamcity/) across multiple project deployments. The
|
|
20
20
|
examples in this section do reference some Teamcity terms (although these concepts are very general
|
|
21
|
-
and applicable to any common CI system).
|
|
21
|
+
and applicable to any common CI system). In addition to TC, Hoist applications are currently built
|
|
22
|
+
and deployed using GitHub Actions and Gitlab pipelines.
|
|
22
23
|
|
|
23
24
|
Hoist also does not require the use of Docker or containerization in general, nor does it rely on
|
|
24
25
|
any particular container orchestration technology (e.g. Kubernetes). That said, the move towards
|
|
@@ -29,20 +30,21 @@ to bundle up and somewhat abstract away the two-part nature of full-stack Hoist
|
|
|
29
30
|
assigned to your application. This is a short, camelCased variant of the longer `appName` and is set
|
|
30
31
|
within the application source code via both the Gradle and Webpack configs.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
## Setup/Prep
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
### Refresh and Lint JS Client
|
|
35
36
|
|
|
36
37
|
We do this first to fail fast if the client code doesn't pass the linter checks, which is relatively
|
|
37
38
|
common. This step could also run any preflight unit tests, etc. should you be diligent enough to
|
|
38
|
-
have them.
|
|
39
|
+
have them. The below assumes `yarn` is used for the project's package manager, sub with `npm` if
|
|
40
|
+
using that instead.
|
|
39
41
|
|
|
40
42
|
```bash
|
|
41
43
|
yarn
|
|
42
44
|
yarn lint
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
### Set Gradle project name (optional)
|
|
46
48
|
|
|
47
49
|
It’s best to be explicit with Gradle about the name of the project. By default it uses the name of
|
|
48
50
|
the containing directory, which in a CI build is probably a random hash.
|
|
@@ -73,9 +75,9 @@ As a workaround, we can have the build system take the app name (we use a projec
|
|
|
73
75
|
echo "rootProject.name = \"%appCode%\"" > settings.gradle
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
## Server and Client Builds
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
### Build Grails server WAR with Gradle
|
|
79
81
|
|
|
80
82
|
This step calls into a `build.gradle` script checked in with each project to build the Grails
|
|
81
83
|
server-side into a WAR.
|
|
@@ -83,11 +85,11 @@ server-side into a WAR.
|
|
|
83
85
|
This step takes an application version as well as an optional build tag, both of which are baked
|
|
84
86
|
into the build:
|
|
85
87
|
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
- `xhAppVersion` - an x.y.z version for releases, or `x.y-SNAPSHOT` for transient builds.
|
|
89
|
+
- `xhAppBuild` - this is an optional arg that gets baked into the server and client and exposed as a
|
|
90
|
+
variable for display in the built-in Hoist admin client. We use it to pass a git commit hash,
|
|
91
|
+
which then provides another way to cross-reference exactly what snapshot of the codebase was used
|
|
92
|
+
to build any given running application.
|
|
91
93
|
|
|
92
94
|
Both version and build can be left unspecified, in which case the version will default to the
|
|
93
95
|
version specified within the app’s `gradle.properties` file (the build tag is nullable). Our
|
|
@@ -108,18 +110,21 @@ project and used according to Gradle best practices.
|
|
|
108
110
|
|
|
109
111
|
In both cases, the output is a `appCode-appVersion.war` file within `/build/libs`.
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
### Build TS Client with Webpack
|
|
112
114
|
|
|
113
|
-
This step builds all the client-side assets (
|
|
115
|
+
This step builds all the client-side assets (TS/CSS/static resources) with Webpack, taking the
|
|
114
116
|
source and dependencies and producing concatenated, minified, and hashed files suitable for serving
|
|
115
|
-
to browsers.
|
|
117
|
+
to browsers.
|
|
118
|
+
|
|
119
|
+
In the example below, we use `yarn` as our package manager / runner tool.
|
|
116
120
|
|
|
117
121
|
This step takes several arguments that are passed via a script in `package.json` to Webpack. Each
|
|
118
122
|
project has a `webpack.config.js` file checked into the root of its `client-app` directory that
|
|
119
123
|
accepts any args and runs them through a script provided by
|
|
120
124
|
[hoist-dev-utils](https://github.com/xh/hoist-dev-utils/blob/master/configureWebpack.js) to produce
|
|
121
|
-
a fully-based Webpack configuration object.
|
|
122
|
-
|
|
125
|
+
a fully-based Webpack configuration object. See that project for additional details.
|
|
126
|
+
|
|
127
|
+
The appVersion and appBuild params, detailed above, are the most common options set at build-time.
|
|
123
128
|
|
|
124
129
|
An example Teamcity command line runner. ⚠️ Note this must run with `client-app` as its working
|
|
125
130
|
directory:
|
|
@@ -136,9 +141,9 @@ yarn build --env.appVersion=$appVersion --env.appBuild=$appBuild
|
|
|
136
141
|
|
|
137
142
|
The output is a set of files within `/client-app/build/` .
|
|
138
143
|
|
|
139
|
-
|
|
144
|
+
## Docker Container images
|
|
140
145
|
|
|
141
|
-
|
|
146
|
+
The primary outputs of the overall build process are a pair of Docker containers, one for the
|
|
142
147
|
Grails server and one for the client JS assets. These include the build assets and are tagged with
|
|
143
148
|
the desired version, making them (as a pair) a complete and deployable instance of the application.
|
|
144
149
|
|
|
@@ -148,30 +153,32 @@ both the server and client containers. Both can be based on
|
|
|
148
153
|
[those](https://github.com/xh/xh-tomcat) [images](https://github.com/xh/xh-nginx) will show that
|
|
149
154
|
they are very thin layers on top of the official Tomcat and nginx images on Docker Hub.
|
|
150
155
|
|
|
151
|
-
|
|
156
|
+
### Build and Publish Tomcat Docker image
|
|
152
157
|
|
|
153
158
|
The Grails server component is deployed within a Tomcat container. The app should have a minimal
|
|
154
159
|
`/docker/tomcat/Dockerfile` (checked into source control) such as:
|
|
155
160
|
|
|
156
161
|
```dockerfile
|
|
157
|
-
|
|
162
|
+
# Update the tag below to a fixed version for stability, or next to get a regularly updated build
|
|
163
|
+
FROM xhio/xh-tomcat:next-jdk17
|
|
158
164
|
COPY setenv.sh bin/
|
|
159
165
|
COPY *.war webapps/ROOT.war
|
|
160
166
|
```
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
environment variables / Java Opts required by Tomcat. This typically contains a reasonable `Xmx`
|
|
164
|
-
(max JVM heap) value for the app and a pointer to an “instance config” file used by Hoist apps to
|
|
165
|
-
bootstrap themselves with DB credentials and other low-level configuration required at startup. By
|
|
166
|
-
convention we place this file within a Docker volume that’s mounted to `/appCode` within each
|
|
167
|
-
container
|
|
168
|
+
------
|
|
168
169
|
|
|
169
|
-
|
|
170
|
+
#### Optional `setenv.sh`
|
|
171
|
+
|
|
172
|
+
The optional `setenv.sh` referenced here can be checked in with the app project and used to set
|
|
173
|
+
environment variables / Java Opts required by Tomcat. This typically contains a reasonable `Xmx`
|
|
174
|
+
(max JVM heap) value for the app, either hard-coded or referencing a CI param or env variable:
|
|
170
175
|
|
|
171
176
|
```bash
|
|
172
|
-
export JAVA_OPTS="$JAVA_OPTS -Xmx2G
|
|
177
|
+
export JAVA_OPTS="$JAVA_OPTS -Xmx2G"
|
|
173
178
|
```
|
|
174
179
|
|
|
180
|
+
------
|
|
181
|
+
|
|
175
182
|
That leaves the build with the job of generating a suitable tag for the container, running the
|
|
176
183
|
Docker build, and then pushing to an appropriate (likely internal) Docker registry. The container
|
|
177
184
|
tag should include the appCode + `-tomcat` to indicate that this is the Grails-side container.
|
|
@@ -203,28 +210,33 @@ rm *.war
|
|
|
203
210
|
exit $ret
|
|
204
211
|
```
|
|
205
212
|
|
|
206
|
-
|
|
213
|
+
### Build and Publish nginx Docker image
|
|
207
214
|
|
|
208
215
|
The static JS resources are deployed within an nginx container. The app should have a minimal
|
|
209
216
|
`/docker/nginx/Dockerfile/ ` (checked into source control) such as:
|
|
210
217
|
|
|
211
218
|
```dockerfile
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
COPY
|
|
219
|
+
# Update the tag below to a fixed version for stability, or next to get a regularly updated build
|
|
220
|
+
FROM xhio/xh-nginx:next
|
|
221
|
+
COPY app.conf $XH_NGINX_CONFIG_PATH/
|
|
222
|
+
COPY build/ $XH_NGINX_CONTENT_PATH/
|
|
215
223
|
```
|
|
216
224
|
|
|
217
|
-
Note that the `$
|
|
225
|
+
Note that the `$XH_` environment variables are set for convenience within the `xh-nginx` base image
|
|
218
226
|
Dockerfile.
|
|
219
227
|
|
|
220
|
-
|
|
228
|
+
------
|
|
229
|
+
|
|
230
|
+
#### About the `app.conf` nginx configuration file
|
|
231
|
+
|
|
232
|
+
The `app.conf` referenced above is an app-specific nginx configuration that should be checked in
|
|
221
233
|
alongside the Dockerfile. It should setup the available routes to serve each bundled client app,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
234
|
+
handle any required redirects, and (importantly) include a _proxy configuration_ to pass traffic
|
|
235
|
+
through from the nginx container to the Tomcat container. Hoist deploys typically bind only the
|
|
236
|
+
nginx ports to the host machine, then link the nginx and Tomcat containers together via Docker/k8s
|
|
237
|
+
so there’s a single point of entry (nginx) for incoming requests. This means that no CORS or
|
|
238
|
+
further, external proxy configuration is required to have the nginx-hosted client communicate with
|
|
239
|
+
its Tomcat back-end.
|
|
228
240
|
|
|
229
241
|
While the exact content of the `app.conf` file will vary depending on the app, a representative
|
|
230
242
|
example is below:
|
|
@@ -232,20 +244,19 @@ example is below:
|
|
|
232
244
|
```
|
|
233
245
|
server {
|
|
234
246
|
server_name localhost;
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
server {
|
|
239
|
-
server_name localhost;
|
|
240
|
-
listen 443 ssl;
|
|
247
|
+
listen 80;
|
|
241
248
|
root /usr/share/nginx/html;
|
|
242
249
|
|
|
243
|
-
|
|
244
|
-
|
|
250
|
+
# NOT included here - CSP and other security-related headers. See Toolbox for recommendations,
|
|
251
|
+
# ensuring you tailor to your particular deployment environment and requirements.
|
|
245
252
|
|
|
246
|
-
# Redirect root to
|
|
253
|
+
# Redirect root to platform-appropriate default client app - either app or mobile.
|
|
247
254
|
location = / {
|
|
248
|
-
|
|
255
|
+
if ($is_mobile) {
|
|
256
|
+
return 302 https://$host/mobile/;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return 302 https://$host/app/;
|
|
249
260
|
}
|
|
250
261
|
|
|
251
262
|
# Static JS/CSS/etc assets not matching a more specific selector below
|
|
@@ -253,60 +264,60 @@ server {
|
|
|
253
264
|
expires $expires;
|
|
254
265
|
}
|
|
255
266
|
|
|
256
|
-
#
|
|
257
|
-
location
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
267
|
+
# Entry points for all of this project's SPWA clients
|
|
268
|
+
location ~ ^/(admin|app|mobile)/?$ {
|
|
269
|
+
# Add trailing slash if not present. Use explicit redirect w/leading https as nginx is
|
|
270
|
+
# behind a load balancer and will first redirect to http otherwise, resulting in an excess
|
|
271
|
+
# redirect with the load balancer sending the browser back to https.
|
|
272
|
+
if ($request_uri ~ ^/(admin|app|mobile)$) {
|
|
273
|
+
return 301 https://$host$uri/;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
# When at the correct path, check if the requested path exists as a file - if so, serve it.
|
|
277
|
+
# If not, serve index.html - this allows app routing to work - e.g. /admin/general/config
|
|
278
|
+
# will load /admin/index.html and allow the client app code to interpret the rest.
|
|
279
|
+
try_files $uri /$1/index.html;
|
|
263
280
|
expires $expires;
|
|
264
281
|
}
|
|
265
282
|
|
|
266
|
-
|
|
267
|
-
return 301 $uri/;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
location /app/ {
|
|
271
|
-
try_files $uri /app/index.html;
|
|
272
|
-
expires $expires;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
# Proxy to Grails back-end - appCode-tomcat is defined by Docker (e.g. via link)
|
|
283
|
+
# Proxy to Grails back-end, accessible to nginx on localhost as per container deployment.
|
|
276
284
|
location /api/ {
|
|
277
|
-
proxy_pass http://
|
|
285
|
+
proxy_pass http://localhost:8080/;
|
|
278
286
|
include includes/xh-proxy.conf;
|
|
287
|
+
include includes/xh-hardeners.conf;
|
|
279
288
|
}
|
|
280
289
|
}
|
|
281
290
|
```
|
|
282
291
|
|
|
283
292
|
**_Note that this example configuration:_**
|
|
284
293
|
|
|
285
|
-
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
294
|
+
- Uses nginx config includes sourced from the base `xh-nginx` image. The base image also copies
|
|
295
|
+
in [an overall config](https://github.com/xh/xh-nginx/blob/master/xh.conf) that enables gzip
|
|
296
|
+
compression and sets the `$expires` variable referenced above.
|
|
297
|
+
- Assumes a load balancer / ingress is handling SSL termination and that the nginx container is not
|
|
298
|
+
directly exposed to the internet. While uncommon for Hoist apps, nginx can handle SSL if needed.
|
|
299
|
+
- Sets up locations for three client-app entry points / bundles: `app`, `admin`, and `mobile`, with
|
|
300
|
+
`mobile` being a dedicated app for mobile clients. Not all apps will have these three - some might
|
|
301
|
+
lack a mobile client entirely, or ship other dedicated client apps.
|
|
302
|
+
- Uses the `try_files` directive to attempt to service requests at sub-paths by handing back asset
|
|
303
|
+
files if they exist, but otherwise falling back to `index.html` within that path. This allows for
|
|
304
|
+
the use of HTML5 “pushState” routing, where in-app routes are written to the URL without the use
|
|
305
|
+
of a traditional `#` symbol (e.g. <http://host/app/details/123>).
|
|
306
|
+
- Creates a proxy endpoint at `/api/` to pass traffic through to the Tomcat back-end, which here is
|
|
307
|
+
expected to be reachable from nginx via `localhost`.
|
|
308
|
+
- The `/api/ `path is expected by the JS client, which will automatically prepend it to the path
|
|
309
|
+
of any local/relative fetch requests. This can be customized if needed on the client by
|
|
310
|
+
adjusting the `baserUrl` param passed to `configureWebpack()`.
|
|
311
|
+
- The use of `localhost` is enabled via a deployment configuration that runs the two containers
|
|
312
|
+
on the same pod / task / workload. This will vary based on the deployment environment.
|
|
313
|
+
|
|
314
|
+
------
|
|
305
315
|
|
|
306
316
|
The build system now simply needs to copy the built client-side resources into the Docker context
|
|
307
317
|
and build the image. The sample below is simplified, but could also include the return code checks
|
|
308
|
-
in the Tomcat example above. Note the `-nginx` suffix on the container tag.
|
|
309
|
-
|
|
318
|
+
in the Tomcat example above. Note the `-nginx` suffix on the container tag.
|
|
319
|
+
|
|
320
|
+
⚠️ This example must run with `docker/nginx` as its working directory:
|
|
310
321
|
|
|
311
322
|
```bash
|
|
312
323
|
cp -R ../../client-app/build/ .
|
|
@@ -316,43 +327,40 @@ sudo docker build --pull -t "$containerTag" .
|
|
|
316
327
|
sudo docker push "$containerTag"
|
|
317
328
|
```
|
|
318
329
|
|
|
319
|
-
|
|
330
|
+
### Docker cleanup
|
|
320
331
|
|
|
321
332
|
✨ At this point the build is complete and new versioned or snapshot images containing all the
|
|
322
333
|
runtime code have been pushed to a Docker registry and are ready for deployment.
|
|
323
334
|
|
|
324
335
|
It might be beneficial to add one more step to clean up local Docker images on the build agent, to
|
|
325
336
|
avoid them continuing to grow and take up disk space indefinitely. Note this forces Docker to pull
|
|
326
|
-
the base images anew each time, which takes a small amount of time/bandwidth. It could
|
|
327
|
-
|
|
337
|
+
the base images anew each time, which takes a small amount of time/bandwidth. It could be made more
|
|
338
|
+
targeted if desired:
|
|
328
339
|
|
|
329
340
|
```bash
|
|
330
341
|
sudo docker system prune -af
|
|
331
342
|
```
|
|
332
343
|
|
|
333
|
-
|
|
344
|
+
## Docker deployment
|
|
334
345
|
|
|
335
|
-
🚢
|
|
346
|
+
🚢 XH typically creates distinct targets for build vs. deploy, and configure deployment targets to
|
|
336
347
|
prompt for the version number and/or Docker hostname. This process will differ significantly
|
|
337
348
|
depending on the use (or not) of orchestration technology such as Kubernetes or AWS Elastic
|
|
338
349
|
Container Service (ECS).
|
|
339
350
|
|
|
340
351
|
Regardless of the specific implementation, the following points should apply:
|
|
341
352
|
|
|
342
|
-
-
|
|
343
|
-
|
|
344
|
-
-
|
|
345
|
-
|
|
346
|
-
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
as required for nginx, and logs if so configured. This volume must be created in advance on the
|
|
354
|
-
host and populated with any required bootstrap files. How that’s done again will depend on the
|
|
355
|
-
particular Docker environment in play.
|
|
353
|
+
- Both `appCode-tomcat` and `appCode-nginx` containers should be deployed as a service / pair, and
|
|
354
|
+
be kept at the same version.
|
|
355
|
+
- The Tomcat container does not need to have any ports exposed/mapped onto the host (although it
|
|
356
|
+
could if direct access is desired).
|
|
357
|
+
- The nginx container typically exposes ports 80 and 443, although if a load balancer or similar is
|
|
358
|
+
also in play that might vary (and would require appropriate adjustments to the `app.conf` nginx
|
|
359
|
+
file outlined above).
|
|
360
|
+
- The nginx container must be able to reach the Tomcat container at the same name included in its
|
|
361
|
+
`app.conf` file, typically `localhost` (as in the example above).
|
|
362
|
+
- A persistent volume can be used to store logs if so configured. How that’s done again will depend
|
|
363
|
+
on the particular deployment environment and is beyond the scope of this doc.
|
|
356
364
|
|
|
357
365
|
A sample Teamcity SSH-exec runner using Docker directly:
|
|
358
366
|
|
|
@@ -384,8 +392,8 @@ sudo docker container rm $nginxName
|
|
|
384
392
|
# Pull nginx image at specified version
|
|
385
393
|
sudo docker image pull $nginxImage
|
|
386
394
|
|
|
387
|
-
# Run nginx image - link to Tomcat for proxying, expose ports, and mount local docker volume for
|
|
388
|
-
sudo docker run -d --name $nginxName --link $tomcatName:$tomcatName -p 80:80
|
|
395
|
+
# Run nginx image - link to Tomcat for proxying, expose ports, and mount local docker volume for log storage
|
|
396
|
+
sudo docker run -d --name $nginxName --link $tomcatName:$tomcatName -p 80:80 --mount type=volume,src=$appCode,dst=/$appCode --restart always $nginxImage
|
|
389
397
|
echo "Deploying $nginxImage complete"
|
|
390
398
|
|
|
391
399
|
# Prune Docker, cleaning up dangling images and avoiding disk space bloat
|
|
@@ -394,5 +402,6 @@ sudo docker system prune -af
|
|
|
394
402
|
|
|
395
403
|
------------------------------------------
|
|
396
404
|
|
|
397
|
-
|
|
398
|
-
|
|
405
|
+
☎️ info@xh.io | <https://xh.io>
|
|
406
|
+
|
|
407
|
+
Copyright © 2025 Extremely Heavy Industries Inc.
|
|
@@ -4,9 +4,18 @@ The information below applies to Hoist development generally and covers the setu
|
|
|
4
4
|
development environment for both a [Hoist Core](https://github.com/xh/toolbox) server and a Hoist
|
|
5
5
|
React client application.
|
|
6
6
|
|
|
7
|
-
[Toolbox](https://github.com/xh/toolbox) is our reference app for Hoist development
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
[Toolbox](https://github.com/xh/toolbox) is our reference app for Hoist development and can be a
|
|
8
|
+
useful project to check out and run locally to explore Hoist development. Please refer
|
|
9
|
+
to [that project's README](https://github.com/xh/toolbox/blob/develop/README.md) for additional,
|
|
10
|
+
Toolbox-specific setup info.
|
|
11
|
+
|
|
12
|
+
## tldr;
|
|
13
|
+
|
|
14
|
+
Development of Hoist applications requires:
|
|
15
|
+
|
|
16
|
+
* Git
|
|
17
|
+
* JDK 17
|
|
18
|
+
* Node (LTS or other recent) + `npm` (bundled with Node) or `yarn` (installable via `npm`)
|
|
10
19
|
|
|
11
20
|
## Git
|
|
12
21
|
|
|
@@ -16,27 +25,34 @@ via [Homebrew](https://brew.sh/).
|
|
|
16
25
|
|
|
17
26
|
## Server-side prerequisites
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
Hoist Core is the server-side plugin powering Hoist React applications.
|
|
29
|
+
See [that project's README](https://github.com/xh/hoist-core/blob/develop/README.md) for more
|
|
30
|
+
detailed information about the configuration and use of Hoist's Grails server.
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
### Java 17 JDK
|
|
33
|
+
|
|
34
|
+
The one common pre-requisite for running the server-side of a Hoist project is a Java 17 JDK. Any
|
|
35
|
+
common OpenJDK distribution should work. XH typically uses the JetBrains distro, which has
|
|
36
|
+
improved support for hot reloading, helpful for Hoist projects with a significant amount of server-
|
|
37
|
+
side development.
|
|
23
38
|
|
|
24
39
|
If using IntelliJ (see below), consider having the IDE download and update a JDK for you:
|
|
25
40
|
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
41
|
+
- From the "File > New Projects Settings" menu, open "Structure for New Projects..." If you have an
|
|
42
|
+
existing project open, you can also select "File > Project Structure" to modify that project.
|
|
43
|
+
- Select the "SDKs" option in the navigation tree.
|
|
44
|
+
- Click the + button and select "Download JDK..."
|
|
45
|
+
- Select version 17 and a distro of your choice (JetBrains Runtime is a good default).
|
|
31
46
|
|
|
32
|
-
###
|
|
47
|
+
### Server-side instance configuration
|
|
33
48
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
YAML file in place to tell your app where and how to connect to its database.
|
|
49
|
+
Before starting the server-side of a project for the first time, ensure you have copied the
|
|
50
|
+
project's `template.env` to `.env` and filled in any missing instance configuration values required
|
|
51
|
+
to provide environment-specific database connection and service account details.
|
|
38
52
|
|
|
39
|
-
|
|
53
|
+
Note that some older projects might use a YAML config file in place of `.env` - if you don't see a
|
|
54
|
+
`.env.template` file in the root of your project repo, this is likely the case. Consult another
|
|
55
|
+
developer on the project or ask XH for assistance.
|
|
40
56
|
|
|
41
57
|
## Client-side prerequisites
|
|
42
58
|
|
|
@@ -45,28 +61,26 @@ For Toolbox development, see that project's README for TB-specific database info
|
|
|
45
61
|
A recent version of Node.js is required to build and run the client-side component of the
|
|
46
62
|
application (via Webpack and webpack-dev-server).
|
|
47
63
|
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
64
|
+
- The latest (or any recent) LTS build is recommended - you can download directly from
|
|
65
|
+
https://nodejs.dev/ or use a tool (recommended) such as Homebrew or NVM (node-version-manager) to
|
|
66
|
+
install and update your local node versions.
|
|
67
|
+
- Ensure that node is on your path via `node --version`.
|
|
52
68
|
|
|
53
69
|
### Yarn
|
|
54
70
|
|
|
55
|
-
XH uses
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- The easiest way to install yarn is with npm (🤯): `npm i -g yarn`
|
|
60
|
-
- Once installed, verify it can be run globally with `yarn --version`
|
|
61
|
-
- Within the `client-app` directory of a Hoist app such as Toolbox, run `yarn` to download, install,
|
|
62
|
-
and build all client-side dependencies. (Note that `yarn` is a shortcut for `yarn install` - they
|
|
63
|
-
do the same thing.)
|
|
71
|
+
XH uses both `yarn` (v1) and `npm` (recent/lts) for JS package management - Hoist has no requirement
|
|
72
|
+
for one over the other, although `npm` has been found to work better in some corporate environments
|
|
73
|
+
with intensive workstation and/or network-level antimalware and other file scanning. The important
|
|
74
|
+
thing is to decide on one or the other for your project and ensure all developers use the same tool.
|
|
64
75
|
|
|
65
|
-
|
|
76
|
+
When using `yarn`, we typically include an updated, portable version of yarn bundled within each
|
|
77
|
+
project, but a local yarn install is still required to detect and run the portable copy:
|
|
66
78
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
- The easiest way to install yarn is with npm (🤯): `npm i -g yarn`
|
|
80
|
+
- Once installed, verify it can be run globally with `yarn --version`
|
|
81
|
+
- Within the `client-app` directory of a Hoist app such as Toolbox, run `yarn` to download, install,
|
|
82
|
+
and build all client-side dependencies. (Note that `yarn` is a shortcut for `yarn install` - they
|
|
83
|
+
do the same thing.)
|
|
70
84
|
|
|
71
85
|
## JetBrains IntelliJ
|
|
72
86
|
|
|
@@ -98,27 +112,27 @@ beyond the scope of this doc. There are a few recommended settings to highlight,
|
|
|
98
112
|
|
|
99
113
|
From within the IDE's general preferences / settings dialog:
|
|
100
114
|
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
|
|
115
|
+
- Navigate to `Languages & Frameworks > Javascript`:
|
|
116
|
+
- Ensure "ECMAScript 6+" selected in the top-level of this section.
|
|
117
|
+
- Expand `Webpack` - *if doing local Toolbox + Hoist React development*, you can choose to
|
|
118
|
+
configure "Manually" and point IntelliJ at a stub `webpack.config.intellij.js` checked-in at
|
|
119
|
+
the root of your local hoist-react project. This will cause IntelliJ to resolve any
|
|
120
|
+
auto-suggestions or context clues to the local versions of the Hoist classes and utils.
|
|
121
|
+
- Expand `Code Quality Tools > Eslint` - select "Automatic" configuration to enable eslint to
|
|
122
|
+
run and monitor your code as you update it. Note that you will need to have run `yarn` to
|
|
123
|
+
install your local client-side dependencies first.
|
|
124
|
+
- If using Prettier in your project, enable that as well in the dedicated `Prettier` section.
|
|
125
|
+
- Navigate to `Languages & Frameworks > Node.js and NPM`:
|
|
126
|
+
- Ensure the IDE has detected the version of Node you wish to use.
|
|
127
|
+
- You can also specify yarn as your package manager, if you wish to use the IDEs built-in yarn
|
|
128
|
+
integration.
|
|
129
|
+
- Navigate to `Languages & Frameworks > Stylesheets > Stylelint`:
|
|
130
|
+
- Enable with "Automatic configuration" to turn on local support for Stylelint, if using in your
|
|
131
|
+
project.
|
|
132
|
+
- Navigate to `Version Control > Git` - verify the IDE has detected your local git and select
|
|
133
|
+
"Update method: Rebase" to avoid unnecessary merge commits when updating your local repo.
|
|
134
|
+
- The GitToolBox plugin is a useful add-on to IntelliJ, with several useful enhancements to
|
|
135
|
+
version control support.
|
|
122
136
|
|
|
123
137
|
------------------------------------------
|
|
124
138
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "76.0.0-SNAPSHOT.
|
|
3
|
+
"version": "76.0.0-SNAPSHOT.1755394070476",
|
|
4
4
|
"description": "Hoist add-on for building and deploying React Applications.",
|
|
5
5
|
"repository": "github:xh/hoist-react",
|
|
6
6
|
"homepage": "https://xh.io",
|