Я следую руководству здесь, чтобы настроить автоматическую генерацию идентификаторов для компонентов FormattedMessage в IntlProvider, но, похоже, он не вводит идентификаторы во время выполнения, так как я получаю эту ошибку в консоли.
An `id` must be provided to format a message. You can either:
1. Configure your build toolchain with [babel-plugin-formatjs](https://formatjs.io/docs/tooling/babel-plugin)
or [@formatjs/ts-transformer](https://formatjs.io/docs/tooling/ts-transformer)
Я начал с нового реагирующего приложения из create-react-app и добавил оттуда react-intl, следуя инструкциям по установке на сайте formatjs.io.
Babel.config.json
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"ast": true
}
]
]
}
пакет.json
{
"name": "react-intl-test",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/node": "^16.18.23",
"@types/react": "^18.0.35",
"@types/react-dom": "^18.0.11",
"babel-plugin-formatjs": "^10.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^6.3.2",
"react-scripts": "5.0.1",
"typescript": "^4.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"extract": "formatjs extract src/**/*.ts* --ignore=**/*.d.ts --out-file lang/en-US.json --id-interpolation-pattern [sha512:contenthash:base64:6]",
"compile": "formatjs compile lang/en-US.json --ast --out-file src/compiled-lang/en-US.json",
},
"eslintConfig": {
"extends": "react-app",
"plugins": [
"formatjs"
],
"rules": {
"formatjs/no-offset": "error"
}
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.21.4",
"@formatjs/cli": "^6.0.4",
"babel-plugin-formatjs": "^10.4.0",
"eslint": "^8.38.0",
"eslint-plugin-formatjs": "^4.9.1"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": [
"src"
]
}
App.tsx
import React from 'react';
import './App.css';
import { FormattedMessage } from 'react-intl';
function App() {
return (
<div className = "App">
hello <FormattedMessage description = "other part of hello world" defaultMessage='world'></FormattedMessage>
</div>
);
}
export default App;
en-US.json
{
"Oup1TP": [
{
"type": 0,
"value": "world"
}
]
}
Я могу включить правило lint EnforceId, и оно ищет тот же идентификатор, который загружается из файла en-US.json.
Я перепробовал множество вариантов правил eslint, переключился на файл .babelrc, изменил хэш. Если я вручную ввожу идентификатор в отформатированное сообщение или помещаю идентификатор из скомпилированного файла, приложение работает нормально.
Насколько я понимаю, компоненты FormattedMessage в IntlProvider с этой настройкой должны иметь идентификатор, введенный при запуске. Я основываю это на документации, в которой рекомендуется не добавлять идентификаторы вручную в пользу автоматической генерации, и на этой резервной логике, указанной в документации.
Я подозреваю, что проблема в том, как настроен create-react-app
. Все инструменты предварительно настроены. Я не думаю, что вы можете просто установить Babel-плагины. Вам нужно npm запустить eject, чтобы иметь возможность их использовать.
Спасибо за совет. Используя CRACO, create-react-app-rewired и vite, все отлично работает из коробки. CRA, похоже, не запускает плагины Babel. Я сделал образцы приложений с помощью Vite и Rewired, которые работают по умолчанию без дополнительной настройки. github.com/newnewz/react-intl-vite-test github.com/newnewz/react-intl-test