Files
remark42/frontend/package.json
T
Dmitry VerkhoturovandGitHub fc4e10573c Replace react-intl and remove React from the widget (#2176)
Second and final step of #2166. `react-intl` is replaced by
`app/common/intl.tsx`, a small i18n binding over Preact context, and with
`react-redux` already gone nothing holds the React compatibility alias.

React is now absent from the lockfile, the installed tree, the config and
the bundles: `react`, `react-dom`, `react-intl`, `@types/react`,
`@preact/compat`, `use-sync-external-store` and `intl-messageformat` are
all gone, along with the `paths` entries in `tsconfig.json` and three
babel-loader excludes. Runtime dependencies go from 15 to 10.

`preact/compat` goes too, which matters more than its 3.8 kB. Importing
it anywhere installs hooks on preact's shared `options` that remap
`onFocus`/`onBlur` to `focusin`/`focusout` for every element and make
`@testing-library/preact` rewrite `change` to `input`, the two bugs
behind #2166, still live until now. `Button` was wrapped in `forwardRef`
with no caller passing one, and `TextareaAutosize` now takes its ref as
an ordinary prop. The workaround in `sort-picker.spec.tsx` is gone with
them, since `fireEvent.change` reaches a `<select>` again.

Gzipped, against master: `remark.mjs` 76.17 kB to 56.47, `last-comments.mjs`
37.97 to 18.26, `deleteme.mjs` 14.51 to 8.42. The limits move with them and
keep more relative headroom than master shipped.

### The binding

`IntlProvider`, `useIntl`, `createIntl`, `defineMessages`,
`FormattedMessage` and `IntlShape`. 32 files change only their import.

The export names copy react-intl's deliberately: `formatjs extract` finds
messages by recognising `defineMessages`, `FormattedMessage` and
`intl.formatMessage` in the AST rather than by import source, so renaming
one silently empties the catalogue. `frontend/CLAUDE.md` records that,
along with the destructive part: `translation:generate` would then strip
the unextracted keys from all 24 catalogues and the check would pass.

A message the binding cannot parse falls back to the message in the
source: a broken, unhandled or nested tag, a brace that is not a
well-formed placeholder, and a placeholder naming a value the caller did
not supply. `mk.json` and `th.json` carried broken markup and rendered in
English; both are repaired, so a catalogue sweep over every locale can now
require well-formed markup with no exceptions listed.

`translation:check` gained the validation that would have caught them when
they were proposed: a translation's tags have to be well-formed pairs of the
names the English string uses, with no attributes, and its placeholders have
to be ones the English string provides. Leaving a tag or a placeholder out
stays allowed. Run against master's catalogues it reports both.

### enzyme

`@types/enzyme` was the last thing pulling `@types/react`, so React could
not leave while enzyme stayed. Its three test files move to
`@testing-library/preact`, which now has no rival: `@testing-library/preact-hooks`
had one import left and its own unmet peer warning. `intersection-observer`
was a runtime dependency nothing imported, and the `cheerio` override lost
its last dependent with enzyme.

Enzyme's `.find(X).prop()` threw unless exactly one node matched, so the
converted tests assert node counts explicitly to keep that.

### Verified

All 181 message ids formatted across all 24 catalogues through both real
react-intl and this binding: 4344 comparisons, no differences. From a wiped
`node_modules`: `pnpm install --frozen-lockfile`, `pnpm lint`,
`pnpm type-check`, `pnpm test` (392 tests, 42 suites), `pnpm build`,
`pnpm size-check`, `pnpm translation-check`.
2026-08-21 02:30:26 -05:00

92 lines
3.5 KiB
JSON

{
"name": "remark42",
"version": "0.0.0",
"description": "Frontend related code for Remark42",
"keywords": [
"remark42",
"comments",
"comment engine",
"commenting"
],
"scripts": {
"prepare": "if [ -z \"$CI\" ]; then cd .. && husky install frontend/.husky; else echo \"Skip Husky Hooks\"; fi",
"lint-staged": "lint-staged",
"dev:app": "pnpm --filter @remark42/app dev"
},
"packageManager": "pnpm@10.10.0",
"devDependencies": {
"husky": "^8.0.1",
"lint-staged": "^13.0.3"
},
"pnpm": {
"overrides": {
"decode-uri-component@<0.2.1": ">=0.2.1",
"loader-utils@>=2.0.0 <2.0.3": ">=2.0.3 <3.0.0",
"loader-utils@>=2.0.0 <2.0.4": ">=2.0.4 <3.0.0",
"json5@<1.0.2": ">=1.0.2",
"json5@>=2.0.0 <2.2.2": ">=2.2.2",
"tough-cookie@<4.1.3": ">=4.1.3",
"micromatch@<4.0.8": ">=4.0.8",
"esbuild@<=0.24.2": ">=0.25.0",
"word-wrap@<1.2.4": ">=1.2.4",
"cookie@<0.7.0": ">=0.7.0",
"@babel/runtime-corejs3@<7.26.10": ">=7.26.10 <8.0.0",
"@babel/runtime@<7.26.10": ">=7.26.10 <8.0.0",
"@babel/helpers@<7.26.10": ">=7.26.10 <8.0.0",
"cross-spawn@<6.0.6": ">=6.0.6",
"cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5",
"tmp@<=0.2.3": ">=0.2.4",
"form-data@>=4.0.0 <4.0.4": ">=4.0.4",
"nanoid@>=4.0.0 <5.0.9": ">=5.0.9",
"glob@>=10.2.0 <10.5.0": ">=10.5.0 <11.0.0",
"diff@>=4.0.0 <4.0.4": ">=4.0.4",
"semver@>=2.0.0-alpha <5.7.2": ">=5.7.2",
"semver@>=7.0.0 <7.5.2": ">=7.5.2",
"semver@>=6.0.0 <6.3.1": ">=6.3.1",
"serialize-javascript@<=7.0.2": ">=7.0.3",
"flatted@<3.4.0": ">=3.4.0",
"flatted@<=3.4.1": ">=3.4.2",
"lodash-es@>=4.0.0 <=4.17.23": ">=4.18.0",
"lodash@>=4.0.0 <=4.17.23": ">=4.18.0",
"lodash-es@<=4.17.23": ">=4.18.0",
"lodash@<=4.17.23": ">=4.18.0",
"serialize-javascript@>=6.0.0 <6.0.2": ">=6.0.2",
"@xmldom/xmldom@<0.8.12": ">=0.8.12",
"@babel/traverse@<7.23.2": ">=7.23.2 <8.0.0",
"@xmldom/xmldom@<0.8.13": ">=0.8.13",
"@tootallnate/once@<2.0.1": ">=2.0.1",
"serialize-javascript@>=5.0.0 <7.0.5": ">=7.0.5",
"uuid@<11.1.1": ">=11.1.1",
"@babel/plugin-transform-modules-systemjs@>=7.12.0 <=7.29.3": ">=7.29.4 <8.0.0",
"lodash@>=4.0.0 <=4.17.22": ">=4.17.23",
"shell-quote@>=1.1.0 <=1.8.3": ">=1.8.4",
"tmp@<0.2.6": ">=0.2.6",
"form-data@>=4.0.0 <4.0.6": ">=4.0.6",
"launch-editor@<=2.14.0": ">=2.14.1",
"@babel/core@<=7.29.0": ">=7.29.6 <8.0.0",
"webpack-dev-server@<5.2.6": ">=5.2.6 <6.0.0",
"http-proxy-middleware@>=0.16.0 <2.0.10": ">=2.0.10",
"yaml@>=1.0.0 <2.0.0": ">=1.10.3 <2.0.0",
"yaml@>=2.0.0 <3.0.0": ">=2.9.0 <3.0.0",
"js-yaml@>=3.0.0 <4.0.0": ">=3.15.1 <4.0.0",
"js-yaml@>=4.0.0 <5.0.0": ">=5.2.2 <6.0.0",
"minimatch@>=3.0.0 <4.0.0": ">=3.1.3 <4.0.0",
"minimatch@>=9.0.0 <10.0.0": ">=9.0.7 <10.0.0",
"ajv@>=8.0.0 <9.0.0": ">=8.18.0 <9.0.0",
"ws@>=7.0.0 <8.0.0": ">=7.5.11 <8.0.0",
"ws@>=8.0.0 <9.0.0": ">=8.21.0 <9.0.0",
"brace-expansion@>=1.0.0 <2.0.0": ">=1.1.18 <2.0.0",
"brace-expansion@>=2.0.0 <3.0.0": ">=2.0.2 <3.0.0",
"brace-expansion@>=4.0.0 <6.0.0": ">=5.0.9 <6.0.0",
"fast-uri": ">=4.1.2 <5.0.0",
"nanoid@>=3.0.0 <4.0.0": ">=3.3.18 <4.0.0",
"postcss@<8.5.23": ">=8.5.23 <9.0.0",
"svgo": ">=4.0.2 <5.0.0",
"undici@>=7.0.0 <8.0.0": ">=7.29.0 <8.0.0",
"body-parser@<1.20.6": ">=1.20.6 <2.0.0",
"preact": "10.29.8",
"@types/minimatch": "5.1.2"
}
}
}