@xh/hoist 76.0.0-SNAPSHOT.1755386207928 → 76.0.0-SNAPSHOT.1755397026376

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.
@@ -9,16 +9,17 @@ at the build process.
9
9
 
10
10
  **_At a high level, the build process:_**
11
11
 
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.
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
- ### 1\) Setup/Prep
33
+ ## Setup/Prep
33
34
 
34
- #### 1.1) Refresh and Lint JS Client
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
- #### 1.2) Set Gradle project name (optional)
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
- ### 2\) Server and Client Builds
78
+ ## Server and Client Builds
77
79
 
78
- #### 2.1) Build Grails server WAR with Gradle
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
- - `xhAppVersion` - an x.y.z version for releases, or `x.y-SNAPSHOT` for transient builds.
87
- - `xhAppBuild` - this is an optional arg that gets baked into the server and client and exposed as a
88
- variable for display in the built-in Hoist admin client. We use it to pass a git commit hash,
89
- which then provides another way to cross-reference exactly what snapshot of the codebase was used
90
- to build any given running application.
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
- #### 2.2) Build JS Client with Webpack
113
+ ### Build TS Client with Webpack
112
114
 
113
- This step builds all the client-side assets (JS/CSS/static resources) with Webpack, taking the
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. We use `yarn` as our package manager / runner tool.
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. The appVersion and appBuild params, detailed above, are
122
- the most common options passed in at build-time.
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
- ### 3\) Docker images
144
+ ## Docker Container images
140
145
 
141
- 🐳 The primary outputs of the overall build process are a pair of Docker containers, one for the
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
- #### 3.1) Build and Publish Tomcat Docker image
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
- FROM xhio/xh-tomcat:latest
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
- The `setenv.sh` referenced here can also be checked in with the app project and used to set
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
- All this means that a `/docker/tomcat/setenv.sh` typically looks like:
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 -Dio.xh.hoist.instanceConfigFile=/appCode/conf.yml"
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
- #### 3.2) Build and Publish nginx Docker image
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
- FROM xhio/xh-nginx:latest
213
- COPY app.conf $/XH_NGINX_CONFIG_PATH/
214
- COPY build/ $/XH_NGINX_CONTENT_PATH/
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 `$XH` environment variables are set for convenience within the `xh-nginx` base image
225
+ Note that the `$XH_` environment variables are set for convenience within the `xh-nginx` base image
218
226
  Dockerfile.
219
227
 
