@wezom/dynamic-modules-import
v0.2.3-beta
Published
A library for defining the modules used on the page and loading them asynchronously on demand
Downloads
6
Maintainers
Readme
@wezom/dynamic-modules-import
A library for defining the modules used on the page and loading them asynchronously on demand
Coverage
| Statements | Branches | Functions | Lines | | ------------------------------------------------------------------ | ------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------- | | | | | |
Table of Content:
Usage
Install npm package
npm i @wezom/dynamic-modules-import
Import to your codebase
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';
Create
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);
});
};
Modules that are imported
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 */
});
};
Create options
selector
required
type: JQuery.Selector
modules
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;
}
modules[moduleName].filter
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;
},
// ...
}
}
modules[moduleName].importFn
You own method for importing module
// example
const modules = {
moduleA: {
importFn: () => import('my-module'),
// ...
},
moduleB: {
importFn: async () => {
await someGlobals();
return import('my-dependent-module');
},
// ...
}
}
modules[moduleName].importCondition
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;
},
// ...
}
}
debug
optional
type: boolean
default: false
pendingCssClass
optional
type: string
default: '_dmi-is-pending'
loadedCssClass
optional
type: string
default: '_dmi-is-loaded'
errorCssClass
optional
type: string
default: '_dmi-has-error'
API
Properties
All props are readonly. You cannot change them after creation.
debug
type: boolean
value: depends on create option debug
selector
type: JQuery.Selector
value: depends on create option selector
pendingCssClass
type: string
value: depends on create option pendingCssClass
pendingEvent
type: string
value: "dmi:pending"
loadedCssClass
type: string
value: depends on create option loadedCssClass
loadedEvent
type: string
value: "dmi:loaded"
errorCssClass
type: string
value: depends on create option errorCssClass
errorEvent
type: string
value: "dmi:error"
Methods
importAll()
// signature
importAll(
$container?: JQuery,
awaitAll?: boolean,
ignoreImportCondition?: boolean
): Promise<any>;
importModule()
// signature
importModule(
moduleName: string,
$container?: JQuery,
ignoreImportCondition?: boolean
): Promise<any>;