Understanding (all) JavaScript module formats and tools

When you build an application with JavaScript, you always want to modularize your code. However, JavaScript language was initially invented for simple form manipulation, with no built-in features like module or namespace. In years, tons of technologies are invented to modularize JavaScript. This article discusses all mainstream terms, patterns, libraries, syntax, and tools for JavaScript modules.

IIFE module: JavaScript module pattern

In the browser, defining a JavaScript variable is defining a global variable, which causes pollution across all JavaScript files loaded by the current web page:

// Define global variables. let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; // Use global variables. increase(); reset();

To avoid global pollution, an anonymous function can be used to wrap the code:

(() => { let count = 0; // ... });

Apparently, there is no longer any global variable. However, defining a function does not execute the code inside the function.

IIFE: Immediately invoked function expression

To execute the code inside a function f, the syntax is function call () as f(). To execute the code inside an anonymous function (() => {}), the same function call syntax () can be used as (() => {})():

(() => { let count = 0; // ... })();

This is called an IIFE (Immediately invoked function expression). So a basic module can be defined in this way:

// Define IIFE module. const iifeCounterModule = (() => { let count = 0; return { increase: () => ++count, reset: () => { count = 0; console.log("Count is reset."); } }; })(); // Use IIFE module. iifeCounterModule.increase(); iifeCounterModule.reset();

It wraps the module code inside an IIFE. The anonymous function returns an object, which is the placeholder of exported APIs. Only 1 global variable is introduced, which is the module name (or namespace). Later the module name can be used to call the exported module APIs. This is called the module pattern of JavaScript.

Import mixins

When defining a module, some dependencies may be required. With IIFE module pattern, each dependent module is a global variable. The dependent modules can be directly accessed inside the anonymous function, or they can be passed as the anonymous function’s arguments:

// Define IIFE module with dependencies. const iifeCounterModule = ((dependencyModule1, dependencyModule2) => { let count = 0; return { increase: () => ++count, reset: () => { count = 0; console.log("Count is reset."); } }; })(dependencyModule1, dependencyModule2);

The early version of popular libraries, like jQuery, followed this pattern. (The latest version of jQuery follows the UMD module, which is explained later in this article.)

Revealing module: JavaScript revealing module pattern

The revealing module pattern is named by Christian Heilmann. This pattern is also an IIFE, but it emphasizes defining all APIs as local variables inside the anonymous function:

// Define revealing module. const revealingCounterModule = (() => { let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; return { increase, reset }; })(); // Use revealing module. revealingCounterModule.increase(); revealingCounterModule.reset();

With this syntax, it becomes easier when the APIs need to call each other.

CJS module: CommonJS module, or Node.js module

CommonJS, initially named ServerJS, is a pattern to define and consume modules. It is implemented by Node,js. By default, each .js file is a CommonJS module. A module variable and an exports variable are provided for a module (a file) to expose APIs. And a require function is provided to load and consume a module. The following code defines the counter module in CommonJS syntax:

// Define CommonJS module: commonJSCounterModule.js. const dependencyModule1 = require("./dependencyModule1"); const dependencyModule2 = require("./dependencyModule2"); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; exports.increase = increase; exports.reset = reset; // Or equivalently: module.exports = { increase, reset };

The following example consumes the counter module:

// Use CommonJS module. const { increase, reset } = require("./commonJSCounterModule"); increase(); reset(); // Or equivelently: const commonJSCounterModule = require("./commonJSCounterModule"); commonJSCounterModule.increase(); commonJSCounterModule.reset();

At runtime, Node.js implements this by wrapping the code inside the file into a function, then passes the exports variable, module variable, and require function through arguments.

// Define CommonJS module: wrapped commonJSCounterModule.js. (function (exports, require, module, __filename, __dirname) { const dependencyModule1 = require("./dependencyModule1"); const dependencyModule2 = require("./dependencyModule2"); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; module.exports = { increase, reset }; return module.exports; }).call(thisValue, exports, require, module, filename, dirname); // Use CommonJS module. (function (exports, require, module, __filename, __dirname) { const commonJSCounterModule = require("./commonJSCounterModule"); commonJSCounterModule.increase(); commonJSCounterModule.reset(); }).call(thisValue, exports, require, module, filename, dirname);

AMD module: Asynchronous Module Definition, or RequireJS module

AMD (Asynchronous Module Definition https://github.com/amdjs/amdjs-api), is a pattern to define and consume module. It is implemented by RequireJS library https://requirejs.org/. AMD provides a define function to define module, which accepts the module name, dependent modules’ names, and a factory function:

// Define AMD module. define("amdCounterModule", ["dependencyModule1", "dependencyModule2"], (dependencyModule1, dependencyModule2) => { let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; return { increase, reset }; });

It also provides a require function to consume module:

// Use AMD module. require(["amdCounterModule"], amdCounterModule => { amdCounterModule.increase(); amdCounterModule.reset(); });

The AMD require function is totally different from the CommonJS require function. AMD require accept the names of modules to be consumed, and pass the module to a function argument.

Dynamic loading

AMD’s define function has another overload. It accepts a callback function, and pass a CommonJS-like require function to that callback. Inside the callback function, require can be called to dynamically load the module:

// Use dynamic AMD module. define(require => { const dynamicDependencyModule1 = require("dependencyModule1"); const dynamicDependencyModule2 = require("dependencyModule2"); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; return { increase, reset }; });

AMD module from CommonJS module

The above define function overload can also passes the require function as well as exports variable and module to its callback function. So inside the callback, CommonJS syntax code can work:

// Define AMD module with CommonJS code. define((require, exports, module) => { // CommonJS code. const dependencyModule1 = require("dependencyModule1"); const dependencyModule2 = require("dependencyModule2"); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; exports.increase = increase; exports.reset = reset; }); // Use AMD module with CommonJS code. define(require => { // CommonJS code. const counterModule = require("amdCounterModule"); counterModule.increase(); counterModule.reset(); });

UMD module: Universal Module Definition, or UmdJS module

UMD (Universal Module Definition, https://github.com/umdjs/umd) is a set of tricky patterns to make your code file work in multiple environments.

UMD for both AMD (RequireJS) and native browser

For example, the following is a kind of UMD pattern to make module definition work with both AMD (RequireJS) and native browser:

// Define UMD module for both AMD and browser. ((root, factory) => { // Detects AMD/RequireJS"s define function. if (typeof define === "function" && define.amd) { // Is AMD/RequireJS. Call factory with AMD/RequireJS"s define function. define("umdCounterModule", ["deependencyModule1", "dependencyModule2"], factory); } else { // Is Browser. Directly call factory. // Imported dependencies are global variables(properties of window object). // Exported module is also a global variable(property of window object) root.umdCounterModule = factory(root.deependencyModule1, root.dependencyModule2); } })(typeof self !== "undefined" ? self : this, (deependencyModule1, dependencyModule2) => { // Module code goes here. let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; return { increase, reset }; });

It is more complex but it is just an IIFE. The anonymous function detects if AMD’s define function exists.

  • If yes, call the module factory with AMD’s define function.
  • If not, it calls the module factory directly. At this moment, the root argument is actually the browser’s window object. It gets dependency modules from global variables (properties of window object). When factory returns the module, the returned module is also assigned to a global variable (property of window object).

UMD for both AMD (RequireJS) and CommonJS (Node.js)

The following is another kind of UMD pattern to make module definition work with both AMD (RequireJS) and CommonJS (Node.js):

(define => define((require, exports, module) => { // Module code goes here. const dependencyModule1 = require("dependencyModule1"); const dependencyModule2 = require("dependencyModule2"); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; module.export = { increase, reset }; }))(// Detects module variable and exports variable of CommonJS/Node.js. // Also detect the define function of AMD/RequireJS. typeof module === "object" && module.exports && typeof define !== "function" ? // Is CommonJS/Node.js. Manually create a define function. factory => module.exports = factory(require, exports, module) : // Is AMD/RequireJS. Directly use its define function. define);

Again, don’t be scared. It is just another IIFE. When the anonymous function is called, its argument is evaluated. The argument evaluation detects the environment (check the module variable and exports variable of CommonJS/Node.js, as well as the define function of AMD/RequireJS).

  • If the environment is CommonJS/Node.js, the anonymous function’s argument is a manually created define function.
  • If the environment is AMD/RequireJS, the anonymous function’s argument is just AMD’s define function. So when the anonymous function is executed, it is guaranteed to have a working define function. Inside the anonymous function, it simply calls the define function to create the module.

ES module: ECMAScript 2015, or ES6 module

After all the module mess, in 2015, JavaScript’s spec version 6 introduces one more different module syntax. This spec is called ECMAScript 2015 (ES2015), or ECMAScript 6 (ES6). The main syntax is the import keyword and the export keyword. The following example uses new syntax to demonstrate ES module’s named import/export and default import/export:

// Define ES module: esCounterModule.js or esCounterModule.mjs. import dependencyModule1 from "./dependencyModule1.mjs"; import dependencyModule2 from "./dependencyModule2.mjs"; let count = 0; // Named export: export const increase = () => ++count; export const reset = () => { count = 0; console.log("Count is reset."); }; // Or default export: export default { increase, reset };

To use this module file in browser, add a <script> tag and specify it is a module: <script type="module" src="esCounterModule.js"></script>. To use this module file in Node.js, rename its extension from .js to .mjs.

// Use ES module. // Browser: <script type="module" src="esCounterModule.js"></script> or inline. // Server: esCounterModule.mjs // Import from named export. import { increase, reset } from "./esCounterModule.mjs"; increase(); reset(); // Or import from default export: import esCounterModule from "./esCounterModule.mjs"; esCounterModule.increase(); esCounterModule.reset();

For browser, <script>’s nomodule attribute can be used for fallback:

<script nomodule> alert("Not supported."); </script>

ES dynamic module: ECMAScript 2020, or ES11 dynamic module

In 2020, the latest JavaScript spec version 11 is introducing a built-in function import to consume an ES module dynamically. The import function returns a promise, so its then method can be called to consume the module:

// Use dynamic ES module with promise APIs, import from named export: import("./esCounterModule.js").then(({ increase, reset }) => { increase(); reset(); }); // Or import from default export: import("./esCounterModule.js").then(dynamicESCounterModule => { dynamicESCounterModule.increase(); dynamicESCounterModule.reset(); });

By returning a promise, apparently, import function can also work with the await keyword:

// Use dynamic ES module with async/await. (async () => { // Import from named export: const { increase, reset } = await import("./esCounterModule.js"); increase(); reset(); // Or import from default export: const dynamicESCounterModule = await import("./esCounterModule.js"); dynamicESCounterModule.increase(); dynamicESCounterModule.reset(); })();

The following is the compatibility of import/dynamic import/export, from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules:

import compatibility

export compatibility

System module: SystemJS module

SystemJS is a library that can enable ES module syntax for older ES. For example, the following module is defined in ES 6syntax:

// Define ES module. import dependencyModule1 from "./dependencyModule1.js"; import dependencyModule2 from "./dependencyModule2.js"; dependencyModule1.api1(); dependencyModule2.api2(); let count = 0; // Named export: export const increase = function () { return ++count }; export const reset = function () { count = 0; console.log("Count is reset."); }; // Or default export: export default { increase, reset }

If the current runtime, like an old browser, does not support ES6 syntax, the above code cannot work. One solution is to transpile the above module definition to a call of SystemJS library API, System.register:

// Define SystemJS module. System.register(["./dependencyModule1.js", "./dependencyModule2.js"], function (exports_1, context_1) { "use strict"; var dependencyModule1_js_1, dependencyModule2_js_1, count, increase, reset; var __moduleName = context_1 && context_1.id; return { setters: [ function (dependencyModule1_js_1_1) { dependencyModule1_js_1 = dependencyModule1_js_1_1; }, function (dependencyModule2_js_1_1) { dependencyModule2_js_1 = dependencyModule2_js_1_1; } ], execute: function () { dependencyModule1_js_1.default.api1(); dependencyModule2_js_1.default.api2(); count = 0; // Named export: exports_1("increase", increase = function () { return ++count }; exports_1("reset", reset = function () { count = 0; console.log("Count is reset."); };); // Or default export: exports_1("default", { increase, reset }); } }; });

So that the import/export new ES6 syntax is gone. The old API call syntax works for sure. This transpilation can be done automatically with Webpack, TypeScript, etc., which are explained later in this article.

Dynamic module loading

SystemJS also provides an import function for dynamic import:

// Use SystemJS module with promise APIs. System.import("./esCounterModule.js").then(dynamicESCounterModule => { dynamicESCounterModule.increase(); dynamicESCounterModule.reset(); });

Webpack module: bundle from CJS, AMD, ES modules

Webpack is a bundler for modules. It transpiles combined CommonJS module, AMD module, and ES module into a single harmony module pattern, and bundle all code into a single file. For example, the following 3 files define 3 modules in 3 different syntaxes:

// Define AMD module: amdDependencyModule1.js define("amdDependencyModule1", () => { const api1 = () => { }; return { api1 }; }); // Define CommonJS module: commonJSDependencyModule2.js const dependencyModule1 = require("./amdDependencyModule1"); const api2 = () => dependencyModule1.api1(); exports.api2 = api2; // Define ES module: esCounterModule.js. import dependencyModule1 from "./amdDependencyModule1"; import dependencyModule2 from "./commonJSDependencyModule2"; dependencyModule1.api1(); dependencyModule2.api2(); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; export default { increase, reset }

And the following file consumes the counter module:

// Use ES module: index.js import counterModule from "./esCounterModule"; counterModule.increase(); counterModule.reset();

Webpack can bundle all the above file, even they are in 3 different module systems, into a single file main.js:

  • root
    • dist
      • main.js (Bundle of all files under src)
    • src
      • amdDependencyModule1.js
      • commonJSDependencyModule2.js
      • esCounterModule.js
      • index.js
    • webpack.config.js

Since Webpack is based on Node.js, Webpack uses CommonJS module syntax for itself. In webpack.config.js:

const path = require('path'); module.exports = { entry: './src/index.js', mode: "none", // Do not optimize or minimize the code for readability. output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, };

Now run the following command to transpile and bundle all 4 files, which are in different syntax:

npm install webpack webpack-cli --save-dev npx webpack --config webpack.config.js

AS a result, Webpack generates the bundle file main.js. The following code in main.js is reformatted, and variables are renamed, to improve readability:

(function (modules) { // webpackBootstrap // The module cache var installedModules = {}; // The require function function require(moduleId) { // Check if module is in cache if (installedModules[moduleId]) { return installedModules[moduleId].exports; } // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, require); // Flag the module as loaded module.l = true; // Return the exports of the module return module.exports; } // expose the modules object (__webpack_modules__) require.m = modules; // expose the module cache require.c = installedModules; // define getter function for harmony exports require.d = function (exports, name, getter) { if (!require.o(exports, name)) { Object.defineProperty(exports, name, { enumerable: true, get: getter }); } }; // define __esModule on exports require.r = function (exports) { if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); } Object.defineProperty(exports, '__esModule', { value: true }); }; // create a fake namespace object // mode & 1: value is a module id, require it // mode & 2: merge all properties of value into the ns // mode & 4: return value when already ns object // mode & 8|1: behave like require require.t = function (value, mode) { if (mode & 1) value = require(value); if (mode & 8) return value; if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; var ns = Object.create(null); require.r(ns); Object.defineProperty(ns, 'default', { enumerable: true, value: value }); if (mode & 2 && typeof value != 'string') for (var key in value) require.d(ns, key, function (key) { return value[key]; }.bind(null, key)); return ns; }; // getDefaultExport function for compatibility with non-harmony modules require.n = function (module) { var getter = module && module.__esModule ? function getDefault() { return module['default']; } : function getModuleExports() { return module; }; require.d(getter, 'a', getter); return getter; }; // Object.prototype.hasOwnProperty.call require.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // __webpack_public_path__ require.p = ""; // Load entry module and return exports return require(require.s = 0); })([ function (module, exports, require) { "use strict"; require.r(exports); // Use ES module: index.js. var esCounterModule = require(1); esCounterModule["default"].increase(); esCounterModule["default"].reset(); }, function (module, exports, require) { "use strict"; require.r(exports); // Define ES module: esCounterModule.js. var amdDependencyModule1 = require.n(require(2)); var commonJSDependencyModule2 = require.n(require(3)); amdDependencyModule1.a.api1(); commonJSDependencyModule2.a.api2(); let count = 0; const increase = () => ++count; const reset = () => { count = 0; console.log("Count is reset."); }; exports["default"] = { increase, reset }; }, function (module, exports, require) { var result; !(result = (() => { // Define AMD module: amdDependencyModule1.js const api1 = () => { }; return { api1 }; }).call(exports, require, exports, module), result !== undefined && (module.exports = result)); }, function (module, exports, require) { // Define CommonJS module: commonJSDependencyModule2.js const dependencyModule1 = require(2); const api2 = () => dependencyModule1.api1(); exports.api2 = api2; } ]);

Again, it is just another IIFE. The code of all 4 files is transpiled to the code in 4 functions in an array. And that array is passed to the anonymous function as an argument.

Babel module: transpile from ES module

Babel is another transpiler to convert ES6+ JavaScript code to the older syntax for the older environment like older browsers. The above counter module in ES6 import/export syntax can be converted to the following babel module with new syntax replaced:

// Babel. Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // Define ES module: esCounterModule.js. var dependencyModule1 = _interopRequireDefault(require("./amdDependencyModule1")); var dependencyModule2 = _interopRequireDefault(require("./commonJSDependencyModule2")); dependencyModule1["default"].api1(); dependencyModule2["default"].api2(); var count = 0; var increase = function () { return ++count; }; var reset = function () { count = 0; console.log("Count is reset."); }; exports["default"] = { increase: increase, reset: reset };

And here is the code in index.js which consumes the counter module:

// Babel. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // Use ES module: index.js var esCounterModule = _interopRequireDefault(require("./esCounterModule.js")); esCounterModule["default"].increase(); esCounterModule["default"].reset();

This is the default transpilation. Babel can also work with other tools.

Babel with SystemJS

SystemJS can be used as a plugin for Babel:

npm install --save-dev @babel/plugin-transform-modules-systemjs

And it should be added to the Babel configuration babel.config.json:

{ "plugins": ["@babel/plugin-transform-modules-systemjs"], "presets": [ [ "@babel/env", { "targets": { "ie": "11" } } ] ] }

Now Babel can work with SystemJS to transpile CommonJS/Node.js module, AMD/RequireJS module, and ES module:

npx babel src --out-dir lib

The result is:

  • root
    • lib
      • amdDependencyModule1.js (Transpiled with SystemJS)
      • commonJSDependencyModule2.js (Transpiled with SystemJS)
      • esCounterModule.js (Transpiled with SystemJS)
      • index.js (Transpiled with SystemJS)
    • src
      • amdDependencyModule1.js
      • commonJSDependencyModule2.js
      • esCounterModule.js
      • index.js
    • babel.config.json

Now all the ADM, CommonJS, and ES module syntax are transpiled to SystemJS syntax:

// Transpile AMD/RequireJS module definition to SystemJS syntax: lib/amdDependencyModule1.js. System.register([], function (_export, _context) { "use strict"; return { setters: [], execute: function () { // Define AMD module: src/amdDependencyModule1.js define("amdDependencyModule1", () => { const api1 = () => { }; return { api1 }; }); } }; }); // Transpile CommonJS/Node.js module definition to SystemJS syntax: lib/commonJSDependencyModule2.js. System.register([], function (_export, _context) { "use strict"; var dependencyModule1, api2; return { setters: [], execute: function () { // Define CommonJS module: src/commonJSDependencyModule2.js dependencyModule1 = require("./amdDependencyModule1"); api2 = () => dependencyModule1.api1(); exports.api2 = api2; } }; }); // Transpile ES module definition to SystemJS syntax: lib/esCounterModule.js. System.register(["./amdDependencyModule1", "./commonJSDependencyModule2"], function (_export, _context) { "use strict"; var dependencyModule1, dependencyModule2, count, increase, reset; return { setters: [function (_amdDependencyModule) { dependencyModule1 = _amdDependencyModule.default; }, function (_commonJSDependencyModule) { dependencyModule2 = _commonJSDependencyModule.default; }], execute: function () { // Define ES module: src/esCounterModule.js. dependencyModule1.api1(); dependencyModule2.api2(); count = 0; increase = () => ++count; reset = () => { count = 0; console.log("Count is reset."); }; _export("default", { increase, reset }); } }; }); // Transpile ES module usage to SystemJS syntax: lib/index.js. System.register(["./esCounterModule"], function (_export, _context) { "use strict"; var esCounterModule; return { setters: [function (_esCounterModuleJs) { esCounterModule = _esCounterModuleJs.default; }], execute: function () { // Use ES module: src/index.js esCounterModule.increase(); esCounterModule.reset(); } }; });

TypeScript module: Transpile to CJS, AMD, ES, System modules

TypeScript supports all JavaScript syntax, including the ES6 module syntax https://www.typescriptlang.org/docs/handbook/modules.html. When TypeScript transpiles, the ES module code can either be kept as ES6, or transpiled to other formats, including CommonJS/Node.js, AMD/RequireJS, UMD/UmdJS, or System/SystemJS, according to the specified transpiler options in tsconfig.json:

{ "compilerOptions": { "module": "ES2020", // None, CommonJS, AMD, System, UMD, ES6, ES2015, ES2020, ESNext. } }

For example:

// TypeScript and ES module. // With compilerOptions: { module: "ES6" }. Transpile to ES module with the same import/export syntax. import dependencyModule from "./dependencyModule"; dependencyModule.api(); let count = 0; export const increase = function () { return ++count }; // With compilerOptions: { module: "CommonJS" }. Transpile to CommonJS/Node.js module: var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; exports.__esModule = true; var dependencyModule_1 = __importDefault(require("./dependencyModule")); dependencyModule_1["default"].api(); var count = 0; exports.increase = function () { return ++count; }; // With compilerOptions: { module: "AMD" }. Transpile to AMD/RequireJS module: var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; define(["require", "exports", "./dependencyModule"], function (require, exports, dependencyModule_1) { "use strict"; exports.__esModule = true; dependencyModule_1 = __importDefault(dependencyModule_1); dependencyModule_1["default"].api(); var count = 0; exports.increase = function () { return ++count; }; }); // With compilerOptions: { module: "UMD" }. Transpile to UMD/UmdJS module: var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./dependencyModule"], factory); } })(function (require, exports) { "use strict"; exports.__esModule = true; var dependencyModule_1 = __importDefault(require("./dependencyModule")); dependencyModule_1["default"].api(); var count = 0; exports.increase = function () { return ++count; }; }); // With compilerOptions: { module: "System" }. Transpile to System/SystemJS module: System.register(["./dependencyModule"], function (exports_1, context_1) { "use strict"; var dependencyModule_1, count, increase; var __moduleName = context_1 && context_1.id; return { setters: [ function (dependencyModule_1_1) { dependencyModule_1 = dependencyModule_1_1; } ], execute: function () { dependencyModule_1["default"].api(); count = 0; exports_1("increase", increase = function () { return ++count; }); } }; });

The ES module syntax supported in TypeScript was called external modules.

Internal module and namespace

TypeScript also has a module keyword and a namespace keyword https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html#pitfalls-of-namespaces-and-modules. They were called internal modules:

module Counter { let count = 0; export const increase = () => ++count; export const reset = () => { count = 0; console.log("Count is reset."); }; } namespace Counter { let count = 0; export const increase = () => ++count; export const reset = () => { count = 0; console.log("Count is reset."); }; }

They are both transpiled to JavaScript objects:

var Counter; (function (Counter) { var count = 0; Counter.increase = function () { return ++count; }; Counter.reset = function () { count = 0; console.log("Count is reset."); }; })(Counter || (Counter = {}));

TypeScript module and namespace can have multiple levels by supporting the . separator:

module Counter.Sub { let count = 0; export const increase = () => ++count; } namespace Counter.Sub { let count = 0; export const increase = () => ++count; }

The the sub module and sub namespace are both transpiled to object’s property:

var Counter; (function (Counter) { var Sub; (function (Sub) { var count = 0; Sub.increase = function () { return ++count; }; })(Sub = Counter.Sub || (Counter.Sub = {})); })(Counter|| (Counter = {}));

TypeScript module and namespace can also be used in the export statement:

module Counter { let count = 0; export module Sub { export const increase = () => ++count; } } module Counter { let count = 0; export namespace Sub { export const increase = () => ++count; } }

The transpilation is the same as submodule and sub-namespace:

var Counter; (function (Counter) { var count = 0; var Sub; (function (Sub) { Sub.increase = function () { return ++count; }; })(Sub = Counter.Sub || (Counter.Sub = {})); })(Counter || (Counter = {}));

Conclusion

Welcome to JavaScript, which has so much drama - 10+ systems/formats just for modularization/namespace:

  1. IIFE module: JavaScript module pattern
  2. Revealing module: JavaScript revealing module pattern
  3. CJS module: CommonJS module, or Node.js module
  4. AMD module: Asynchronous Module Definition, or RequireJS module
  5. UMD module: Universal Module Definition, or UmdJS module
  6. ES module: ECMAScript 2015, or ES6 module
  7. ES dynamic module: ECMAScript 2020, or ES11 dynamic module
  8. System module: SystemJS module
  9. Webpack module: transpile and bundle of CJS, AMD, ES modules
  10. Babel module: transpile ES module
  11. TypeScript module and namespace

Fortunately, now JavaScript has standard built-in language features for modules, and it is supported by Node.js and all the latest modern browsers. For the older environments, you can still code with the new ES module syntax, then use Webpack/Babel/SystemJS/TypeScript to transpile to older or compatible syntax.

211 Comments

  • This is insane. Also you have a typo `mian.js`

  • I don't mean you're insane, just JS. Thanks for the summary.

  • @Derp I fixed the typo. Thank you!

  • Very helpful tutorial. I've found that the ES6 module pattern works well when using Javascript classes as well.

  • Nice. Thank you!

  • Excellent summary mate!

  • Once I was quite successful with AMD, requires is/was amazing back 2014.

    Today I'm optimistic with ES natively in the browser, script type module, I haven't figured out the tooling to optimize my js with this new way of using modules but it is definitely life changing.

    This article is very fun, thanks for taking the time to put it all together.

  • Excellent work, comprehensively covering this important and often confusing topic. Thank you - bookmarked!

  • Hi, many thanks for this post !! Very comprehensive guide with many examples. Things stands clear now for me ;)

    I think there is mini typo there:

    AMD’s ***require*** function has another overload. It accepts a callback function, and pass a CommonJS-like require function to that callback. So AMD modules can be loaded by calling require:

    It's *define* function that accepts a callback, not *require*.

  • This was a great historical overview -- thank you.

    A small typo: "Only 1 global variable is introduced, which is the modal name."

    I believe you meant to say "module name", not "modal name."

  • Excellent work, one of the best JS modules explanation article.
    Thank you!

  • @pomeh, @Brian, I fixed the typo. Thank you!

  • Thank you for sharing this helpful article, good content, beautiful images, hope you continue to post more articles.

  • Nicely written, appreciate you putting the effort on an example for each one.
    Thank you

  • Excellent, THX!

  • Great article, thanks!
    + Not sure this is intended or not, but seems "deependencyModule1" is a typo in "UMD for both AMD (RequireJS) and native browser" section. Should be "dependencyModule1"?

  • Try https://hqjs.org/ it is smart server that transform modules to ES6 format.

  • The article is very good and complete for me, the image and content I see are quite quality, hope that in the future you will continue to share more.

  • Thank you

    I just use webpack bundler, I dont know how those modules work.

    Thanks for the article, now we know, how the JavaScript was a mess and we improved.

  • Thanks for sharing the article it's a real helpful one, The article covering most of the important topics, and main parts of JavaScript.
    Nice work and keep posting.

  • so nice and perfect

  • thanks veryyy good

  • thanks for sharing
    also feel free to see
    Vishyat Technologies is one of the best Digital Marketing and SEO company in Chandigarh. Our expert SEO services in Chandigarh have helped a lot of business get better online exposure. SEO services Company in Amritsar,
    Seo Company In Punjab, SEO company in India, SEO COMPANY IN GURGAON
    Website: http://www.vishyat.com
    Email: contact(at)vishyat.com
    Contact: +91-935-461-6193, +917827890148




  • Assignments group is a rated among the top assignment help providers across the globe. We are providing Assignment writing help, Assignment writing Services.
    We provide the best online assignment help,services with quality assignments hand written by the experts which are most reliable. Assignment Group is the best choice for a online assignment help for a student as we never compromise with the quality of the assignments.Assignment help UK, Assignment writing Australia,We at assignments group provide assignments with 0% plagiarism. We go through the assignments written by experts multiple times and use high standard plagiarism checking softwares to ensure that your Online programming assignment help. is plagrism free. With us you will get 100% hand written assignment help.Assignment help UAE
    We give task Help to understudies over the globe of all space and everything being equal. Simply present your work and get instant help nowEssay writing services,thesis writing service, Dissertation writing service. Our Experts are 24x7 online to assist students with their assignments. We assist students with provides programming assignment help, Academic writing help, composing their expositions inside the given cutoff time. We have a group of article wrting specialists who help understudies to compose their exposition effectively and score top evaluations in thier scholastics.We are also Academic essay writers, Academic writers UK, Statistics assignments help

    https://assignmentsgroup.com/

  • Make your motorcycle more dynamic, powerful, faster. Upgrade your bike to more power using honda ruckus fatty wheel, honda ruckus fatty tire, ruckus fat wheel, honda ruckus handlebar, Honda dio rims, rggsjiso,honda ruckus rims set, hondadio af18 125cc, dio mag wheel. You can find all adjustments spare parts on tunescoot like 150cc gy6 fatty tire kit, hondadio wheels, alloy wheels for hondadio, hondadio back wheel rim price, dio rim price, honda ruckus handlebar stem, honda ruckus custom handlebars, honda ruckus aftermarket handlebars, dio alloy wheels, hondadio wheel rim, ruckus handlebar stem, jisorrgs, jisohondadio, hondadio mag wheels, hondadiojiso, dio wheel, gy6 fatty wheel, hondadio alloy wheel price, honda ruckus fat tire kit, ruckus fatty wheel, gy6 4 valve head, yamahazuma modified, 180cc big bore kit, hondadio af18 racing parts, yamaha jog exhaust, yamaha jog upgrades, honda ruckus clutch bell, suzukign 125 big bore kit, suzuki 125 big bore kit, gy6 180cc big bore kit, We offer a wide range of products honda ruckus fatty wheel, yamahayzf r125 180cc kit, 180cc gy6, gy6 63mm big bore kit, 180cc kit, suzukigs 125 big bore kit, gy6 fatty wheel, gy6 150cc 4 valve head, yamaha jog rr exhaust, gy6 4 valve head kit, hondacbr 125 r 180cc kit, 1p57qmj big bore kit, jog exhaust, yamahamt 125 180cc kit, 180cc gy6 horsepower, crf150r 180cc big bore kit, dr 125 big bore kit,
    These products can be used to adjust and tune your scooter or motorcycle gn 125 big bore kit, yamaha 3kj engine, gn 125 big bore kit, yamaha jog tuning, vino 125 big bore kit, jog 90, yamahadt 125 big bore kit, yamahazuma tuning, , uma 125 big bore kit top speed, 54mm bore kit for mio, stock bore mio i 125, yamahabws tuning, yamaha jog r tuning, yamaha jog rr tuning, jog r tuning, suzukign 125 big bore kit, dt 125 big bore kit, yamaha vino 125 big bore kit, jog 90 for sale, mio camshaft for 59mm bore, big valve mio, koso crankcase mio i 125, racing pulley for mio price, mio torque drive assembly, yamaha dt230 review, 59 big valve mio, mio 59 big valve, hondadio oil seal price, mtrt big valve for mio price, big valve mio sporty, 5vv big valve head for mio, big valve for mio sporty, spec v big valve for mio price, mtrt big valve, mio sporty big valve, mio sporty 59 big valve, mtrt big valve price, mtrt head big valve for sale, dio, dio125, ruckusracing dio, dio engine black edition
    We provide good quality spare parts and tuning products. Call us at +86 1306 884 49 00 or mail us at sales@tunescoot.site or visit our website https://tunescoot.site/

  • Your blog is great. I read a lot of interesting things from it. Thank you very much for sharing. Hope you will update more news in the future.

  • Hello, I'm Devin Wilson. I am working as a freelancer and expert to resolve an issue on Email. For instant support related to the Verizon Email Login Problem please contact our team for instant help.

  • Creative Monk is the best Seo Company in Chandigarh providing best seo services in chandigarh, India for all domains at an affordable price

  • defiant digital are number one <a href="https://defiantdigital.com.au/case-studies/">social media marketing company</a> in the globe. we provide lots of different services which can help your business digital appearance on top of search engine result page. so contact us for more information.

  • Anyone can explain to me how the JavaScript module pattern works? Also, what are the differences between the common js module and node.js module?

  • I’m extremely impressed together with your writing skills and also with your website. We are PROMINENT EXPORTS https://www.prominentexports.com/ has made a name for itself in the list of top Exporter and Suppliers of Metal planter in India, handicrafts manufacturers in India, Wall Hanging Accessories Organizer in India and also gardening items in India.
    I agreed your website is very good and helpful, I read helpful content in your website it will definitely helps in future.
    These are my another sites -
    https://coco-products.co.in/ https://www.coco-jute.com/

  • I’m still learning from you, but I’m making my way to the top as well. I absolutely enjoy reading everything that is posted on your website.Keep the aarticles coming. I liked it! <a href="https://www.totosite365.info" target="_blank" title="스포츠토토">스포츠토토</a>

  • May I simply just say what a relief to discover someone that actually knows what they are talking about online. You actually know how to bring an issue to light and make it important. A lot more people ought to look at this and understand this side of the story. It’s surprising you aren’t more popular given that you definitely possess the gift. <a href="https://www.slotmachine777.site" target="_blank" title="릴게임">릴게임</a>


  • thanks for sharing your thoughts with us. if you are searching <a href="https://www.bashaautohaus.com.au/">car repair sydney</a> you can contact Basha Autohaus. we are providing you all types of services like car paint, repairing, dent removal, etc. contact us for more details.

  • Very helpful content.

    watch this -

    https://maps.google.com/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.de/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.co.uk/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.co.jp/url?sa=t&url=https%3A%2F%2Fprominentexports.com/
    https://images.google.co.jp/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.co.jp/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.es/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.es/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.fr/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.ca/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.com.br/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.nl/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.nl/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.co.in/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.co.in/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.co.in/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.ru/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.com.br/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.com.br/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.com.au/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.ru/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.com.tw/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.com.hk/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.com.hk/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.pl/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.com.au/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.co.id/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.co.id/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.co.id/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://maps.google.com.tw/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.be/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://www.google.be/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.com/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.se/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/
    https://images.google.ch/url?sa=t&url=https%3A%2F%2Fwww.prominentexports.com/

  • Thanks for the great summary! Been trying to get myself acquainted with the evolution of JS modules. Thankfully will conclude with your article!

  • Please read my comment and visit our website

  • Please read my comment and visit our website

  • If you like, visit this site

  • Learning and understanding JavaScript has never been an easy task for me. I still remember my college days, when implementing a script was tough for me. But with time I am getting interested in it.

  • Global Edu Consulting Dehradun is acknowledged for offering the best boarding schools across India. Established as an educational consultant, Global Edu Consulting navigates the families towards vast Boarding schools options available.

  • Thanks for sharing
    also feel free to see
    Creative Monk is one of the best Digital Marketing and SEO company in Chandigarh. Our expert SEO services in Chandigarh have helped a lot of business get better online exposure.

  • Very Informative tutorial. I've found that the ES6 module pattern works well when using JavaScript classes as well.

  • Nice to meet you. I read the text well. I have good information.
    <a href="https://https://weareexitmusic.com/" target="_blank" title="먹튀검증">먹튀검증</a>

  • Hello, thank you for the good information.
    I have good information. I want to take a look.
    <a href="https://crozetpizza.net">토토사이트</a>

  • Hi I read the article well
    I also have good information. Take a look
    <a href="https://euro-fc.com" target="_blank" title="안전놀이터">안전놀이터</a>

  • It's cold
    Take good care of your body. I have good information.
    <a href="https://imaginemegame.com" target="_blank" title="파워볼">파워볼</a>

  • Hi I read the article well
    I also have good information. Take a look
    <a href="https://www.euro-fc.com">안전놀이터추천</a>

  • It's cold
    Take good care of your body. I have good information.
    <a href="https://www.imaginemegame.com">파워볼사이트</a>

  • Hello, thank you for the good information.
    I have good information. I want to take a look.
    <a href="https://crozetpizza.net">토토사이트모음</a>

  • Nice to meet you. I read the text well. I have good information.
    <a href="https://weareexitmusic.com/">검증놀이터</a

  • Many thanks for your valuable content. You are an inspiration with your hard work.\

    Keep up the awesome work and know that you’re appreciated!

    Thanks,
    Anu Thakur

  • what a usefull blog, thanks for this fell free to See us - https://gardendeco.in We are Best
    <a href="https://gardendeco.in">Online Garden Store</a> In India


    <a href="https://gardendeco.in">Garden Accessories Online</a>
    <a href="https://gardendeco.in">Garden Decor Online in India</a>

  • Hello sir, you have such a good concept of javascript. It will help our web development projects.

  • Solutions 1313 best SEO Company in Chandigarh will provide you with the best SEO services and also help you to find the best leads and engagements. Our SEO experts will provide you with the best guidelines for your business growth.

  • Chandan Hospital is offering you the best Vaginal Rejuvenation Treatment in Chandigarh that will help women to increase the flexibility of the skin around their vagina. We have a team of experienced and professional doctors. You can contact us anytime for the treatment.

  • Sunil Kumar is considered one of Punjab’s leading astrologers. You can consult him through phone calls, and chat and can get the answers to astrology, numerology, Vastu, etc. related questions. He is available 24*7 days so contact him any time.

  • Daebak! that’s what I was looking for, what a information! present here at this website

  • This article presents clear idea designed for the new visitors of blogging, that in fact how to do blogging and site-building.

  • Article writing is also a fun, if you know then you can write otherwise it
    is complex to write.Look at my site

  • Thanks designed for sharing such a pleasant thinking, piece of writing is good, thats why i have read
    it entirely

  • Good write-up, I am normal visitor of one抯 web site, maintain up the nice operate, and It is going to be a regular visitor for a lengthy time.

  • I know this web site gives quality based posts and other data, is there any other web page which gives such stuff in quality? 파워볼 하는법

  • Hey Dixin's,

    The article is very well written and explained precisely with deep insights. Thanks for writing this article.

  • Games MOBA Offline Android Terbaik - Salah satunya selingan yang sangat menarik dan yang terpopuler ialah Games. Sekarang ini memang banyak ada tipe dan tipe games, dimulai dari games RPG, games perang sampai games penjelajahan. Tiap games mempunyai feature dan serunya sendiri, hingga sering bila beberapa orang yang ketagihan games.

  • Nice Info :)

  • I am really impressed with your blog article, such great & useful information you mentioned here. I have read all your posts and all are very informative. Thanks for sharing and keep it up like this.

  • I just got to this amazing site not long ago. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page

  • Ennoble Infotech is the Best Digital Marketing Company in Chandigarh, providing seo, smo, orm, gmb & web development services. Our professional SEO services in Chandigarh have helped a lot of business get better online exposure.

  • Thanks for sharing the informative post. If you are looking the Linksys extender setup guidelines . so, we have a best technical expert for handlings your quires. for more information gets touch with us.

  • nice information.

  • Great article! That kind of information is shared on the internet. Come and consult with my website. Thank you!<a href="https://www.thekingcasino.top" target="_blank" title="바카라사이트">바카라사이트</a>

  • Your work is very good and I appreciate you and hopping for some more informative posts. Thank you for sharing great information to us.<a href="https://www.wooricasino.top" target="_blank" title="바카라사이트">바카라사이트</a>

  • What’s up every one, here every one is sharing these kinds of knowledge, so it’s nice to read this webpage, and
    I used to pay a quick visit this weblog everyday<a href="https://www.pharaohcasino.net" target="_blank" title="바카라사이트">바카라사이트</a>

  • I am really pleased to glance at this web site posts which carries tons of useful information, thanks for providing these
    kinds of statistics.<a href="https://www.badugisite.net" target="_blank" title="바둑이게임">바둑이게임</a>

  • I am really pleased to glance at this web site posts

  • Thank you for sharing such great information

  • Amazing article, as always! Thanks for all the solid gold advice.

  • Thank you for the post.

  • Valuable info. Lucky me I found your website by accident. I bookmarked it. This article is genuinely good and I have learned lot of things from it concerning blogging. thanks.

  • This article presents clear idea designed for the new visitors of blogging, that in fact how to do blogging and site-building.

  • Thanks designed for sharing such a pleasant thinking, piece of writing is good, thats why i have read it entirely

  • You actually make it seem so easy with your presentation but I find this matter to be really something that I think I would never understand. It seems too complicated and very broad for me. I’m looking forward for your next post, I will try to get the hang of it!

  • Most of whatever you assert is astonishingly legitimate and it makes me ponder the reason why I hadn’t looked at this with this light before. This particular piece truly did turn the light on for me personally as far as this issue goes. Nevertheless there is actually one factor I am not too comfortable with so whilst I make an effort to reconcile that with the core theme of your position, allow me observe just what all the rest of the readers have to say.Well done. Visit my website too we have a lot to offer!

  • thanx you admin...

  • Thank you for sharing it's a really greatful article and it's very helpful.

  • <a href="https://ardaasfilms.com">best digital marketing agency</a>

  • Vary Good Information Share..
    <a href="http://www.sattamatkagod.com/">220 patti</a>

    Good Post, I am a big believer in posting comments on sites to let the blog writers know that they’ve added something advantageous to the world wide web satta matka and indian matka and matka boss..<a href="http://www.sattamatkagod.com/">Matka Guessing</a>



    losing money and 100% possibility of winning the money.
    <a href="https://www.sattamatkagod.com/">satta matka</a>
    is an exceptionally renowned game of India, which nearly everybody









    The Best Website For Online Satta Matka Result

    <a href="https://www.sattamatkagod.com/">
    Satta matka | kalyan | satta matta matka |matka result | satta batta | matka guessing |Satta Live | kalyan matka | kalyan | matka tips | today satta number | matka chart | indian matka | satta chart | madhur matka | aaj ka satta</a>

  • Nice post it’s useful and very informative, keep up the good work.

  • Good article!

    I will follow you to create useful articles like this 🙂

  • Nice.

    Always remember this

  • Your work is very good and I appreciate you and hopping for some more informative posts. Thank you for sharing great information to us

  • This is wonderful website to find blogs on various topics. Really liked your work and has been following it for a long time now. I basically work for a website which provide technology solutions for students who are unable to do so. Therefore, it is necessary for me to be aware of almost all the topics under the sun.

  • Very good written information. It will be valuable to anybody who employees it, as well as yours truly :). Keep up the good work ? for sure i will check out more posts.

  • Magnificent beat ! I wish to apprentice while you amend your web site, how could i subscribe for a blog web site?
    The account aided me a acceptable deal. I had been a little bit acquainted
    of this your broadcast provided bright clear concept

  • I am really impressed with your blog article, such great & useful information you mentioned here. I have read all your posts and all are very informative. Thanks for sharing and keep it up like this.

  • I feel this is among the most vital info for me. And i am happy reading your article. But want to remark on few general things, The web site taste is perfect, the articles is in point of fact great : D. Excellent task, cheers

  • I recently found many useful information in your website especially this blog page. Among the lots of comments on your articles. Thanks for sharing

  • Your blog is great. I read a lot of interesting things from it. Thank you very much for sharing. Hope you will update more news in the future.

  • Just a smiling visitor here to share the love (:, btw outstanding layout.

  • Thank you for sharing this useful article. Keep it up! Regards!
    <a href="https://www.casinosite777.info" target="_blank" title="바카라사이트">바카라사이트</a>

  • Your article is very interesting. I think this article has a lot of information needed, looking forward to your new posts.
    <a href="https://www.baccaratsite.top" target="_blank" title="카지노사이트">카지노사이트</a>

  • Thank you for providing a good quality article.
    <a href="https://www.sportstoto.zone" target="_blank" title="토토">토토</a>

  • Excellent Blog! I would like to thank you for the efforts you have made in writing this post.
    <a href="https://www.baccaratsite.biz" target="_blank" title="바카라사이트">바카라사이트</a>

  • If you are looking for Aqua water purifier, you can refer to our site to buy.

  • If you are looking for Aqua water purifier, you can refer to our site to buy.



  • Raj International Cargo Packers and Movers |7790012001
    Packers and Movers in Zirkapur , Feel free to contact us at info@rajpackersmovers.net Our contact numbers +91-9878957562 +91-7790012001 http://rajpackersmovers.net
    Mohali, Panchkula, Zirkapur, Chandigarh
    If you are looking Packers and Movers in Chandigarh have set up an office full of experts that will grab entire your tensions concerning the move far away letting you trouble free at the time of complete relocation
    The team members are completely aware of the handling of all sorts of commercial, residential, business and industrial relocation services.
    movers and packers services in Zirkapur , Zirkapur ,near area Chandigarh Welcome To Raj International Cargo Packers and Movers is a name of best Packers and Packers in Zirkapur . Raj International Cargo Packers and Movers provides various services such as Domestic Moving, International Moving, Home Storage, Car Carriers.packers and movers services in zirakpur
    movers and packers in delhi.cheap packers and movers in Zirkapur
    Raj Packers and Movers is an initiative to simplify people’s lives by providing an array of personalized services at their fingertips and then at their doorstep. Carriers Packers and movers zirkapur and best packers and movers in zirakpur.Raj International Cargo Packers and Movers in Ambala make it easier for you in the most cost-effective wayPackers and Movers in Chandigarh
    movers and packers services in Chandigarh , Zirkapur ,near area Chandigarh Welcome To Raj International Cargo Packers and Movers is a name of best Packers and Packers in Chandigarh . Raj International Cargo Packers and Movers provides various services such as Domestic Moving, International Moving, Home Storage, Car Carriers.packers and movers services in Chandigarh
    movers and packers in delhi.cheap packers and movers in Chandigarh
    Transportation, Supply Chain, Ware Housing, Exim Cargo, ODC Transportation, Infrastructure, Air Terminal Management, Record Management etc. you can simplify the moving process and turn the situation into an easygoing and smooth affair.Raj Packers and Movers is an initiative to simplify people’s lives by providing an array of personalized services at their fingertips and then at their doorstep. Carriers Packers and movers zirkapur and best packers and movers in Chandigarh .Raj International Cargo Packers and Movers in Ambala make it easier for you in the most cost-effective way.

  • درآموزش تعمیرات برد های الکترونیکی به شما نحوه تعمیرات انواع بردهای لوازم خانگی، تعمیرات بردهای صنعتی، تعمیرات برد پکیج، تعمیرات برد کولر گازی، تعمیرات برد اینورتر و ... آموزش داده خواهد شد.
    https://fannipuyan.com/electronic-boards-repair-training/

  • ما به عنوان دبستان غیر دولتی پیشرو برای اولین بار در ایران با ارائه طرح کیف در مدرسه توانستیم گام به گام با آموزش نوین دنیا پیش رفته و کیفیت آموزش را ارتقا بخشیم و توانایی کودکانمان را در تمامی مهارت های زندگی مانند ایجاد تفکر واگرا و همگرا ، قدرت حل مسئله ، مسئولیت پذیری ،عزت نفس و توجه و تمرکز در آنان ایجاد نموده و در آموزش کامپیوتر و زبان انگلیسی که از مهارت های بسیار لازم فردای کودکانمان است همواره پیشگام بوده ایم.
    http://pishroschool.ir/

  • An outstanding post! This guide gives me all the info to get started with JavaScript module syntax. I appreciate every step you shared.

  • i like this blog very much its a ratting nice situation to click here <a href="https://www.badugisite.net" target="_blank" title="바둑이게임">바둑이게임</a>

  • I like the valuable information you provide in your articles.<a href="https://www.pharaohcasino.net" target="_blank" title="카지노사이트">카지노사이트</a>

  • Thank you for providing a good quality article. If you’ve ever thought about giving it a try, just click it!

  • Very good. I love to read your page dear continue. Also play our game:

  • I like this website its a master peace ! Glad I found this on google .
    I must say, as a lot as I enjoyed reading what you had to say, I couldn't help but lose interest after a while.

  • Your website is really cool and this is a great inspiring article.

  • It is very lucky to me to visit your website. We hope you continue to publish great posts in the future.

  • This is by far the best post I've seen recently. This article, which has been devoted to your efforts, has helped me to complete my task.

  • Thanks for Sharing the valuable information with us.

  • All is good you did here. Learn about traditional home mortgages, adjustable rate mortgages, home equity loans & lines-of-credit available at KEMBA Financial Credit Union. An Adjustable Rate Mortgage (ARM) provides you the option of a rate that changes based on the current market.

  • <p><u><a href="https://www.lsjewels.co.nz/">https://www.lsjewels.co.nz</a></u></p>
    <p>L.S jewels corner is an online website for <a href="https://www.lsjewels.co.nz/about_us">artificial jewellery online</a> shopping for women. Nowadays, wearing jewelry is not just adding glamour to your appearance but also it states your sense of style. If you are in search of imitation jewelry that will give stylish touch to your outlook, then you&rsquo;re at right place. If you are looking for <a href="https://www.lsjewels.co.nz/">jewellery online shopping</a>. The biggest advantage of imitation jewelry is that it is not that expensive as real gold, silver and diamond. Imitation jewelry gives you an opportunity to buy variety of jewelry in comparison buying expensive gold or <a href="https://www.lsjewels.co.nz/american_diamond_necklace_silverdrop">american diamond jewellery online shopping</a>. Our highly skilled workforce and experts try hard to ensure you get the maximum satisfaction while acquiring our products.<a href="https://www.lsjewels.co.nz/buy_traditional_indian_jewellery_bangles_online_nz">best indian jewellery</a></p>
    <p>&nbsp;</p>


  • <url="https://www.lsjewels.co.nz/">https://www.lsjewels.co.nz</url>
    L.S jewels corner is an online website for <url="https://www.lsjewels.co.nz/urlbout_us">artificial jewellery online</url> shopping for women. Nowadays, wearing jewelry is not just adding glamour to your appearance but also it states your sense of style. If you are in search of imitation jewelry that will give stylish touch to your outlook, then you&rsquo;re at right place. If you are looking for <url="https://www.lsjewels.co.nz/">jewellery online shopping</url>. The biggest advantage of imitation jewelry is that it is not that expensive as real gold, silver and diamond. Imitation jewelry gives you an opportunity to buy variety of jewelry in comparison buying expensive gold or <url="https://www.lsjewels.co.nz/urlmerican_diamond_necklace_silverdrop">american diamond jewellery online shopping</url>. Our highly skilled workforce and experts try hard to ensure you get the maximum satisfaction while acquiring our products.<url="https://www.lsjewels.co.nz/buy_traditional_indian_jewellery_bangles_online_nz">best indian jewellery</url>

  • After filing their brief the lawyers for iMEGA went public on why they claimed that the Commonwealth of Kentucky's actions were wrong. Jon Fleischaker, counsel for iMEGA, said, ☞ <a href="https://www.topseom114.net/" target="_blank" title="바카라사이트">바카라사이트</a>

  • thanks for sharing this valuable content with us

  • Nice post love it check my site for fast <a href="https://sattaking.vip/">Satta King</a> we provide superfast and all time result <a href="https://sattaking.vip/">SattaKing</a>

  • Your article is so nice, thanks for sharing this information.

  • I am so grateful for your blog.Really looking forward to read more. Really Great.

  • خرید زیورآلات

  • فروشگاه اینترنتی زدشاپ

  • if you are looking for a pet shop dog for your animal just check our site.

  • This article is really fantastic and thanks for sharing the valuable post.

  • Wow! Thank you! I permanently wanted to write on my blog something like that.

  • Great Post !! Very interesting topic will bookmark your site to check if you write more about in the future.

  • This post is really astounding one! I was delighted to read this, very much useful. Many thanks

  • Thanks for sharing.I found a lot of interesting information here. A really good post, very thankful and hopeful that you will write many more

  • Great Article it its really informative and innovative keep us posted with new updates. its was really valuable. 

  • Thanks for writing such a good article, I stumbled onto your blog and read a few post. I like your style of writing...

  • Very interesting topic will bookmark your site to check if you Post more about in the future.

  • Huawei started their journey in January 2014 with four phones in Bangladeshi market. Day by day they're trying to work out their showrooms and authorized dealers altogether over Bangladesh. they have to compete with the most Chinese brands like Xiaomi.
    Huawei Advantages and Disadvantages
    Huawei is building up its own portable working framework to possibly supplant Google's Android on a portion of its gadgets. Huawei's working framework is known by the inner code name "Hongmeng" and might be discharged as Ark OS, yet these names are not affirmed by Huawei.
    • Android OS: Huawei is among the foremost seasoned makers of telephones which they serve a worldwide market delivering alongside Huawei Mobile Price in Bangladesh an honest assortment of contraptions going from enormous touch screen mobile phones to old advancements and QWERTY button models.

  • اگر به دنبال خرید لوازم خانگی اقساطی هستید می توانید به سایت ما مراجعه فرمایید.

  • HERO Bike is a two-or three-wheeled motor vehicle. There are three foremost types of motorcycles: street, off-road, and dual purpose. Within these types, there are many sub-types of motorcycles for unique purposes. There is regularly a racing counterpart to every type. Each configuration affords either specialized advantage or wide capability, and every plan creates a specific driving posture.
    Hero Bike Blessings or Disadvantages:
    HERO two is amongst the most pro makers of bikes and they serve a global market turning in alongside <a href="https://www.bikevaly.com/hero/">Hero Bike Price in Bangladesh</a> a broad assortment of contraptions going from satisfactory models. A portion of the professionals have included the accompanying and so on too.

  • Satta Matka or simply Matka is Indian Form of Lottery. Matkaoffice.net is world's fastest matka official website. Welcome to top matka world <a href=https://matkaoffice.net/
    >SATTA</a> MATKA, satta matka, kalyan.

  • Thanks for a nice post. I really really love it. It's so good and so awesome Satta Matka or simply Matka is Indian Form of Lottery. Matkaoffice.net is world's fastest matka official website. Welcome to top matka world <a href=https://matkaoffice.net/
    >SATTA MATKA</a>satta matka, kalyan.

  • Since the start of cell phones in Bangladesh, Nokia is the most well-known brand. Nokia wins the individuals' trust of all phases with Nokia Mobile Price in BD.
    • Get information of reasonable cost, fantastic highlights, appealing plan, and most strikingly simple to utilize. Through HMD Global, Nokia telephones are conveyed in Bangladesh.
    Nokia's mid and high range Information
    Since highlight Information, time in Bangladesh we accomplish customer's trust by presenting Nokia 3310, Nokia 105, etc.
    • These days, as low range information like Nokia 2, and Nokia 2.1 are the best Nokia cell phones in Bangladesh.
    • The brand's most recent cell phone is Nokia 2.3 with Quad-center 2.0 GHz Cortex-A53 processor.
    • Be that as it may, Nokia's mid and high scope of telephones are notable for their exhibition.

  • I am very happy to revisit your blog. Thanks to your posting, I am getting useful information today. Thank you for writing a good article.

  • The Enterprise Solutions helps offer a broad scope of Nokia items and arrangements that include grading the endeavor, gadgets for the mobile, security highlight and infrastructure, programming, and administrations.

    Wherever to get the best Nokia mobile phone, you should search on Google by writing <a href="https://www.mobiledor.co/brand/nokia/">Nokia Mobile Price in BD</a>. Hope you find the best mobile phone for you.

  • I am regular visitor, how are you everybody?

    This post posted at this web page is truly good. https://www.sportstoto.top

  • Wow, fantastic blog layout! How long have
    you been blogging for? you made blogging look easy.
    The overall look of your website is excellent, as well as the content!

  • Wonderful article! We will be linking to this great article
    on our site. Keep up the good writing.

  • Every weekend i used to visit this web page, for the reason that i want enjoyment, as this this
    web site conations truly pleasant funny information too.

  • Wonderful beat ! I would like to apprentice at the same
    time as you amend your web site, how can i subscribe for a weblog web site?
    The account aided me a applicable deal. I were a
    little bit acquainted of this your broadcast provided vivid clear concept

  • Thanks for sharing this wonderful post with us and hoping that you will continue doing this job on the daily basis to guide us in a better way. <a href="https://www.ufabet1688x.com/">ufabet1688</a>

  • New Life Foundations is known as one of the most reliable Nasha Mukti Kendra in Sangrur. We provide a perfect environment for the addicts and make it easy for them to quit the drugs.

  • Thanks for a nice post. I really love it. It's so good and so awesome. Satta Matka or simply Matka is Indian game. Matkaoffice.net is world's fastest matka official website. Welcome to top matka world <a href= https://sattamatkalive.com/
    >SATTA MATKA</a>satta matka.

  • Really this is a good submit. I m happy that finally someone writes about it.

  • I got great blog here which is very excellent.

  • I am really really impressed with your writing skills as well as with the layout on your blog.

  • Your site has a wide collection of fantastic blogs that helps a lot.

  • Wonderful experience while reading your blog.

  • I am really really impressed with your writing skills as well as with the layout on your blog.

  • I have read so many articles and the blogs but your post is genuinely a good post. Keep it up!

  • Yes! this is absolutely right blog for those who are looking for the relevant information and who wishes for it.

  • I got great blog here which is very excellent.

  • Really this is a good submit. I m happy that finally someone writes about it.

  • Thanks for providing this information. Really interesting info!! Get today's local news on all topics including technology, business, fashion, food, travel, shopping, health, education, and much more on Times News Blog. Please visit https://timesnewsblog.com for more information.

  • Best SEO company in Mohali .

  • Nice blog here! Also your web site loads up fast! What web host are you using? Can I get your affiliate link to your host?

  • Wow, amazing blog layout! How long have you been blogging for?
    you made blogging look easy. The overall look of your site is
    wonderful, as well as the content!

  • Thanks for sharing this article. This article was very helpful to me. Keep moving.

  • Your article looks really adorable, here’s a site link i dropped for you which you may like. <a href="https://www.totosite365.info" target="_blank" title="totosite365.info">totosite365.info</a>

  • After study a number of the web sites for your site now, i really such as your strategy for blogging. I bookmarked it to my bookmark website list and will be checking back soon 텍사스홀덤사이트 텍사스홀덤 홀덤 포커게임

  • Thank you. I authentically greeting your way for writing an article. I safe as a majority loved it to my bookmark website sheet list and will checking rear quite than later. Share your thoughts. | 파칭코사이트인포 파칭코 파친코 슬롯머신

  • Fantastic work! This really can be the kind of data which needs to really be shared round the internet. Shame on Google for perhaps not placement this specific informative article much higher! 슬롯머신777사이트 슬롯머신사이트 슬롯머신 릴게임

  • I’ve a project that I am just now working on, and I have been on the look out for such information.
    블랙잭사이트 카지노사이트 바카라사이트 온라인카지노

  • Sigma Cabinets is known as one of the leading Kitchen Cabinet Design companies in Vancouver. We have more than a decade of experience in the industry and providing the best kitchen design services to clients.

  • This article has really helped me in understanding all javascript module formats :)

  • Truly enjoyed browsing your blog posts. Having read this I believed it was rather informative.

  • Truly enjoyed browsing your blog posts. Having read this I believed it was rather informative.

  • hi guys. if you are looking for a buy home in a turkey just visit our site.

  • I was really amazed reading this,how they come up for this idea, anyway thankyou author for this

  • It would bring high impact to the reader and could bring life changing by knowing it.

  • I am incapable of reading articles online very often, but I’m happy I did today. It is very well written, and your points are well-expressed. I request you warmly, please, don’t ever stop writing.

  • nice

  • good blos

  • this is a awsome blogs man

  • keep love you

  • Greetings, dear blog owners and writer friends, we love your team as our company, the articles you write smell of quality and we will be following you all the time. Thanks for everything, we liked this article as usual.

  • Hello, I enjoy reading through your article post. I like to write a little comment to support you.

  • Excellent post! We will be linking to this great content on our skull rings web site. Keep up the good writing.


  • Thank you ever so for you blog post. Really thank you!

  • There is certainly a lot to learn about this topic. I really like all the points you made.

  • Glad to see this kind of brilliant and very interesting informative post. Best view i have ever seen !

  • Hey there, You’ve done an incredible job. I’ll definitely digg it
    and for my part suggest to my
    friends. I am confident they will be benefited from this site.|<a href="https://jusoyo1.5to.me" rel="nofollow">성인주소모음</a><br>


  • Every weekend i used to pay a quick visit this web site, because i want enjoyment, for the reason that this this
    web page conations really nice funny data too.<a href="https://haebam.com" rel="nofollow">해외선물커뮤니티</a><br>

  • Hey there, You’ve done an excellent job. I will definitely dig it and personally suggest to my friends. I’m confident they will be benefited from this website.

  • Pretty nice post. I just stumbled upon your weblog and wished to say that I’ve truly enjoyed browsing your blog posts. After all I will be subscribing to your rss feed and I hope you write again soon! <a href="https://www.ufabet1688x.com/">ยูฟ่าเบท</a>

  • I do trust all the ideas you have offered on your post. They are very convincing and can certainly work. Nonetheless, the posts are very quick for beginners. May you please extend them a little from next time? thanks you for the post.
    <a href="https://www.sportstoto365.com" target="_blank" title="토토사이트">토토사이트</a>

  • I can read all the opinions of others as well as i gained information to each and everyone here on your site. Just keep on going dude. Check over here: home

  • Looking at this article, I miss the time when I didn't wear a mask. https://mtboan.com/ 먹튀검증업체 Hopefully this corona will end soon. My blog is a blog that mainly posts pictures of daily life before Corona and landscapes at that time. If you want to remember that time again, please visit us.

  • Hello, I'm happy to see some great articles on your site. Would you like to come to my site later? My site also has posts, comments and communities similar to yours. Please visit and take a look <a href="https://remarka.kz/">토토사이트</a>

  • In the meantime, I wondered why I couldn't think of the answer to this simple problem like this. Your article is an article that gives the answer to all the content I've been contemplating. <a href="https://remarka.kz/">메이저토토사이트</a>

  • It’s a pity you don’t have a donate button! I’d certainly donate to this excellent blog! I suppose for now i’ll settle for bookmarking and adding your RSS feed to my Google account. I look forward to fresh updates and will share this website with my Facebook group

  • I've been looking for photos and articles on this topic over the past few days due to a school assignment, and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks :D <a href="https://mtygy.com/">먹튀신고</a>

  • Excellent article. Keep posting such kind of info on your site. Im really impressed by your blog. Hey there, You’ve done a great job. I’ll definitely digg it and for my part suggest to my friends. I am confident they’ll be benefited from this website

  • Going with the best print companions is no lower than a prime
    requisite. You will need to figure out their offerings, range of print modern technologies,
    as well as ultimate shipment procedure. Connecting with the most effective Three-dimensional printing agency Company will definitely be
    actually of extremely important value hereof. That will certainly give you the option to fulfill your professional needs within designated deadlines.
    Very most notably, you are going to obtain specialist premium prints which
    will help you gain more customers than in the past.

  • Thanks for sharing this informative blog

  • It's really great blog

  • Thanks for this Genuine Information

  • Superfine Construction is an independent company that has more than a decade of experience providing fully managed solutions for all your interior needs. We offer a first-class service from designing to completion of your project.

  • Heya i’m for the primary time here. I came across this board and I to find It truly helpful & it helped me out much. I hope to offer one thing back and aid others like you aided me

  • Thanks for sharing that information, <a href="https://geekstechi.org/">Geek Squad Tech Support</a> is a globally recognized tech support provider, providing various support services for personal computer, gadgets, home repair and much more. We have successfully provided support services for nearly two million customers and the count has been increasing every other day.
    Please follow this link to know more about PayPal Account Login.
    <a href="https://sites.google.com/view/paypalemaillogin">PayPal Account Login</a> is one of the best, user-friendly payment platforms. Moreover, it facilitates payments that take place via online transfers between different parties.

Add a Comment

As it will appear on the website

Not displayed

Your website