220
- The `app.conf` referenced here is an app-specific nginx configuration that should be checked in
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
- configure SSL certificates if needed, do any required redirects, and (importantly) include a _proxy
223
- configuration_ to pass traffic through from the nginx container to the Tomcat container. Hoist
224
- deploys typically bind only the nginx ports to the host machine, then link the nginx and Tomcat
225
- containers together via Docker so there’s a single point of entry (nginx) for incoming requests.
226
- This means that no CORS or further, external proxy configuration is required to have the
227
- nginx-dosted client communicate with its Tomcat back-end.
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
- include includes/xh-secure-redirect.conf;
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
- ssl_certificate /appCode/ssl/appCode.crt;
244
- ssl_certificate_key /appCode/ssl/appCode.pem;
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 /app/
253
+ # Redirect root to platform-appropriate default client app - either app or mobile.
247
254
  location = / {
248
- return 301 $scheme://$host/app/;
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
- # App entry points - ensure trailing slash, match or fallback to index for sub-routes
257
- location = /admin {
258
- return 301 $uri/;
259
- }
260
-
261
- location /admin/ {
262
- try_files $uri /admin/index.html;
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
- location = /app {
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://appCode-tomcat:8080/;
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
- - Uses `appCode` as a placeholder - use the same code as configured in the app’s server and client
286
- builds!
287
- - Calls several optional nginx config includes, sourced from the base `xh-nginx` image. The base
288
- image also copies in [an overall config](https://github.com/xh/xh-nginx/blob/master/xh.conf) that
289
- enables gzip compression and sets the `$expires` variable referenced above.
290
- - Redirects insecure requests to HTTPS on port 443 and terminates SSL itself, using certificates
291
- sourced from `/appCode/ssl` - the conventional location for Hoist apps to store certs and keys
292
- within an attached Docker volume.
293
- - Sets up locations for each client-app entry point / bundle - here we are shipping two JS apps with
294
- this container: `app` - the business-user facing app itself - and `admin` - the built-in Hoist
295
- Admin console. Apps might have other entry points, such as `mobile` or other more specific
296
- bundles.
297
- - Uses the `try_files` directive to attempt to service requests at sub-paths by handing back asset
298
- files if they exist, but otherwise falling back to `index.html` within that path. This allows for
299
- the use of HTML5 “pushState” routing, where in-app routes are written to the URL without the use
300
- of a traditional `#` symbol (e.g. <http://host/app/details/123>).
301
- - Creates a proxy endpoint at `/api/` to pass traffic through to the Tomcat back-end. This path is
302
- expected by the JS client, which will automatically prepend it to the path of any local/relative
303
- Ajax requests. This can be customized if needed on the client by adjusting the `baserUrl` param
304
- passed to `configureWebpack()`.
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. ⚠️ This example must
309
- also run with `docker/nginx` as its working directory:
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
- #### 3.3) Docker cleanup
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 probably be
327
- made more targeted if desired:
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
- ### 4\) Docker deployment
344
+ ## Docker deployment
334
345
 
335
- 🚢 We typically setup distinct targets for build vs. deploy, and configure deployment targets to
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
- - Both `appCode-tomcat` and `appCode-nginx` containers should be deployed as a service / pair, and
343
- be kept at the same version.
344
- - The Tomcat container does not need to have any ports exposed/mapped onto the host (although it
345
- could if direct access is desired).
346
- - The nginx container typically exposes ports 80 and 443, although if a load balancer or similar is
347
- also in play that might vary (and would require appropriate adjustments to the `app.conf` nginx
348
- file outlined above).
349
- - The nginx container must be able to reach the Tomcat container at the same name included in its
350
- `app.conf` file - by convention, it expects to use `appCode-tomcat`. With straight Docker, this
351
- can be accomplished via the `--link` option (see below).
352
- - A shared volume can be used to host the instance config .yml file for the Grails server, SSL certs
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 SSL certificate access
388
- sudo docker run -d --name $nginxName --link $tomcatName:$tomcatName -p 80:80 -p 443:443 --mount type=volume,src=$appCode,dst=/$appCode --restart always $nginxImage
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
- 📫☎️🌎 info@xh.io | https://xh.io/contact
398
- Copyright © 2025 Extremely Heavy Industries Inc. - all rights reserved
405
+ ☎️ info@xh.io | <https://xh.io>
406
+
407
+ Copyright © 2025 Extremely Heavy Industries Inc.
@@ -14,24 +14,24 @@ so those projects can continue to stay on the most recent versions of Hoist.
14
14
 
15
15
  ## Essential Updates
16
16
 
17
- - Update to the latest `hoist-react` and `hoist-dev-utils` versions within your
18
- app's `package.json`.
19
- - Add `typescript` as a devDependency.
20
- - Use the major/minor version specified
21
- by [Hoist's own dependencies](https://github.com/xh/hoist-react/blob/develop/package.json).
22
- - We recommend using the `~` semver qualifier to allow auto-updates to newer patch releases
23
- only, e.g. `~4.9.5`.
24
- - Add a `tsconfig.json` file to your project's `/client-app` directory, right alongside your
25
- existing `package.json`.
26
- - Consult
27
- the [file included by Toolbox](https://github.com/xh/toolbox/blob/develop/client-app/tsconfig.json).
28
- - The settings will likely be the same as those required by your project, with the one exception
29
- of the `paths` entry in the Toolbox file. That supports developing hoist-react itself,
30
- alongside
31
- the application, and should be omitted from standard application projects.
32
- - Review and update to the "Breaking Changes" listed within
33
- Hoist's [CHANGELOG](https://github.com/xh/hoist-react/blob/develop/CHANGELOG.md) for the Hoist TS
34
- release and any other Hoist releases you are taking into your application with this update.
17
+ - Update to the latest `hoist-react` and `hoist-dev-utils` versions within your
18
+ app's `package.json`.
19
+ - Add `typescript` as a devDependency.
20
+ - Use the major/minor version specified
21
+ by [Hoist's own dependencies](https://github.com/xh/hoist-react/blob/develop/package.json).
22
+ - We recommend using the `~` semver qualifier to allow auto-updates to newer patch releases
23
+ only, e.g. `~4.9.5`.
24
+ - Add a `tsconfig.json` file to your project's `/client-app` directory, right alongside your
25
+ existing `package.json`.
26
+ - Consult
27
+ the [file included by Toolbox](https://github.com/xh/toolbox/blob/develop/client-app/tsconfig.json).
28
+ - The settings will likely be the same as those required by your project, with the one exception
29
+ of the `paths` entry in the Toolbox file. That supports developing hoist-react itself,
30
+ alongside
31
+ the application, and should be omitted from standard application projects.
32
+ - Review and update to the "Breaking Changes" listed within
33
+ Hoist's [CHANGELOG](https://github.com/xh/hoist-react/blob/develop/CHANGELOG.md) for the Hoist TS
34
+ release and any other Hoist releases you are taking into your application with this update.
35
35
 
36
36
  This should be a good checkpoint at which to run your application. Even without converting any app
37
37
  files to TS, you should be able to successfully compile and run - after adjusting for any of the
@@ -46,27 +46,27 @@ browsing through your application with the developer console open.
46
46
 
47
47
  The following deprecations will be common, but should be easy to adjust for:
48
48
 
49
- - Use of `modelConfig` vs. `model` when passing a model configuration as a component prop in the
50
- form of a plain-object. A case-sensitive search for `model: {` within your client source should
51
- provide a good starting point. Common with `Panel` models, as those are often specified inline.
52
- - Columns will now warn if they are passed unknown configuration keys - previously this was allowed,
53
- with any extra keys spread onto the Column instance as a way for apps to carry around some extra
54
- data. Use the new dedicated `Column.appData` config instead.
49
+ - Use of `modelConfig` vs. `model` when passing a model configuration as a component prop in the
50
+ form of a plain-object. A case-sensitive search for `model: {` within your client source should
51
+ provide a good starting point. Common with `Panel` models, as those are often specified inline.
52
+ - Columns will now warn if they are passed unknown configuration keys - previously this was allowed,
53
+ with any extra keys spread onto the Column instance as a way for apps to carry around some extra
54
+ data. Use the new dedicated `Column.appData` config instead.
55
55
 
56
56
  ## IDE / Tooling
57
57
 
58
58
  If using IntelliJ, ensure that your settings are configured correctly to get the most of out TS:
59
59
 
60
- - Under "Languages & Frameworks > JavaScript", ensure that your ESLint and (if enabled) Prettier
61
- configs include the `.ts` file extension.
62
- - Under "Languages & Frameworks > TypeScript", ensure that the IDE has picked up the TS distribution
63
- from your app's `node_modules` and that the TypeScript language service is enabled.
64
- - We recommend checking "show project errors" while leaving "recompile on changes" unchecked.
65
- - IntelliJ maintains distinct code style settings for JS vs. TS. You will likely want to review your
66
- TS code style settings and get in sync.
67
- - Consider
68
- copying [the Hoist project's `.editorconfig` file](https://github.com/xh/hoist-react/blob/develop/.editorconfig)
69
- into your project to apply XH-standardized settings automatically.
60
+ - Under "Languages & Frameworks > JavaScript", ensure that your ESLint and (if enabled) Prettier
61
+ configs include the `.ts` file extension.
62
+ - Under "Languages & Frameworks > TypeScript", ensure that the IDE has picked up the TS distribution
63
+ from your app's `node_modules` and that the TypeScript language service is enabled.
64
+ - We recommend checking "show project errors" while leaving "recompile on changes" unchecked.
65
+ - IntelliJ maintains distinct code style settings for JS vs. TS. You will likely want to review your
66
+ TS code style settings and get in sync.
67
+ - Consider
68
+ copying [Hoist React's .editorconfig](https://github.com/xh/hoist-react/blob/develop/.editorconfig)
69
+ into your project to apply XH-standardized settings automatically.
70
70
 
71
71
  If using Husky in your project for git hooks, consider adding `yarn run tsc` to your `pre-commit`
72
72
  check. Note that for `tsc` to run successfully, you will need to have _at least one_ TypeScript file
@@ -82,12 +82,12 @@ balancing the update with application/project priorities.
82
82
 
83
83
  This process boils down to:
84
84
 
85
- - Selecting a file or package to migrate.
86
- - Renaming all files within from `.js -> .ts` (and `.jsx -> .tsx` if you are using JSX).
87
- - Be sure to also rename any `index.js` files you might be using for imports within a given package.
88
- - Fixing any immediate TS compilation errors in the newly renamed files. The IDE or Webpack build
89
- should flag them, and you can also run `yarn tsc` to compile directly and review any warnings.
90
- - Begin strategically adding types within each file, focusing on public properties and APIs.
85
+ - Selecting a file or package to migrate.
86
+ - Renaming all files within from `.js -> .ts` (and `.jsx -> .tsx` if you are using JSX).
87
+ - Be sure to also rename any `index.js` files you might be using for imports within a given package.
88
+ - Fixing any immediate TS compilation errors in the newly renamed files. The IDE or Webpack build
89
+ should flag them, and you can also run `yarn tsc` to compile directly and review any warnings.
90
+ - Begin strategically adding types within each file, focusing on public properties and APIs.
91
91
 
92
92
  ### Bootstrap.ts + Service Declarations
93
93
 
@@ -98,9 +98,7 @@ rename with a `.ts` extension to ensure you have at least one TS file in your bu
98
98
  In that same file, add a declaration statement to let TS know about any of your application
99
99
  services (`HoistService` instances) that you are initializing. Those are installed on and referenced
100
100
  from the `XH` object; for TS to consider references to those services valid, it needs to know that
101
- the type of the `XH` singleton (`XHApi`) has a property for each of your services. For users of
102
- IntelliJ, an ignored re-declaration of the XH singleton with this interface helps the IDE properly
103
- notice uses of these services.
101
+ the type of the `XH` singleton (`XHApi`) has a property for each of your services.
104
102
 
105
103
  In Toolbox, we have the following within `Bootstrap.ts` to declare five TB-specific services (your
106
104
  services will vary of course) and a custom property installed on `HoistUser`, the type returned
@@ -116,8 +114,6 @@ declare module '@xh/hoist/core' {
116
114
  portfolioService: PortfolioService;
117
115
  taskService: TaskService;
118
116
  }
119
- // @ts-ignore - Help IntelliJ recognize uses of injected service methods from the `XH` singleton.
120
- export const XH: XHApi;
121
117
 
122
118
  export interface HoistUser {
123
119
  profilePicUrl: string;
@@ -149,15 +145,16 @@ The pace and completeness with which you migrate the rest of your app's codebase
149
145
  Consider prioritizing packages in an order similar to the below to get the most benefit early on
150
146
  from your TS upgrade:
151
147
 
152
- - _Services_ - often centralized business logic accessed from multiple parts of the app, a great
153
- candidate for typed functions and public properties.
154
- - _POJOs_ - if your app maintains any classes for data modeling, consider typing their public
155
- properties and any public instance methods.
156
- - _Utils_ - shared, app specific utility functions are good candidates for typing, with callers
157
- benefiting from typed parameters and return signatures.
158
- - _Models & Components_ - the bulk of your client-side codebase...
148
+ - _Services_ - often centralized business logic accessed from multiple parts of the app, a great
149
+ candidate for typed functions and public properties.
150
+ - _POJOs_ - if your app maintains any classes for data modeling, consider typing their public
151
+ properties and any public instance methods.
152
+ - _Utils_ - shared, app specific utility functions are good candidates for typing, with callers
153
+ benefiting from typed parameters and return signatures.
154
+ - _Models & Components_ - the bulk of your client-side codebase...
159
155
 
160
156
  ------------------------------------------
161
157
 
162
- 📫☎️🌎 info@xh.io | https://xh.io/contact
163
- Copyright © 2025 Extremely Heavy Industries Inc. - all rights reserved
158
+ ☎️ info@xh.io | <https://xh.io>
159
+
160
+ Copyright © 2025 Extremely Heavy Industries Inc.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "76.0.0-SNAPSHOT.1755386207928",
3
+ "version": "76.0.0-SNAPSHOT.1755397026376",
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",