@quintoandar/react-intl-v2-to-v4
v1.0.0
Published
Codemods to upgrade react-intl from v2 to v4
Downloads
5
Readme
Upgrade react-intl
from v2 to v4
Codemods to migrate react-intl from v2 to v4.
Never heard of codemods? Here is a quick summary from facebook/codemod:
codemod is a tool/library to assist you with large-scale codebase refactors that can be partially automated but still require human oversight and occasional intervention.
How to use
# installing globally
npm install -g @quintoandar/react-intl-v2-to-v4
# starting the interactive prompt
react-intl-v2-to-v4
# running a specific transform with glob and custom options
react-intl-v2-to-v4 'src/**/*.test.js' migrateGetChildContext --dry
# passing jscodeshift options
# learn more at https://github.com/facebook/jscodeshift#usage-cli
react-intl-v2-to-v4 . migrateIntlShape --jscodeshift="--run-in-band"
# passing recast options
# useful for formatting configuration (tab size, quotes, trailing comma etc.)
# learn more at https://github.com/benjamn/recast/blob/822b013218a583c555bcf754beddfc52371b4a58/lib/options.ts
react-intl-v2-to-v4 . migrateIntlShape --jscodeshift="--printOptions='{\"quote\":\"double\"}'"
# or using npx
npx @quintoandar/react-intl-v2-to-v4
Use react-intl-v2-to-v4 --help
to see the CLI commands or refer to the help file.
Features
Migrate intlShape
prop type (migrateIntlShape
)
Remove the deprecated intlShape
import and replace its occurrences with PropType.object
.
It automatically adds import PropTypes from 'prop-types'
if necessary.
import React from 'react';
+ import PropTypes from 'prop-types';
- import { injectIntl, intlShape } from 'react-intl';
+ import { injectIntl } from 'react-intl';
// ...
Component.propTypes = {
foo: PropTypes.bool,
- intl: intlShape.isRequired,
+ intl: PropTypes.object.isRequired,
};
Note: if you are using named imports from prop-types
, you will get a duplicate import
import React from 'react';
import { bool, string } from 'prop-types';
+ import PropTypes from 'prop-types';
- import { injectIntl, intlShape } from 'react-intl';
+ import { injectIntl } from 'react-intl';
Linting with a no-duplicate-imports
rule will catch these cases.
Migrate injectIntl
withRef
option (migrateInjectIntlWithRef
)
Replace the deprecated withRef
option with forwarRef
.
import { injectIntl } from 'react-intl';
// ...
- export default injectIntl(MyComponent, { withRef: true });
+ export default injectIntl(MyComponent, { forwardRef: true });
Note: any change related to migrating to the React > 16.3 ref
API must be done manually.
Migrate getChildContext
(migrateGetChildContext
)
This transform searches speciffically for this pattern:
const intlProvider = new IntlProvider({ locale: 'en', defaultLocale: 'en' }, {}); // IntlProvider arguments don't matter
const { intl } = intlProvider.getChildContext();
and replaces intlProvider.getChildContext
with createIntl
:
import React from 'react';
- import { IntlProvider } from 'react-intl';
+ import { createIntl, createIntlCache } from 'react-intl';
- const intlProvider = new IntlProvider({ locale: 'en', defaultLocale: 'en' }, {});
- const { intl } = intlProvider.getChildContext();
+ const intlCache = createIntlCache();
+ const intl = createIntl({
+ locale: 'en-US',
+ defaultLocale: 'en-US',
+ }, intlCache);
Migrate injectIntl
HOC to useIntl
hook (partial) (migrateInjectIntlToUseIntl
)
Replace the injectIntl
import with useIntl
and remove injectIntl
calls by returning WrappedComponent
directly.
import React from 'react';
- import { injectIntl } from 'react-intl';
+ import { useIntl } from 'react-intl';
const WrappedComponent = () => {
return <div />;
};
- export default injectIntl(WrappedComponent);
+ export default WrappedComponent;
You will have to manually add the useIntl
hook to your component:
import React from 'react';
import { useIntl } from 'react-intl';
const WrappedComponent = () => {
+ const intl = useIntl();
return <div />;
};
export default WrappedComponent;
If you are composing multiple high-order components using something like recompose
, you will have to remove injectIntl
manually:
export default compose(
connect(mapStateToProps, mapDispatchToProps),
- injectIntl,
)(Component);
Unsupported changes
These codemods do not automate all required changes to upgrade from v2 or v3 to v4.
It is necessary to do some manual work as described by the lists up next.
Some of these tasks should be simple, like removing addLocaleData
, a method most likely to be used only once per project, so a codemod would not save that much time.
- [v3] (optional) Keep
<span>
as defaulttextComponent
- [v3] Remove
addLocaleData
/ReactIntlLocaleData
and includeIntl.PluralRules
andIntl.RelativeTimeFormat
polyfills - [v3] Migrate
FormattedRelative
/formatRelative
to newFormattedRelativeTime
/formatRelativeTime
API - [v3] Update
FormattedMessage
/formatMessage
rich text formatting - [v3] Use apostrophe (
'
) instead of backslash (/
) as escape character in messages - [v3] Remove dash (
-
) from{placeholder-variables}
- [v3] Support ESM in build toolchain
- [v4] Migrate
FormattedHTMLMessage
/formatHTMLMessage
toFormattedMessage
/formatMessage
with rich text
For more information, see the official guides:
Contributing
The implementation of this tool is based on other open-source libraries, so check out their documentation:
- Transforms: jscodeshift
- CLI: meow
- Prompt: inquirer
Testing
Unit tests are written with Jest and jscodeshift testing utilities.
Important: if you are writting a test case where the file should not be changed, the expected output fixture must be empty!
Releasing
Creating a release on GitHub automatically publishes a new version on npm.