Optimizing Composite Component Files

You can compress and bundle the composite component files in your Oracle JET web application using the r.js tool. r.js includes the RequireJS Optimizer that combines the scripts for optimal browser delivery.

r.js is an optimization tool that can combine related scripts together into modules and compress them. The tool is also used for optimizing CSS files. This optimization results in less number of HTTP requests that are required to load a component definition, which leads to a performance improvement in loading a screen that uses such components.

The optimizer is a part of the r.js tool which is designed to be run as part of a build or packaging step, when you are ready to deploy the code. For more information on r.js, see http://requirejs.org/docs/optimization.html.

To install r.js using Node.js, use the following command:

npm install -g requirejs

Note:

If you are using a UNIX or MAC machine, you may use sudo npm install -g requirejs command to install r.js.

Once the execution of the above command is complete, you can use r.js in the command-line interface (CLI) to run the optimizer. For example, if you are using Node.js with npm, use the following command to run the optimizer on your composite component:

r.js -o <optimizer script>

The <optimizer script> is generally referenced from the scripts folder of your root application directory that contains the configuration for optimizing your composite component. To create the <optimizer script>, see Creating an Optimizer Script for a Single Composite Component.

Creating an Optimizer Script for a Single Composite Component

You can create a script that specifies the configuration of the composite component you want to optimize using the r.js tool. Optimization performed by r.js bundles and compresses all the files of the composite component into one file.

For example, consider a JET composite component foo-person with the directory structure as shown below:

/jet-composites
 /foo-person
  loader.js
  component.json
  styles.css
  view.html
  viewModel.js
  /resources
   /nls
    foo-person-translations.js

To optimize a single composite component foo-person:

  1. Create a foo-person-build.js file in the scripts folder of your root application with the following content:

    ({
      baseUrl: '../src/js/jet-composites',
      name: 'foo-person/loader',
      out: '../src/js/jet-composites/foo-person/min/loader.js',
      optimize: 'uglify',
      separateCSS: false,
      generateSourceMaps: true,
      paths: {
          'text': '../../../node_modules/requirejs-text/text',
          'css': '../../../node_modules/require-css/css.min',
          'css-builder': '../../../node_modules/require-css/css-builder',
          'normalize': '../../../node_modules/require-css/normalize',
          'ojL10n': '../../../node_modules/@oracle/oraclejet/dist/js/libs/oj/ojL10n',
          'knockout': 'empty:',
          'jquery': 'empty:',
          'ojs': 'empty:'
      },
      exclude: [
          'text',
          'css',
          'css-builder',
          'normalize',
          'ojL10n'
      ]
    })
    • The libraries that are required by the composite component but not directly used by r.js to optimize the code are mapped to empty: to prevent r.js from including the contents of those libraries in the output file. The require-text and require-css libraries are used by r.js to include the HTML, JSON, and CSS dependencies of the composite component.

    • If you need a non-uglified version of the composite component, you can set the optimize property to none.

    • If a source map is required to help with debugging in the browser, then set the generateSourceMaps flag to true.

  2. Now run the optimizer with the following command:

    r.js -o foo-person-build.js

    This will generate an output file /jet-composites/foo-person/min/loader.js containing all the necessary resources of the composite component, including the HTML, JSON, and CSS as shown below:

    /jet-composites
     /foo-person
      loader.js
      component.json
      styles.css
      view.html
      viewModel.js
      /resources
       /nls
        foo-person-translations.js
      /min
       loader.js
       loader.css (only if using separateCSS)
       loader.js.map (optional source map)

    The output will contain a definition for each file that is required by the composite component, and each file will have a module name that matches the original file path relative to the baseUrl.

By default, r.js combines all the CSS files referenced by the require-css library into one string, and then wraps the string in a <style> tag. However, if these CSS files contain URLs for images, fonts, and so on, then you must generate a separate bundled CSS file that you can load using a <link> tag. To accomplish this, set the separateCSS property to true. This will create a bundled CSS file with the same file name and directory as the bundled JavaScript file. For example, if the bundled JavaScript file name is loader.js, then the bundled CSS is named loader.css by default.

Note:

Setting the separateCSS property in your script will cause an extra HTTP request. You can avoid this if your composite component does not need to load external resources such as, fonts or background images from within its CSS definitions.

To use the separateCSS property, you must load the optimized CSS file manually by editing the foo-person-build.js file as shown below:

({
    ...
    separateCSS: true,
    wrap: {
        end: "require(['css!foo-person/loader']);"
    },
    ...
});

Consuming an Optimized Composite Component

After you run the r.js optimization tool to generate a single optimized file, you can add the composite component to your application using the file.

To add the composite component to your application using the optimized file, load the file by adding foo-person/loader to the define() block of the viewModel that uses the composite component. You must then define the path of the composite component by adding a RequireJS path mapping to foo-person that points to the jet-composites/foo-person/min directory. This involves adding the required configuration to the /src/js/path_mapping.json directory as shown below:

"foo-person": {
  "debug": {
    "path": "jet-composites/foo-person"
  },
  "release": {
    "path": "jet-composites/foo-person/min"
  }
}

If you have additional language translation bundles under the /resources/nls directory, you must copy the translation bundles into your /min directory as they are loaded dynamically and cannot be included in the compressed loader.js file created by r.js.