Best Practice non-SHIM/SHIM Development

The best practice is to accomodate both non-SHIM and SHIM development. Here's how you do it:

Create a robust SHIM, call it react_shim.html.

  • Place the shim into your root resource, say under new_/react_shim.html

  • Create your main component module: MyComponent.tsx

  • Create a "runner" module that gathers input parameters and then mounts the component into the dom using ReactDom.render().

    • Call the runner: MyComponentRunner.tsx

    • Bundle this to the appropriate js location e.g. new_/js/MyComponentRunner.js

    • You could also call this MyComponentMain.tsx depending on your preferences.

  • Create a SHIM friendly module that calls the runner.

    • if your SHIM is robust enough, you could use the resulting bundled js file as the load point for react_shim.html

    • Bundle this to the appropriate js location e.g. new_/js/MyComponentShim.js

  • Create a HTML file in the appropriate location that loads MyComponentfor production use.

    • Example file: new_/MyComponent.html

    • This HTML loads MyComponentRunner.js and then calls run

This allows you to

  • Have a stable HTML file for production you use when setting up your WebResource in the Form Editor.

  • Allow hot-reload for development and bypass the need to continuously load js files to the server--they are served directly from your development system i.e. laptop.

  • Keep a semblance of separation of concerns.

You might think this seems complicated and it is more complicated, but it is also worth it since you get hot reloading for free on any development workstation.

Also, Dynamics itself uses React+Redux (in the new UCI) and script loaders in a very similar fashion.

MyComponent.tsx

This module holds your component and it typically receives a variety of repo/DAO props as well some top level information such as the entity name and entity id (assuming you use something like EntityForm described elsewhere). Using EntityForm allows you to detect when a form is saved and entity id information is available and we show how to inherit from those props in the example below.

MyComponentRunner.tsx

This module holds a general run function that can be called with the target element and other parameters to load MyComponent into the DOM.

Notice how we initialize key parameters for the component freeing our component from initialization tasks and keeping these concerns separated cleanly. You can make props whatever you want, but typically want to allow as much flexibility as possible for drilling in properties from the run call. Since the run call is called from the SHIM, you can pass in parameters for the view directly from the FormProperties data property, through the URL or by loading initialization props from a remote location.

There are several patterns you can develop depending on where you obtain your configuration and initial pros from. Typically, you need metadata and config data and those may be asynchronous. Hence in the example above, we have a Promise that we must work with. It's easier, obviously, if there is no asynchronous initialization needed.

MyComponentShim.ts

This is the SHIM load point that when you need a SHIM load js file, load this module. You would use this as your "targeturl" in the example SHIM in another section below.

MyComponent.html

Although you could use a SHIM to do a production load, and is kind of easier since you would not need this file, it is less abstract to define a simple HTML loader.

webpack bundling

You'll need to run your bundler to bundle the two key outputs:

Running webpack produces MyComponentShim.js and MyComponent.js in your target output directory. You only ever need to load MyComponent.js since the SHIM .js file is designed for use only when using webpack-dev-servser. MyComponent.js should be moved to your Dynamics server via a WebResources uploader or whatever process you normally use to move incrementally developed WebResources to Dynamics. The SHIM file is designed to be loaded via a local web server running. You need to arrange for it to be picked up via the mechanism in your react shim in the next section.

react_shim.html

A robust shim is included below

Now you want to load your SHIM file, specify this generic "react_shim.html" file as your WebResource in the Form Editor. The "data" parameters should be set to the following. You must be careful in that "data" can only handle so much data as it passes the data in the URL and URLs have length restrictions.

Last updated

Was this helpful?