Context - trying to understand how hawtio-online works and uses nginx and node.js/express on OpenShift.
Links:
-
/data/sources/_testing/grgr-test-web/patternfly-webpack/readme.adoc - yarn workspaces + TS + WebPack + esbuild
Started: 2024-12-05
-
Starting fresh and run
corepack use yarn
to get emptypackage.json
-
Add manually
.yarnrc.yml
:enableGlobalCache: false enableTelemetry: false nodeLinker: node-modules pnpEnableEsmLoader: false
-
git commit
Here are the levels of TS configuration:
-
webpack
+ts-loader
-
webpack
+swc-loader
(Rust-based) - 4x faster thants-loader
-
rspack
withbuiltin:swc-loader
- 10x faster thants-loader
-
spact
/swcpack
= swc without webpack
Basic usage - just with typescript
npm package in dev dependencies
$(yarn bin tsc) --init
Let’s treat the above as canonical version of tsconfig.json
.
https://www.typescriptlang.org/tsconfig is a documentation for option. Some are obvious, but some are not.
-
module
- Sets the module system for the program. You very likely wantnodenext
for modern Node.js projects andpreserve
oresnext
for code that will be bundled. - this is quite clear information. -
moduleResolution
- looks likenodenext
orbundler
are the only good choices.
Generally canonical usage of $(yarn bin tsc)
should be used only to check the types. While the actual bundler uses the (same) configuration to do its own transpiling without type checking.
Then how the emit
, declaration
, outDir
, … options work?
We can use rspack which is Rust-based, webpack-compatible bundler. Using webpack is more canonical though.
Just adding jest
dev dependency and a ts
based test gives this:
$ yarn test FAIL src/App.test.ts ● Test suite failed to run Jest encountered an unexpected token Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. By default "node_modules" folder is ignored by transformers. Here's what you can do: • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. • If you need a custom transformation specify a "transform" option in your config. • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. You'll find more details and examples of these config options in the docs: https://jestjs.io/docs/configuration For information about custom transformations, see: https://jestjs.io/docs/code-transformation Details: /data/sources/github.com/grgrzybek/hawtio-online-tests/packages/introspection-app/src/App.test.ts:16 import { describe, expect, test } from "@jest/globals"; ^^^^^^ SyntaxError: Cannot use import statement outside a module at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1505:14) Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 0.216 s Ran all test suites.
So we need jest + ts configuration.
yarn create jest@latest
creates some template jest.config.ts
file based on user input.
After initialization I needed ts-node
package.
But still:
Details: /data/sources/github.com/grgrzybek/hawtio-online-tests/packages/introspection-app/src/App.test.ts:16 import { describe, expect, test } from "@jest/globals"; ^^^^^^
https://jestjs.io/docs/getting-started#via-ts-jest points to
https://kulshekhar.github.io/ts-jest/docs/getting-started/installation/#jest-config-file which mentions yarn ts-jest config:init
which creates:
export default { testEnvironment: "node", transform: { "^.+.tsx?$": ["ts-jest",{}], }, }
And actually this was enough:
$ yarn test PASS src/App.test.ts Hawtio Online Tests ✓ Jest infra test (1 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.031 s, estimated 2 s Ran all test suites.
Hawtio Online uses nginx to serve client-side application and nginx' configuration delegates some URIs to backend application (docker/gateway) based on Node.js and express.
/etc/nginx/nginx.conf.default
and /etc/nginx/nginx.conf
are considerably different, but I want some minimal config…
Let’s prepare some structure in deploy/nginx
, try to run nginx and build minimal configuration file.
$ pwd /home/ggrzybek/sources/github.com/grgrzybek/hawtio-online-tests/deploy/nginx $ nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied) 2024/12/10 11:56:49 [warn] 47214#47214: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:5 2024/12/10 11:56:49 [emerg] 47214#47214: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
$ nginx -V 2>&1 | grep 'configure arguments' | tr ' ' '\n' configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx ...
So we need to override the above.
With empty etc/nginx.nginx.conf:
$ nginx -p $(pwd) -c etc/nginx/nginx.conf -e var/log/nginx/error.log nginx: [emerg] no "events" section in configuration
This works with nginx.conf
containing only events {}
configuration:
$ nginx -p $(pwd) -c etc/nginx/nginx.conf -e var/log/nginx/error.log -g 'pid run/nginx.pid;' $ pgrep -af nginx 49449 nginx: master process nginx -p /home/ggrzybek/sources/github.com/grgrzybek/hawtio-online-tests/deploy/nginx -c etc/nginx/nginx.conf -e var/log/nginx/error.log -g pid run/nginx.pid; 49450 nginx: worker process $ nginx -p $(pwd) -c etc/nginx/nginx.conf -e var/log/nginx/error.log -g 'pid run/nginx.pid;' -s stop $ pgrep -af nginx | wc -l 0
pid
option can be specified in config file, but -e
(error_log
) has to be specified, because it’s needed even before reading config file. Special -e stderr
can be used.
So with correct configuration it’s easiest to run:
$ nginx -p $(pwd) -c etc/nginx/nginx.conf -e stderr
Configuration can be generated using amazing https://nginxconfig.io page (https://do.nginxconfig.io, https://github.com/digitalocean/nginxconfig.io).