Browse Source

走通多语言,基于浏览器环境使用对应的语言包

ddx 2 months ago
parent
commit
73bb11a367
7 changed files with 170 additions and 25 deletions
  1. 127 6
      package-lock.json
  2. 1 0
      package.json
  3. 0 17
      src/app.ts
  4. 32 0
      src/app.tsx
  5. 4 0
      src/assets/i18n/messages/en.js
  6. 4 0
      src/assets/i18n/messages/zh.js
  7. 2 2
      src/pages/index/index.tsx

+ 127 - 6
package-lock.json

@@ -28,6 +28,7 @@
         "antd-mobile": "^5.39.0",
         "react": "^18.0.0",
         "react-dom": "^18.0.0",
+        "react-intl": "^7.1.11",
         "react-router-dom": "^7.6.1"
       },
       "devDependencies": {
@@ -2485,6 +2486,72 @@
       "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
       "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="
     },
+    "node_modules/@formatjs/ecma402-abstract": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz",
+      "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==",
+      "dependencies": {
+        "@formatjs/fast-memoize": "2.2.7",
+        "@formatjs/intl-localematcher": "0.6.1",
+        "decimal.js": "^10.4.3",
+        "tslib": "^2.8.0"
+      }
+    },
+    "node_modules/@formatjs/fast-memoize": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz",
+      "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==",
+      "dependencies": {
+        "tslib": "^2.8.0"
+      }
+    },
+    "node_modules/@formatjs/icu-messageformat-parser": {
+      "version": "2.11.2",
+      "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz",
+      "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==",
+      "dependencies": {
+        "@formatjs/ecma402-abstract": "2.3.4",
+        "@formatjs/icu-skeleton-parser": "1.8.14",
+        "tslib": "^2.8.0"
+      }
+    },
+    "node_modules/@formatjs/icu-skeleton-parser": {
+      "version": "1.8.14",
+      "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz",
+      "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==",
+      "dependencies": {
+        "@formatjs/ecma402-abstract": "2.3.4",
+        "tslib": "^2.8.0"
+      }
+    },
+    "node_modules/@formatjs/intl": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-3.1.6.tgz",
+      "integrity": "sha512-tDkXnA4qpIFcDWac8CyVJq6oW8DR7W44QDUBsfXWIIJD/FYYen0QoH46W7XsVMFfPOVKkvbufjboZrrWbEfmww==",
+      "dependencies": {
+        "@formatjs/ecma402-abstract": "2.3.4",
+        "@formatjs/fast-memoize": "2.2.7",
+        "@formatjs/icu-messageformat-parser": "2.11.2",
+        "intl-messageformat": "10.7.16",
+        "tslib": "^2.8.0"
+      },
+      "peerDependencies": {
+        "typescript": "^5.6.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@formatjs/intl-localematcher": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz",
+      "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==",
+      "dependencies": {
+        "tslib": "^2.8.0"
+      }
+    },
     "node_modules/@hapi/hoek": {
       "version": "9.3.0",
       "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -4847,6 +4914,15 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/hoist-non-react-statics": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
+      "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
+      "dependencies": {
+        "@types/react": "*",
+        "hoist-non-react-statics": "^3.3.0"
+      }
+    },
     "node_modules/@types/html-minifier-terser": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -4962,8 +5038,7 @@
     "node_modules/@types/prop-types": {
       "version": "15.7.14",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
-      "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
-      "devOptional": true
+      "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ=="
     },
     "node_modules/@types/qs": {
       "version": "6.14.0",
@@ -4981,7 +5056,6 @@
       "version": "18.3.23",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
       "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
-      "devOptional": true,
       "dependencies": {
         "@types/prop-types": "*",
         "csstype": "^3.0.2"
@@ -7878,8 +7952,7 @@
     "node_modules/decimal.js": {
       "version": "10.5.0",
       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
-      "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
-      "dev": true
+      "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="
     },
     "node_modules/decode-uri-component": {
       "version": "0.4.1",
@@ -10814,6 +10887,19 @@
       "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.2.tgz",
       "integrity": "sha512-rx+pETSCJEDThm/JCm8CuadcAC410cVjb1XVXFNDKFuylaayHk1+tFxhkjvnMDAfqsJHxZXDAJ3Uc2d5xQyWlQ=="
     },
+    "node_modules/hoist-non-react-statics": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+      "dependencies": {
+        "react-is": "^16.7.0"
+      }
+    },
+    "node_modules/hoist-non-react-statics/node_modules/react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+    },
     "node_modules/hookified": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.9.0.tgz",
@@ -11325,6 +11411,17 @@
       "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz",
       "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="
     },
