Skip to content

Add importAndRun function for Code Splitting #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
dainemawer opened this issue Feb 2, 2022 · 2 comments · May be fixed by #86
Open
1 task done

Add importAndRun function for Code Splitting #80

dainemawer opened this issue Feb 2, 2022 · 2 comments · May be fixed by #86
Assignees
Labels
enhancement New feature or request triage Need to check if this is still relevant

Comments

@dainemawer
Copy link
Contributor

Is your enhancement related to a problem? Please describe.

Based on a recent Slack conversation: https://10up.slack.com/archives/G11CA43FW/p1643728684014569
@rdimascio and I believe it would be a great idea to include this boilerplate JavaScript code into frontend.js so that engineers can better work with dynamically imported JavaScript components:

import importAndRun from './util/import-and-run';

const COMPONENTS = {
	'components/accordion-block': {
		selectors: ['.accordion'],
	},
	'components/site-header': {
		selectors: ['body'],
	},
	'components/site-footer': {
		selectors: ['body'],
	},
	'components/story-navigation': {
		selectors: ['.home-nav'],
	},
	'components/service-explorer': {
		selectors: ['.service-explorer'],
	},
	'components/story-comments': {
		selectors: ['.story-comments'],
	},
	'components/social-share': {
		selectors: ['.social-share'],
	},
	'components/child-filters': {
		selectors: ['.photolisting__aside-filters'],
	},
	'components/cookie-consent': {
		selectors: ['#cookie-consent'],
	},
};

const initComponents = () => {
	Object.entries(COMPONENTS).forEach(([key, value]) => {
		importAndRun(key, value.selectors, value.callback);
	});
};

const init = () => {
	window.requestAnimationFrame(() => {
		document.body.classList.add('js-loaded');
	});

	initComponents();
};

/* eslint-disable-next-line @wordpress/no-global-event-listener */
document.addEventListener('DOMContentLoaded', init);

The above allows us to cleanly and easily keep track of components and import / run them as required.
This task would also require us adding the importAndRun utility to a new assets/js/util folder.

It's our hope that this will close the loop on dynamically imported JavaScript as the scaffold already supports Code Splitting out the box.

/**
 * Default callback when using `importAndRun`
 *
 * @param {Object} Module - Factory function or class
 */
const DEFAULT_CALLBACK = (Module) => {
	try {
		const module = new Module();
		module.init();
	} catch (error) {
		// Something failed
	}
};

/**
 * Dynamically import a module if it appears on the page.
 *
 * @param {string} module - Path to module
 * @param {string[]} selectors - List of selectors. Used to conditionally load the module
 * @param {Function} cb - Callback function to run after loading the module
 * @return {Promise} - Returns the dynamic import
 */
export default (module, selectors = ['body'], cb = DEFAULT_CALLBACK) => {
	let shouldImport = false;

	if (Array.isArray(selectors) && selectors.length) {
		shouldImport = Boolean(
			selectors.find((selector) => {
				return Boolean(document.querySelector(selector));
			}),
		);
	}

	if (!shouldImport) {
		Promise.resolve();
	}

	/* eslint-disable-next-line consistent-return */
	return import(`./../${module}`).then(({ default: module }) => {
		if (cb && typeof cb === 'function') {
			cb(module);
		}
	});
};

Designs

No response

Describe alternatives you've considered

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@dainemawer dainemawer added the enhancement New feature or request label Feb 2, 2022
@dainemawer dainemawer linked a pull request Feb 28, 2022 that will close this issue
6 tasks
@darylldoyle
Copy link
Collaborator

@dainemawer this and the associated PR seem to have stalled for a while. Is this still something you're looking to push forward?

@darylldoyle darylldoyle added the triage Need to check if this is still relevant label Mar 17, 2025
@fabiankaegy
Copy link
Member

My somewhat snarky take is: Use blocks, then everything is code split automatically 🫣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request triage Need to check if this is still relevant
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants