Skip to content

React application developer guide

Kasun Thennakoon edited this page Aug 16, 2019 · 25 revisions

Table of content

* Note: Although most of the examples given here point to APIM Publisher application, the same method should be applied/used in APIM Store application as well. If you see contradictory behavior in Publisher and Store apps, This could be a bug. Please report it in Github issues

Prerequisites

You should have NPM (minimum 5.7.0) and Node.js (minimum 8.12.0) installed.

Source

All the UI apps reside in wso2/carbon-apimgt repository.

Unit test for each app is located inside the individual apps. and new UI Integration tests are located in wso2/product-apim

Building the UI(SPA) applications

We have two build options

  1. Development build npm run build:dev
  2. Production build npm run build:prod

Development build: Provide continues building support and skip es-lint validations, This build is intended to be used in development environments. We have skipped the es-lint validations in this build because most of the IDEAs nowadays support linting through plugins.

Production builds: This build will simply pass the webpack production environment parameter and avoid putting verbose output. Webpack production build will be followed by npm run i18n command to generate the default locale (en.json) file.

Extending or modifying a React applications

Extention model

Accessibility

We should follow the guidelines given in following standard documentation. It also contains a set of examples for checkout. React documentation also contains some examples for implementing web accessibility support using React JSX syntax.

Internationalisation (I18n)

Checkout the i18n wiki page for more information

Props validation

Please add props validation for nested objects as well. Otherwise, we will never be able to bump this plugin version

User experience design

When placing an Action and Cancel button pair i:e

image

Place the Action to the left of the Cancel button.

Troubleshoot guide

No page content, Only page load animation and no errors in console either.

Most probably you would have missed a class or function export in somewhere in the code. This is a known issue and will be fixed in a later release. If you couldn't figure out where is the issue, You can temporally change the render element in here to directly imported ProtectedApp component. For example, use the following import in Publisher.jsx

import PA from './app/ProtectedApp';

and change the below line

                            <Route
                                render={() => {
-                                    return <LoadableProtectedApp user={user} />;
+                                    return <PA user={user} />;
                                }}

Save the changes and run a dev build

npm run build:dev

Now you will able to see the actual exception which breaks the page load.

Production build fails while extracting i18n messages

By default, production build command will generate the i18n locale file too. If you get an error like below, It means you have duplicate ids in <FormattedMessage/> components.

> wso2_apim_publisher@3.0.0 i18n /Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/p
ublisher-new
> extract-messages -l=en,fr -o site/public/locales/ -d en --extractFromFormatMessageCall --flat 'source/src/app/**/*.jsx'

SyntaxError: /Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher-new/source/
src/app/components/Apis/Details/Resources/Resources.jsx: [React Intl] Duplicate message id: "Apis.Details.Resources.Resources.assign.advanced.throttling.perApi", but the `descript
ion` and/or `defaultMessage` are different.
  676 |                                             defaultMessage: 'Apply per API',
  677 |                                         })} />
> 678 |                                         <FormControlLabel value="perResource" control={<Radio />} label={intl.formatMessage({
      |                                                                                                                             ^
  679 |                                             id: 'Apis.Details.Resources.Resources.assign.advanced.throttling.perApi',
  680 |                                             defaultMessage: 'Apply per Resource',
  681 |                                         })} />
    at File.buildCodeFrameError (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/p
ublisher-new/node_modules/@babel/core/lib/transformation/file/file.js:261:12)
    at NodePath.buildCodeFrameError (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resourc
es/publisher-new/node_modules/@babel/traverse/lib/path/index.js:157:21)
    at storeMessage (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher-new
/node_modules/babel-plugin-react-intl/dist/index.js:125:24)
    at processMessageObject (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publi
sher-new/node_modules/babel-plugin-react-intl/dist/index.js:297:21)
    at PluginPass.CallExpression (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher-new/node_modules/babel-plugin-react-intl/dist/index.js:323:25)
    at newFn (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher-new/node_modules/@babel/traverse/lib/visitors.js:193:21)
    at NodePath._call (/Users/tmkasun/Documents/wso2/dev/products/apim/carbon-apimgt-forked/features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher-n

Fix the duplicate ids and re-run the build to solve the issue. Always check for your id given in <FormattedMessage/> component in the generated locale file en.json to make sure that it has extracted the react-i18n id and defaultMessage correctly