+    "node_modules/intl-messageformat": {
+      "version": "10.7.16",
+      "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz",
+      "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==",
+      "dependencies": {
+        "@formatjs/ecma402-abstract": "2.3.4",
+        "@formatjs/fast-memoize": "2.2.7",
+        "@formatjs/icu-messageformat-parser": "2.11.2",
+        "tslib": "^2.8.0"
+      }
+    },
     "node_modules/into-stream": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
@@ -15910,6 +16007,30 @@
       "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
       "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
     },
+    "node_modules/react-intl": {
+      "version": "7.1.11",
+      "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-7.1.11.tgz",
+      "integrity": "sha512-tnVoRCWvW5Ie2ikYSdPF7z3+880yCe/9xPmitFeRPw3RYDcCfR4m8ZYa4MBq19W4adt9Z+PQA4FaMBCJ7E+HCQ==",
+      "dependencies": {
+        "@formatjs/ecma402-abstract": "2.3.4",
+        "@formatjs/icu-messageformat-parser": "2.11.2",
+        "@formatjs/intl": "3.1.6",
+        "@types/hoist-non-react-statics": "^3.3.1",
+        "@types/react": "16 || 17 || 18 || 19",
+        "hoist-non-react-statics": "^3.3.2",
+        "intl-messageformat": "10.7.16",
+        "tslib": "^2.8.0"
+      },
+      "peerDependencies": {
+        "react": "16 || 17 || 18 || 19",
+        "typescript": "^5.6.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-is": {
       "version": "17.0.2",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -18980,7 +19101,7 @@
       "version": "5.8.3",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
       "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
-      "dev": true,
+      "devOptional": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"

+ 1 - 0
package.json

@@ -55,6 +55,7 @@
     "antd-mobile": "^5.39.0",
     "react": "^18.0.0",
     "react-dom": "^18.0.0",
+    "react-intl": "^7.1.11",
     "react-router-dom": "^7.6.1"
   },
   "devDependencies": {

+ 0 - 17
src/app.ts

@@ -1,17 +0,0 @@
-import { PropsWithChildren } from 'react'
-import { useLaunch } from '@tarojs/taro'
-
-import './app.css'
-
-function App({ children }: PropsWithChildren<any>) {
-  useLaunch(() => {
-    console.log('App launched.')
-  })
-
-  // children 是将要会渲染的页面
-  return children
-}
-  
-
-
-export default App

+ 32 - 0
src/app.tsx

@@ -0,0 +1,32 @@
+import { PropsWithChildren } from 'react'
+import { useLaunch } from '@tarojs/taro'
+import { IntlProvider } from 'react-intl';
+import { FormattedMessage } from 'react-intl';
+import './app.css'
+
+
+const locale = (window.navigator.language || 'en').toLowerCase().split('-')[0]; // Get locale from browser or default to 'en'
+const messages = require(`./assets/i18n/messages/${locale}`).default;
+
+function App({ children }: PropsWithChildren<any>) {
+  useLaunch(() => {
+    console.log('App launched.')
+  })
+
+  // children 是将要会渲染的页面
+  // return children
+  return (
+    <IntlProvider locale={locale} messages={messages}>
+      <div>
+        <FormattedMessage id="greeting" defaultMessage="Hello, world!" />
+        <br />
+        <FormattedMessage id="name" defaultMessage="John Doe" />
+        {children}
+      </div>
+    </IntlProvider>
+  );
+}
+  
+
+
+export default App

+ 4 - 0
src/assets/i18n/messages/en.js

@@ -0,0 +1,4 @@
+export default {
+  greeting: 'Hello, world!',
+  name: 'John Doe',
+};

+ 4 - 0
src/assets/i18n/messages/zh.js

@@ -0,0 +1,4 @@
+export default {
+  greeting: '你好,世界!',
+  name: '张三',
+};

+ 2 - 2
src/pages/index/index.tsx

@@ -1,6 +1,7 @@
 import { View, Text } from '@tarojs/components'
 import { useLoad } from '@tarojs/taro'
 import './index.css'
+import { FormattedMessage } from 'react-intl';
 
 export default function Index () {
   useLoad(() => {
@@ -9,8 +10,7 @@ export default function Index () {
 
   return (
     <View>
-      <View className='p-4 text-green-500'>ddd</View>
-      <Text >Hello world!7787</Text>
+      <Text ><FormattedMessage id="greeting" defaultMessage="Hello, world!" /></Text>
     </View>
   )
 }