Skip to content

Commit 0a6ca3f

Browse files
authored
feat: expose a core bundle w/o parser (#1358)
1 parent 61b536b commit 0a6ca3f

23 files changed

+238
-144
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ src/en.js
99
.idea/
1010

1111
# VS Code
12-
.vscode
12+
.vscode
13+
14+
core.js
15+
core.d.ts

core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/core';

docs/API.md

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ There are a few API layers that React Intl provides and is built on. When using
2323
- [Message Syntax](#message-syntax)
2424
- [Message Descriptor](#message-descriptor)
2525
- [Message Formatting Fallbacks](#message-formatting-fallbacks)
26-
- [Advanced Usage](#advanced-usage)
2726
- [`formatMessage`](#formatmessage)
2827
- [`formatHTMLMessage`](#formathtmlmessage)
2928
- [React Intl Components](#react-intl-components)
29+
- [Advanced Usage](#advanced-usage)
30+
- [Core `react-intl`](#core-react-intl)
31+
- [Caveats](#caveats)
3032

3133
<!-- tocstop -->
3234

@@ -412,30 +414,6 @@ The message formatting APIs go the extra mile to provide fallbacks for the commo
412414

413415
Above, "source" refers to using the template as is, without any substitutions made.
414416

415-
#### Advanced Usage
416-
417-
For scenarios where performance is needed, you can pass in `messages` that contains `intl-messageformat`'s `AST` as values to `IntlProvider` to save compilation time when formatting messages. This is especially useful for:
418-
419-
1. Server-side rendering where you can cache the AST and don't have to pay compilation costs multiple time.
420-
2. Desktop apps using Electron or CEF where you can preload/precompile things in advanced before runtime.
421-
422-
Example:
423-
424-
```tsx
425-
import parser from 'intl-messageformat-parser';
426-
import * as ReactDOM from 'react-dom';
427-
const messages = {
428-
ast_simple: parser.parse('hello world'),
429-
ast_var: parser.parse('hello world, {name}'),
430-
};
431-
432-
ReactDOM.render(
433-
<IntlProvider messages={messages}>
434-
<FormattedMessage id="ast_simple" />
435-
</IntlProvider>
436-
); // will render `hello world`
437-
```
438-
439417
#### `formatMessage`
440418

441419
```js
@@ -483,3 +461,48 @@ The React components provided by React Intl allow for a declarative, idiomatic-R
483461
**See:** The [Components][components] page.
484462

485463
[components]: Components.md
464+
465+
## Advanced Usage
466+
467+
### Core `react-intl`
468+
469+
We've also provided a core package that has the same API as the full `react-intl` package but without our parser. What this means is that you would have to pre-parse all messages into `AST` using [`intl-messageformat-parser`](https://www.npmjs.com/package/intl-messageformat-parser) and pass that into `IntlProvider`.
470+
471+
This is especially faster since it saves us time parsing `string` into `AST`. The use cases for this support are:
472+
473+
1. Server-side rendering or pre-parsing where you can cache the AST and don't have to pay compilation costs multiple time.
474+
2. Desktop apps using Electron or CEF where you can preload/precompile things in advanced before runtime.
475+
476+
Example:
477+
478+
```tsx
479+
// Pre-processed
480+
import parser from 'intl-messageformat-parser';
481+
const messages = {
482+
ast_simple: parser.parse('hello world'),
483+
ast_var: parser.parse('hello world, {name}'),
484+
};
485+
486+
// During runtime
487+
// ES6 import
488+
import {IntlProvider, FormattedMessage} from 'react-intl/core';
489+
import * as ReactDOM from 'react-dom';
490+
491+
ReactDOM.render(
492+
<IntlProvider messages={messages}>
493+
<FormattedMessage id="ast_simple" />
494+
</IntlProvider>
495+
); // will render `hello world`
496+
```
497+
498+
The package size is also roughly 30% smaller:
499+
500+
| Package | Minified Size | Minzipped Size |
501+
| ----------------- | ------------- | -------------- |
502+
| `react-intl` | `29K` | `9.07K` |
503+
| `react-intl.core` | `19K` | `6.32K` |
504+
505+
#### Caveats
506+
507+
- Since this approach uses `AST` as the data source, changes to `intl-messageformat-parser`'s `AST` will require cache invalidation
508+
- `AST` is also larger in size than regular `string` messages but can be efficiently compressed

jest.config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
module.exports = {
22
preset: 'ts-jest/presets/js-with-babel',
3-
testRegex: ['/test/functional/.*\\.(js|ts)', '/test/unit/.*\\.(js|ts)'],
3+
testRegex: ['/test/(functional|unit)/.*\\.(ts|tsx)'],
44
testPathIgnorePatterns: ['test/functional/support', '/test/unit/testUtils'],
5-
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
5+
collectCoverageFrom: ['src/**/*.{ts,tsx}'],
66
coverageReporters: ['lcov', 'text', 'text-summary', 'html'],
7+
transformIgnorePatterns: [
8+
'/node_modules/(?!intl-messageformat|intl-messageformat-parser).+\\.js$',
9+
],
710
coverageThreshold: {
811
global: {
912
branches: 85,

package-lock.json

Lines changed: 31 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@
3636
"react": "global:React"
3737
},
3838
"dependencies": {
39-
"@formatjs/intl-relativetimeformat": "^2.3.3",
39+
"@formatjs/intl-relativetimeformat": "^2.3.4",
4040
"@types/hoist-non-react-statics": "^3.3.1",
4141
"@types/invariant": "^2.2.30",
4242
"@types/react": "^16.8.23",
4343
"hoist-non-react-statics": "^3.3.0",
44-
"intl-format-cache": "^4.0.0",
45-
"intl-locales-supported": "^1.3.3",
46-
"intl-messageformat-parser": "^2.0.0",
47-
"intl-messageformat": "^5.0.0",
44+
"intl-format-cache": "^4.0.1",
45+
"intl-locales-supported": "^1.3.4",
46+
"intl-messageformat": "^5.0.1",
47+
"intl-messageformat-parser": "^2.0.1",
4848
"invariant": "^2.1.1",
4949
"react": "^16.3.0",
5050
"shallow-equal": "^1.1.0"
@@ -54,10 +54,10 @@
5454
"@babel/core": "^7.5.0",
5555
"@babel/node": "^7.5.0",
5656
"@babel/plugin-proposal-class-properties": "^7.5.0",
57-
"@babel/plugin-proposal-object-rest-spread": "^7.5.2",
57+
"@babel/plugin-proposal-object-rest-spread": "^7.5.3",
5858
"@babel/plugin-transform-async-to-generator": "^7.5.0",
5959
"@babel/plugin-transform-modules-commonjs": "^7.5.0",
60-
"@babel/preset-env": "^7.5.2",
60+
"@babel/preset-env": "^7.5.3",
6161
"@babel/preset-react": "^7.0.0",
6262
"@types/benchmark": "^1.0.31",
6363
"@types/enzyme": "^3.10.1",
@@ -67,7 +67,7 @@
6767
"@typescript-eslint/eslint-plugin": "^1.10.2",
6868
"@typescript-eslint/parser": "^1.10.2",
6969
"babel-jest": "^24.8.0",
70-
"babel-plugin-react-intl": "^4.0.0",
70+
"babel-plugin-react-intl": "^4.0.1",
7171
"babel-plugin-transform-member-expression-literals": "^6.9.4",
7272
"babel-plugin-transform-property-literals": "^6.9.4",
7373
"babel-plugin-transform-react-remove-prop-types": "^0.4.18",
@@ -96,7 +96,7 @@
9696
"prop-types": "^15.7.2",
9797
"react-dom": "^16.8.6",
9898
"rimraf": "^2.4.2",
99-
"rollup": "^1.16.6",
99+
"rollup": "^1.16.7",
100100
"rollup-plugin-commonjs": "^10.0.1",
101101
"rollup-plugin-node-resolve": "^5.2.0",
102102
"rollup-plugin-replace": "^2.0.0",
@@ -112,13 +112,13 @@
112112
"watchify": "^3.7.0"
113113
},
114114
"scripts": {
115-
"benchmark": "NODE_ENV=production TS_NODE_PROJECT='test/perf/tsconfig.json' ts-node test/perf/index.tsx",
115+
"benchmark": "NODE_ENV=production TS_NODE_PROJECT='./tsconfig.cjs.json' ts-node test/perf/index.tsx",
116116
"build:dist:dev": "cross-env NODE_ENV=development rollup -c rollup.config.dist.js",
117117
"build:dist:prod": "cross-env NODE_ENV=production rollup -c rollup.config.dist.js",
118118
"build:dist": "npm run build:dist:dev && npm run build:dist:prod",
119-
"build:lib": "tsc && tsc -p tsconfig.cjs.json",
119+
"build:lib": "tsc -p src/tsconfig.json && tsc -p src/tsconfig.cjs.json && tsc -p tsconfig.core.json",
120120
"build": "npm run build:lib && npm run build:dist",
121-
"clean": "rimraf src/en.js coverage/ dist/ lib/ test/renderer.js",
121+
"clean": "rimraf coverage/ dist/ lib/ core.js core.d.ts",
122122
"examples:install": "babel-node scripts/examples npm install",
123123
"examples:link": "npm link && babel-node scripts/examples npm link react-intl",
124124
"format:fix": "prettier --write '**/*.{js,md,jsx,ts,tsx}'",

0 commit comments

Comments
 (0)