Skip to content

Commit

Permalink
Merge pull request #6954 from alibaba/release/next
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
ClarkXia authored Jul 25, 2024
2 parents 28f670a + 2199147 commit 60e8e5d
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/plugin-i18n/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
},
"peerDependencies": {
"@ice/app": "^3.4.10",
"@ice/runtime": "^1.4.10"
"@ice/runtime": "^1.4.11"
},
"publishConfig": {
"access": "public"
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-intl/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @ice/plugin-intl

## 1.1.0

### Minor Changes

- 2626dcdc: feat: support the simple mode of intl solution

## 1.0.2

fix: compat with the navigator language return with underslash.
Expand Down
46 changes: 46 additions & 0 deletions packages/plugin-intl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,49 @@ function alertMessage() {
alert(intl.formatMessage({ id: 'app.welcome' }));
}
```

## Simple mode

Simple mode for remove the dependency of `react-intl`:

Define the plugin in `ice.config.mts`:

```ts
import { defineConfig } from '@ice/app';
import intl from '@ice/plugin-intl';

export default defineConfig({
plugins: [
// Add intlSolution to remove the dependency of react-intl
intl({ intlSolution: 'simple' }),
],
});
```

When you use the `simple` mode, you can only use the `intl.formateMessage` function to get the locale message:

```tsx
import { ice } from 'ice';

export default function Home() {
console.log(intl.formatMessage({ id: 'new' }));
return <h1>home</h1>;
}
```

Function `intl.formatMessage` is limited, you can only use the syntax below to get the locale message:

Simple Usage:

```tsx
intl.formatMessage({ id: 'app.welcome', defaultMessage: 'Welcome to my application!' });
intl.formatMessage('app.welcome');
```

With Variables:

```tsx
intl.formatMessage({ id: 'app.welcome' }, { name: 'icejs' });
```

> Caution: the message Syntax only support the pattern like `{name}`.
5 changes: 3 additions & 2 deletions packages/plugin-intl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/plugin-intl",
"version": "1.0.2",
"version": "1.1.0",
"description": "react intl plugin for ice.js 3.",
"files": [
"esm",
Expand All @@ -15,6 +15,7 @@
"exports": {
".": "./esm/index.js",
"./runtime": "./esm/runtime.js",
"./runtime-simple": "./esm/runtime-simple.js",
"./types": "./esm/types.js"
},
"sideEffects": false,
Expand All @@ -28,7 +29,7 @@
},
"devDependencies": {
"@ice/app": "^3.4.9",
"@ice/runtime": "^1.4.8",
"@ice/runtime": "^1.4.11",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0"
},
Expand Down
1 change: 1 addition & 0 deletions packages/plugin-intl/runtime-simple.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './esm/runtime-simple';
19 changes: 14 additions & 5 deletions packages/plugin-intl/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ interface PluginOptions {
localeMessagesKey?: string;
defaultLocaleKey?: string;
useCDN?: boolean;
intlSolution?: 'react-intl' | 'simple';
}

const plugin: Plugin<PluginOptions> = ({
localeMessagesKey = '__LOCALE_MESSAGES__',
defaultLocaleKey = '__DEFAULT_LOCALE__',
useCDN = false,
intlSolution = 'react-intl',
} = {}) => ({
name: 'plugin-intl',
setup: ({ generator, context, createLogger, watch }) => {
Expand Down Expand Up @@ -83,12 +85,19 @@ const plugin: Plugin<PluginOptions> = ({
}

// Add intl export from ice.
generator.addExport({
specifier: ['useIntl', 'intl'],
source: '@ice/plugin-intl/runtime',
});
if (intlSolution === 'simple') {
generator.addExport({
specifier: ['intl'],
source: '@ice/plugin-intl/runtime-simple',
});
} else {
generator.addExport({
specifier: ['useIntl', 'intl'],
source: '@ice/plugin-intl/runtime',
});
}
},
runtime: '@ice/plugin-intl/runtime',
runtime: intlSolution === 'simple' ? '@ice/plugin-intl/runtime-simple' : '@ice/plugin-intl/runtime',
});

export default plugin;
15 changes: 15 additions & 0 deletions packages/plugin-intl/src/intl-until.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const EXPORT_NAME = 'locale';

export const getDefaultLocale = () => {
// @ts-ignore
const defaultLocale = (typeof window !== 'undefined' && window.__ICE_DEFAULT_LOCALE__) ||
(typeof navigator !== 'undefined' && navigator.language) ||
'zh-CN';
return defaultLocale.replace('_', '-');
};

export const getLocaleMessages = () => {
// @ts-ignore
const localeMessages = typeof window === 'undefined' ? global.__ICE_LOCALE_MESSAGES__ : window.__ICE_LOCALE_MESSAGES__;
return localeMessages || {};
};
46 changes: 46 additions & 0 deletions packages/plugin-intl/src/runtime-simple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { RuntimePlugin } from '@ice/runtime/types';
import { getDefaultLocale, getLocaleMessages, EXPORT_NAME } from './intl-until.js';

let currentLocale = getDefaultLocale();
let localeMessages = getLocaleMessages();

const runtime: RuntimePlugin = async ({
appContext,
}) => {
const { appExport } = appContext;
const { getLocale, ...l } = appExport?.[EXPORT_NAME] || {};
if (Object.keys(l)?.length > 0) {
console.error('The locale config is not supported in the simple mode.');
}
const locale = getLocale ? getLocale() : getDefaultLocale();
currentLocale = locale;
// Refresh locale messages for server side because of import hoisting.
localeMessages = getLocaleMessages();
};

interface MessageDescriptor {
id: string;
defaultMessage?: string;
}

const intl = {
formatMessage: (message: MessageDescriptor | string, values?: Record<string, string>) => {
let messageId = typeof message === 'string' ? message : message.id;
const defaultMessage = typeof message === 'string' ? message : message.defaultMessage;
let content = localeMessages?.[currentLocale]?.[messageId];
if (!content) {
console.error(`Message with id "${messageId}" not found in locale "${currentLocale}"`);
return defaultMessage || messageId;
}
if (values) {
Object.keys(values).forEach((key) => {
content = content.replace(new RegExp(`{${key}}`, 'g'), values[key]);
});
}
return content;
},
};

export { intl };

export default runtime;
16 changes: 1 addition & 15 deletions packages/plugin-intl/src/runtime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,11 @@ import * as React from 'react';
import { createIntl, createIntlCache, RawIntlProvider, useIntl } from 'react-intl';
import type { IntlShape } from 'react-intl';
import type { RuntimePlugin } from '@ice/runtime/types';
import { getDefaultLocale, getLocaleMessages, EXPORT_NAME } from './intl-until.js';
import type { LocaleConfig } from './types.js';

const EXPORT_NAME = 'locale';
const cache = createIntlCache();

const getDefaultLocale = () => {
// @ts-ignore
const defaultLocale = (typeof window !== 'undefined' && window.__ICE_DEFAULT_LOCALE__) ||
(typeof navigator !== 'undefined' && navigator.language) ||
'zh-CN';
return defaultLocale.replace('_', '-');
};

const getLocaleMessages = () => {
// @ts-ignore
const localeMessages = typeof window === 'undefined' ? global.__ICE_LOCALE_MESSAGES__ : window.__ICE_LOCALE_MESSAGES__;
return localeMessages || {};
};

const defaultLocale = getDefaultLocale();
let intl: IntlShape = createIntl({
locale: defaultLocale,
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-jsx-plus/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 1.0.4

### Patch Changes

- aaea501d: fix: allow decorators-legacy syntax in js file

## 1.0.3

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-jsx-plus/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/plugin-jsx-plus",
"version": "1.0.3",
"version": "1.0.4",
"description": "JSX Plus support for ice.js",
"license": "MIT",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-jsx-plus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const babelTransformOptions = {
'topLevelAwait',
'classProperties',
'classPrivateMethods',
'decorators-legacy', // allowing decorators by default
],
generatorOpts: {
decoratorsBeforeExport: true,
Expand Down Expand Up @@ -107,7 +108,6 @@ const plugin: Plugin<JSXPlusOptions> = (options: JSXPlusOptions = {}) => ({
if (/\.tsx?$/.test(id)) {
// When routes file is a typescript file, add ts parser plugins.
options.parserOpts.plugins.push('typescript');
options.parserOpts.plugins.push('decorators-legacy'); // allowing decorators by default
}

const { code, map } = transformSync(source, options);
Expand Down
5 changes: 4 additions & 1 deletion packages/plugin-request/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import type { AxiosRequestConfig } from 'axios';
import { request } from './request.js';

interface RequestResult<R, P extends any[]> extends Result<R, P> {
request: (...args: P) => Promise<R>;
request: Result<R, P>['run'];
requestAsync: Result<R, P>['runAsync'];
}

export function useRequest<TData, TParams extends any[] = []>(
Expand Down Expand Up @@ -35,6 +36,8 @@ export function useRequest<TData, TParams extends any[] = []>(
...req,
// Modify ahooks' useRequest `run` as `request`
request: req.run,
// Modify ahooks' useRequest `runAsync` as `requestAsync`
requestAsync: req.runAsync,
} as RequestResult<TData, TParams>;
}

Expand Down
6 changes: 6 additions & 0 deletions packages/runtime/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @ice/runtime

## 1.4.11

### Patch Changes

- 7992d405: fix: throw error for better debugging

## 1.4.10

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/runtime",
"version": "1.4.10",
"version": "1.4.11",
"description": "Runtime module for ice.js",
"type": "module",
"types": "./esm/index.d.ts",
Expand Down
3 changes: 2 additions & 1 deletion packages/runtime/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ export async function loadRouteModule(route: RouteModule, routeModulesCache = {}
return routeModule;
} catch (error) {
console.error(`Failed to load route module: ${id}.`);
console.error(error);
// Re-throw error for better debugging.
throw error;
}
}

Expand Down
25 changes: 14 additions & 11 deletions packages/runtime/tests/routes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,20 @@ describe('routes', () => {
});

it('load error module', async () => {
const routeModule = await loadRouteModules([{
id: 'error',
// @ts-ignore
lazy: async () => {
throw new Error('err');
return {};
},
}], {});
expect(routeModule).toStrictEqual({
error: undefined,
});
// `toThrowError` seems not working with async function.
try {
await loadRouteModules([{
id: 'error',
// @ts-ignore
lazy: async () => {
throw new Error('err');
return {};
},
}], {});
expect(true).toBe(false);
} catch (err) {
expect(true).toBe(true);
}
});

it('load async route', async () => {
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 60e8e5d

Please sign in to comment.