Resolving Compatibility Challenges with Shims and Polyfills: A Quick Introduction

April 29, 2024 | 4 minute read
Mohammed Kassem
SuiteCloud Advocate
Text Size 100%:

For libraries that aren't readily compatible with SuiteScript or are outright incompatible, developers need to proceed with caution. Libraries originally designed for Node.js or browser environments may not work seamlessly with SuiteScript due to differences in the available APIs and the runtime environment.

To navigate and address these compatibility issues where possible:

  • Understand the dependencies: Investigate the package.json to identify the library's build-time and runtime dependencies. By reviewing each dependency and the library’s documentation, you can better understand its core capabilities and any dependencies that are specific to environments like Node.js or browsers, which might not be supported in SuiteScript.


package.json

  • Identify shims and polyfills: Use tools such as Webpack to bundle shims and polyfills, which emulate the missing features or APIs that the third-party library expects. This step is important for adapting libraries that rely on certain Node.js modules or browser-specific features for compatibility with SuiteScript.

Now, shims and polyfills can be a confusing topic for many developers. This guide aims to provide a clear understanding of Suitelet implementation through practical examples. Leveraging two simple scenarios, we'll explore how shims and polyfills can be utilized within Suitelets.

Shims: A Suitelet Walkthrough

Shimming is code that replicates the missing APIs or global objects that the library expects to find.

Example: Integrating a library that relies heavily on the console.log function, which isn't directly available in SuiteScript. You can create a shim that intercepts calls to console.log and translates them to SuiteScript's logging mechanism (N/log).

Here's an example of how you could create a shim for console.log in SuiteScript 2.1 that uses the NetSuite N/log module's functionality:

/**
*
@NApiVersion 2.1
*
@NScriptType Suitelet

*/

define(['N/log'], function(log) {
    // Shim for console.log
    var console = {
        log:
function() {
            var args = Array.prototype.slice.call(arguments);
            log.debug({
                title:
'Console Log',
                details: args.join(
' ')
            });
        }
    };

    // Now you can use console.log as you would normally
    function onRequest(context) {

        console.log('This will be logged using SuiteScript\'s log module.');
              // Your code here...
    }  

    return {
        onRequest: onRequest
    };
});

This code defines a console object with a log method that concatenates all arguments into a string and logs them using SuiteScript's log.debug. Any third-party library code that gets included after this shim is defined would then be able to call console.log without causing errors.

Polyfills: A Suitelet Walkthrough

Polyfills are functions that provide support for JavaScript features that are missing in the SuiteScript environment.

Example: Integrating a library that requires the fetch API for making HTTP requests. As SuiteScript doesn't have a built-in fetch function, you can create a polyfill using SuiteScript's https module's request method.

/**
*
@NApiVersion 2.1
*
@NScriptType Suitelet
*/

define(['N/https', 'N/url'], function(https, url) {
    // Polyfill for fetch using SuiteScript's https module
    function fetch(polyfillUrl, polyfillOptions) {
        var options = {
            method: polyfillOptions.method ||
'GET',

            headers: polyfillOptions.headers,
            body: polyfillOptions.body ? JSON.stringify(polyfillOptions.body) :
null
        };

        // Make the HTTP request using SuiteScript's https module
        var response = https.request({
            method: options.method,
            url: polyfillUrl,
            body: options.body,
            headers: options.headers

        });

        // Return a Promise-like object
        return {
           then:
function(successCallback, errorCallback) {
                if (response.code >= 200 && response.code < 300) {
                    successCallback(response);
                }
else {
                    errorCallback(response);
                }
            }
        };
    }

    // Example usage of the fetch polyfill
    function onRequest(context) {
        fetch(
'https://api.example.com/data', {
            method:
'POST',
            headers: {

                'Content-Type': 'application/json'
            },
            body: {
                key:
'value'
            }
        }).then(

            function(response) {
                // Handle success
                log.debug(
'Fetch Success', response.body);
            },

            function(error) {
                // Handle error
                log.error(
'Fetch Error', error);
            }
        );

        // Your code here...
    }
}

The fetch function takes a URL and an options object like what you would pass to the native fetch API. It then uses SuiteScript's https module to make the HTTP request. The response is wrapped in a simplified promise-like structure that supports .then(successCallback, errorCallback)to polyfill the native fetch API.

Conclusion

This was a quick guide to teach you how shims and polyfills work. Let’s put the theory into practice and set up your SuiteCloud project to use Webpack and stdlib to bridge functionality gaps. Read my “SuiteScript 2.1 Walkthrough: Node Polyfills with Webpack & stdlib article to integrate third-party libraries to help create node polyfills without excessively increasing the size of your build.

Mohammed Kassem

SuiteCloud Advocate


Previous Post

Research Checklist: SuiteScript Compatibility with Third-Party Libraries

Mohammed Kassem | 6 min read

Next Post


SuiteScript 2.1: Compatible Build-Time and Runtime Libraries

Mohammed Kassem | 9 min read