close

Filter

loading table of contents...

Frontend Developer Manual / Version 2107

Table Of Contents

5.13 Integrating Non-Modular JavaScript

Not all JavaScript files found via the NPM registry are written with a JavaScript Module System in mind. This might also apply to your own JavaScript if you are coming from an older CoreMedia version. One of the main differences between modular and non-modular JavaScript is the scope of the declared variables. While the latter has full access to global variables modular JavaScript will never work on the global scope but will import other modules if functionality is needed and exports its own functionality that can be reused by other modules explicitly.

First of all, CoreMedia recommends to actually migrate non-modular JavaScript into modular JavaScript, preferable by using the ES6 module system. This makes sure that all JavaScripts are up-to-date and you can use the advantages of the module system. IDEs like IntelliJ IDEA offer very good code assistance to efficiently work with the module systems.

However, in some cases migration is not possible because the JavaScript comes from a third-party library and may not be changed or it is too expensive to perform a full migration of the existing code base. In both cases the suggested approach is to use a mechanism called Shimming which basically means wrapping the JavaScript into an adapter that - from the perspective of the module system - makes sure that the JavaScript can be used as a module but - from the perspective of the JavaScript file - provides access to all global variables the file is operating on.

Shimming

Shimming is build into the theme build mechanism based on Webpack's imports-loader and exports-loader. Make sure you have read the basic concepts described in the Webpack Documentation.

Let's imaging there is a third-party JavaScript ./src/vendor/specialCalc.js that expects jQuery to be found under a global variable named jQuery. It will perform some calculations and stores its result in a global variable named calculationResult. This JavaScript file may not be touched because the author doesn't think it is a good idea to use a modular system but still provides updates regularly to improve the algorithm of the calculation. To integrate this JavaScript file into a modular system you need to shim it. This can be achieved in two ways.

Shimming via Webpack Configuration

In a theme you can directly adjust your webpack.config.js to add configuration for shimming:

const path = require("path");
const { webpackConfig } = require("@coremedia/theme-utils/webpack.config.js");

module.exports = (env, argv) => {
  const config = webpackConfig(env, argv);

  config.module = config.module || {};
  config.module.rules = config.module.rules || [];
  config.module.rules.push({
    test: path.resolve("./src/vendor/specialCalc.js"),
    use: ["imports-loader?jQuery=jquery", "exports-loader?result=calculationResult"],
  });

  return config;
};

Example 5.3. Shimming in webpack.config.js


This means that whenever ./src/vendor/specialCalc.js is imported by a JavaScript module the module known as jquery will be provided under a variable named jQuery. After the script has run a variable named calculationResult will be exported under the name result.

Basically the mechanism will add code to the beginning and to the end of the JavaScript file during theme build, so the resulting output looks like this and can be used as a JavaScript module:

import jQuery from "jquery";

    ... (the original code of specialCalc.js) ...

    export { calculationResult as result };

Example 5.4. The added code


Shimming via package.json

You can also add a shim configuration in your theme configuration. This also works in bricks so they can provide their required shimming configuration self-contained:

{
  ...
  "coremedia": {
    "type: "theme",
    ...
    "shim": {
      "./src/vendor/jquery.bcSwipe": {
        "imports": {
          "jQuery": "jquery"
        },
        "exports": {
          "": "jQuery"
        }
      }
    }
  }
}

Example 5.5. Shimming in the theme's package.json


This will lead to the same result as the other example.

Warning

Warning

Although it is also possible to shim a module on the fly during a require statement directly in the JavaScript that wants to import a non-modular JavaScript file CoreMedia does not recommend using it. The syntax is hard to read but more important it will break the externals configuration as modules are imported although they are marked as external dependency.

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.