6 Add Third-Party Tools or Libraries to Your Oracle JET App

You can add third-party tools or libraries to your Oracle JET app. The steps to do this vary depending on the method you used to create your app.

If you used the Oracle JET command-line tooling to scaffold your app, you install the library and make modifications to appRootDir/path_mapping.json. If you created your app using any other method and are using RequireJS, you add the library to your app and update the RequireJS bootstrap file, typically main.js.

Note:

This process is provided as a convenience for Oracle JET developers. Oracle JET does not support the additional tools or libraries and cannot guarantee that they will work correctly with other Oracle JET components or toolkit features.

To add a third-party tool or library to your Oracle JET app, complete one of the following procedures.

  • If you created your app with command-line tooling, perform the following steps:

    1. In your app's root directory, enter the following command in a terminal window to install the library using NPM:

      npm install library-name --save
    2. Add the new library to the path mapping configuration file.

      1. Open appRootDir/path_mapping.json for editing.

        A portion of the file is shown below.

        {
        
          "use": "local",
          "cdns": {
            "jet": "https://static.oracle.com/cdn/jet/17.1.0/default/js",
            "css": "https://static.oracle.com/cdn/jet/17.1.0/default/css",
            "config": "bundles-config.js"
          },
          "3rdparty": "https://static.oracle.com/cdn/jet/17.1.0/3rdparty"
        },
        "libs": {
          "knockout": {
              ...
          },
        ...

        Oracle JET's CLI helps manage third-party libraries for your app by adding entries to its local path_mapping.json file.

        For each library listed in the libs map in the path_mapping.json file, the following two actions happen at build time. First, one or more files are copied from somewhere (usually appRootDir/node_modules) into the appRootDir/web output folder. Second, a requireJS path value is created for you to represent the path to the library; it is injected into the built main.js file or optimized bundle. If you use TypeScript, then this should be the same path name that you use at design time for imports from the library.

        The following example is an existing path mapping entry for the persist library, which we analyze below to describe what each attribute does and how it relates to the two build-time actions defined above.
        1  | "persist": {
        2  |   "cdn": "3rdparty",
        3  |   "cwd": "node_modules/@oracle/oraclejet/dist/js/libs/persist",
        4  |   "debug": {
        5  |     "cwd": "debug",
        6  |     "src": [
        7  |       "**"
        8  |     ],
        9  |     "path": "libs/persist/debug",
        10 |     "cdnPath": "persist/debug"
        11 |   },
        12 |   "release": {
        13 |     "cwd": "min",
        14 |     "src": [
        15 |       "**"
        16 |     ],
        17 |     "path": "libs/persist/min",
        18 |     "cdnPath": "persist/min"
        19 |   }
        20 | },
        • Line 1: This is the name of the libs map entry ("persist", in this case). This name is used as the name of the requireJS path entry that is created; therefore, it is also the import path. The same name is used for the folder that gets created under the appRootDir/web/js/libs folder in the built application.

          Note:

          If your app uses TypeScript, then you'll also need a tsconfig.json file paths entry with the same name.
        • Line 2 (Optional): The cdn attribute sets the name of the CDN root for the location of this library. In this case, it is set to the value 3rdparty, which maps to a particular location in the Oracle CDN. Any third-party libraries that you add yourself (that is, those that are not present on the Oracle CDN) should not have a cdn or cdnPath value at all, unless you maintain your own CDN infrastructure where you can place the library.
        • Line 3: The first role of each path mapping entry at build time is to copy files. The cwd attribute on this line tells the tooling where to start copying from, and subsequent paths are relative to this root. This is generally some folder under appRootDir/node_modules/<library>.
        • Lines 4 through 12: The debug and release sections here are the same, with the exception that if you do a normal build, then the specifications in the debug section are followed, and if you do a --release build, then the specifications in the release section are followed. For example, the latter case can allow the copying of only optimized assets for release.
        • Line 5 (Optional): In the context of the debug or release build, this second cwd attribute further refines the copy root for everything that follows. For example, when running a normal (debug) build for the persist library, the copy root is appRootDir/node_modules/@oracle/oraclejet/dist/js/libs/persist/debug, where the debug cwd value is appended to the top-level cwd value. Additionally, this folder name is used in the output; the copied files end up in the appRootDir/web/js/libs/persist/debug directory. This attribute is optional; if omitted, then all copies are copied from paths relative to the root cwd location and placed in the root of the destination folder.
        • Line 6: The src attribute holds an array of all the files that you want to copy from your root location into the built app (that is, all the files that are actually needed at runtime). The paths you add here can either be specific file names, or you can use globs to match multiple files at once. In the example above, the glob ** is used, which results in copying everything from the /debug folder, including subfolders. Folder structure is preserved in the copied output under the /web directory.
        • Line 9: The path attribute is used for the second role performed by each path mapping entry; it defines the value of the requireJS path that gets injected into the main.js file. For the above example, the requireJS path mapping is "persist":"libs/persist/min", which is relative to the requireJS load root, typically appRootDir/web/js.
        • Line 10 (Optional): The cdnPath attribute is optional and should only be used if you have actually put a copy of the library onto a CDN. If that is the case, then if the path_mapping.json file has the use attribute set to "cdn" rather than "local", then the generated requireJS path statement uses this cdnPath value rather than the path value (line 9). The path here is relative to the CDN root defined by the alias allocated to the CDN and used in the cdn attribute for that library. If “use” is set to “cdn” but a library does not include CDN information, then the build falls back to using the local copy of the library and set up the requireJS path accordingly.
      2. Copy one of the existing library entries in the "libs" map and modify as needed for your library.

        The code sample below shows modifications for my-library, a library that contains both minified and debug versions.

        ...
         "libs": {
            "my-library": {
              "cwd": "node_modules/my-library/dist",
              "debug": {
                "src": "my-library.debug.js",
                "path": "libs/my-library/my-library.debug.js"
              },
              "release": {
                "src": "my-library.js",
                "path": "libs/my-library/my-library.js"
              }
            },
        ...

        In this example, the cwd attribute points to the location where NPM installed the library, the src attribute points to a path or array of paths containing the files that are copied during a build, and the path attribute points to the destination that contains the built version.

        When defining your own library entry in the path_mapping.json file, you should test it out by running the ojet build command and then confirm that all the expected files have been copied into the appRootDir/web/js/libs directory and that the requireJS path mapping has been injected in the built appRootDir/web/js/main.js file.

        Note:

        If the existing library entry that you copy to modify includes "cdn": "3rdparty", remove that line from the newly-created entry for your library. This line references the Oracle JET third-party area on the content distribution network (CDN) managed by Oracle. Your library won't be hosted there, and keeping this line causes a release build to fail at runtime by mapping your library's path to a non-existent URL.

        If you use a CDN, add the URL to the CDN in the entry for the cdnPath attribute.

    3. If your project uses TypeScript, then you also need to define a paths entry in your tsconfig.json file that allows you to import the library using the same path name at design time as you'll use at runtime. If the library in question also provides some types for you to use, then the path should point to these to allow your editor to provide TypeScript support for your usage of that library. Here is an example of an existing paths entry in an Oracle JET app created with the command-line tooling.
      "paths": {
        "ojs/*": [
          "./node_modules/@oracle/oraclejet/dist/types/*"
      ],
      ...
  • If you didn’t use command-line tooling to create your app, perform the following steps to add the tool or library.

    1. In the app’s /libs directory, create a new directory and add the new library and any accompanying files to it.

      For example, for a library named my-library, create the my-library directory and add the my-library.js file and any needed files to it. Be sure to add the minified version if available.

    2. In your RequireJS bootstrap file, typically main.js, add a path for the library file in the path mapping section of the requirejs.config() definition.

      For example, add the highlighted code below to your bootstrap file to use a library named my-library.

      requirejs.config({
        // Path mappings for the logical module names
        paths: 
        {
          'knockout': 'libs/knockout/knockout-3.x.x',
          'jquery': 'libs/jquery/jquery-3.x.x.min',
          ...
          'text': 'libs/require/text',
          'my-library': 'libs/my-library/my-library
        },
        require(['knockout', 'my-library'],
        // this callback gets executed when all 
        // required modules are loaded
        function(ko) 
        {
            // Add any start-up code that you want here
        }
      );
    3. If your project uses TypeScript, then you also need to define a paths entry in your tsconfig.json file that allows you to import the library using the same path name at design time as you'll use at runtime. If the library in question also provides some types for you to use, then the path should point to these to allow your editor to provide TypeScript support for your usage of that library. Here is an example of an existing paths entry in an Oracle JET app created with the command-line tooling.
      "paths": {
        "ojs/*": [
          "./node_modules/@oracle/oraclejet/dist/types/*"
       ],
      ...