Skip to content

Common Migration Issues

Jennifer Shepherd edited this page Dec 19, 2019 · 17 revisions

CommonJS and ESM incompatibility

Although an application may bundle JS modules successfully there can still be errors when executing them at runtime. Page Kit uses more recent versions of Babel and Webpack which are stricter than older versions and default to assuming ESM syntax instead of CJS. There is a project board to track CommonJS and ESM fixes here: https://github.com/Financial-Times/dotcom-page-kit/projects/1

Error: exports is not defined

The module was detected as an ECMAScript module but later tried to assign module.exports or exports[prop] which are CommonJS. Find the module and refactor it to use only one module syntax.

ReferenceError: x is not defined

There are two common causes for this issue:

  1. Using require() to load an ESM module then attempting to reference its default export. You'll need to refactor the code to correctly reference the default property, e.g.:

    const foo = require('module').default
    
    // or
    const foo = require('module')
    const bar = foo.default()
  2. Attempting to import a named property from a module which has a default export. You'll need to refactor the code to fix these references.

    // a.js
    export default { foo, bar, baz }
    
    // b.js
    import { foo } from './a' // 💥

References to (not obviously) n-ui properties

For apps using n-ui there are a number of properties which can be added to a request in order to configure some internals. Some are obviously part of n-ui (e.g. response.locals.nUiConfig) but others aren't. Below is a list of properties which are specific to n-ui and should be removed or refactored to use the Page Kit equivalent.

Stylesheet management

These can usually be removed as Page Kit does not provive any tools to split CSS. However, if the app does generate multiple stylesheets the assets middleware can be used to locate those files and passed to the shell component.

// n-ui
response.locals.stylesheets.inline = ['head', 'article'];
response.locals.stylesheets.lazy = ['main'];

// Page Kit assets middleware (if required)
const stylesheets = [
    response.assets.loader.getPublicURL('head.css'),
    response.assets.loader.getPublicURL('article.css')
];

const asyncStylesheets = response.assets.loader.getPublicURL('main.css');

<Shell stylesheets={stylesheets} asyncStylesheets={asyncStylesheets} />

n-feedback is missing styles

This component depends on the styles for o-overlay being available but it does not explicitly depend on this package. Install o-overlay as a dependency of the app if it is not already and integrate the styles.


No equivalent for n-ui scroll tracking

Apps often use scroll tracking to measure if certain components on the page enter the viewport. This had a custom implementation in n-ui but it is now part of o-tracking and apps can be migrated to use this instead.

Before:

import * as nTracking from '@financial-times/n-tracking';
import { tracking } from 'n-ui';

if (flags.get('oTracking')) {
    nTracking.init({ appContext });
    tracking.scrollDepthComponents.init();
}

After:

import * as nTracking from '@financial-times/n-tracking';

if (flags.get('oTracking')) {
    const oTracking = nTracking.init({ appContext });

    oTracking.view.init({
        selector: '.js-track-scroll-event',
        category: 'page',
        action: 'scrolldepth'
    });
}

If you have tracking.audioTeaserView.init();, you might also need this: https://github.com/Financial-Times/next-search-page/blob/master/client/main.js#L100-L112


X_ENGINE_RUNTIME_MODULE is not defined

You need to set up the x-engine Webpack plugin to resolve these variables, e.g. (in your page-kit.config.js):

const xEngine = require('@financial-times/x-engine/src/webpack');
const { hooks } = require('@financial-times/dotcom-page-kit-cli');

module.exports = {
	plugins: [
		({ on }) => {
			on(hooks.WEBPACK_CONFIG, ({ resource }) => {
				const plugin = xEngine();
				resource.plugins.push(plugin);
			});
		},
	],
	settings: {}
}