A library for defining the modules used on the page and loading them asynchronously on demand
Statements | Branches | Functions | Lines |
---|---|---|---|
npm i @wezom/dynamic-modules-import
By default, we distribute our lib as is - original TypeScript files, without transpiling to ES5 or ES6.
// Import original ts code
// but requires to be not exclude in `node_modules`.
// Check your `tsconfig.json`
import { create } from '@wezom/dynamic-modules-import';
You can import compiled files from special folders.
// ES6: const, let, spread, rest and other modern JavaScript features
// but requires to be not exclude in `node_modules`.
// Check your `babebl-loader` (if your use webpack as bandler)
import { create } from '@wezom/dynamic-modules-import/dist/es-6';
// or ES5: no ES6 features but ready for use as is, without transpiling
import { create } from '@wezom/dynamic-modules-import/dist/es-5';
We recommend, that create and setup DMI object in a single module and then import it to your other modules for usage
// modules/dmi.ts
import { create } from '@wezom/dynamic-modules-import';
export default create({
selector: '.my-js-selector',
modules: {
handleFormModule: {
filter: 'form',
importFn: () => import('modules/form-module')
},
handleSliderModule: {
filter: '.js-slider',
importFn: () => import('modules/slider-module')
}
}
});
// app.ts
import $ from 'jquery';
import DMI from 'modules/dmi';
$(() => {
const $root = $('#root');
DMI.importAll($root);
});
Also, you can import each module directly with your custom behavior
// modules/some-module.ts
import $ from 'jquery';
import DMI from 'modules/dmi';
export default () => {
const $someModuleContainer = $('#some-module-container');
const $button = $someModuleContainer.find('button');
$button.on('click', () => {
DMI.importModule('handleSomeModule', $someModuleContainer);
});
};
Your dynamic modules must export default
method!
Method will receive jQuery elements as first argument.
That will be elements for the current module filtered by filter
prop (see "create" section)
// modules/slider-module.ts
import 'heavy-slider-from-node_modules';
export default ($elements: JQuery) => {
$elements.slider({
/* options */
});
};
required
type: JQuery.Selector
required
type: Object<DMIModule>
Each module provided by DMIModule interface
interface DMIModule {
filter:
| JQuery.Selector
| JQuery.TypeOrArray<Element>
| JQuery
| ((this: Element, index: number, element: Element) => boolean);
importFn(stats: DMIModuleStats): Promise<any>;
importCondition?(
$elements: JQuery,
$container: JQuery,
stats: DMIModuleStats
): boolean;
}
Method that has signature like jQuery.fn.filter
and works in same way;
// example
const modules = {
moduleA: {
filter: 'form',
// ...
},
moduleB: {
filter(index) {
return $("strong", this).length === 1;
},
// ...
}
}
You own method for importing module
// example
const modules = {
moduleA: {
importFn: () => import('my-module'),
// ...
},
moduleB: {
importFn: async () => {
await someGlobals();
return import('my-dependent-module');
},
// ...
}
}
You own way to determinate for allowed importing
Note! DMI will not observe by any changes that can be happen in your page or app. So you need yourself re-invoke DMI if something changed and you need to react that with your
importCondion
// example
const modules = {
moduleA: {
importCondition: () => {
// I want to load module only if there more than 20 HTML <p> elements on current invoke
return $('p').length > 20;
},
// ...
}
}
optional
type: boolean
default: false
optional
type: string
default: '_dmi-is-pending'
optional
type: string
default: '_dmi-is-loaded'
optional
type: string
default: '_dmi-has-error'
All props are readonly. You cannot change them after creation.
type: boolean
value: depends on create option debug
type: JQuery.Selector
value: depends on create option selector
type: string
value: depends on create option pendingCssClass
type: string
value: "dmi:pending"
type: string
value: depends on create option loadedCssClass
type: string
value: "dmi:loaded"
type: string
value: depends on create option errorCssClass
type: string
value: "dmi:error"
// signature
importAll(
$container?: JQuery,
awaitAll?: boolean,
ignoreImportCondition?: boolean
): Promise<any>;
// signature
importModule(
moduleName: string,
$container?: JQuery,
ignoreImportCondition?: boolean
): Promise<any>;