DEV Community

Cover image for Back to the Front-end: Exploring the Future of the Umbraco UI (Part 6 - ES Modules)
Matt Brailsford
Matt Brailsford

Posted on

Back to the Front-end: Exploring the Future of the Umbraco UI (Part 6 - ES Modules)

So in the last blog post we introduced Vite and briefly mentioned that it is based around ES Modules, however as this isn't a concept most will be using in the current Angular Umbraco UI, I thought this probably deserved a post of it's own.

About ES Modules

Essentially, ES Modules are the ECMAScript standard for working with modular code. It is often simplified to the import/export syntax, and similar to Web Components, offers us another form of "encapsulation".

Prior to ES Modules, scripts loaded into a page / application would be globally accessible, meaning all variables, functions and classes defined in them could be accessed by any other script running on the page, and vica versa.

ES Modules however are executed in their own scope, and only varibles, functions and classes explicitly exported would be externally visible. Conversly, these are only consumed when they are explicitly imported in the consuming code base.

Defining a Module

ES Modules are regular old JavaScript files, but have one or more root level import and/or export statements.

Any JavaScript that contains at least one root level export will automatically be assumed to be a module by the runtime. If there are no root level export statements, then the runtime will treat the file as a regulard script file.

Exporting

Any root level variable, class or function prefixed with the export keyword will become visible to consumers. All root level variables, classes or functions without the export keyword will only be accessible within the module itself.

// @filename: math.js

// Example private variable
const startIndex = 0;

// Example private fuction
function add(num1, num2) {
  return num1 + num2;
}

// Example variable export
export const pi = 3.142;

// Example class export
export class RandomNumberGenerator {}

// Example function export
export function absolute(num) {
  if (num < 0) return num * -1;
  return num;
}
Enter fullscreen mode Exit fullscreen mode

As per the example above, ES Modules can contain multiple exports. ES Modules can also declare a default export with the export default prefix

// @filename: hello.js

// Example default export
export default function helloWorld() {
  console.log("Hello, world!");
}
Enter fullscreen mode Exit fullscreen mode

Importing

To consume a variable, class or function exported by another module, we can import them at the top of our script.

// Import exports from the math module
import { pi, absolute } from "./maths.js";

// Use the imported variables / functions
console.log(pi);
console.log(absolute(pi));
Enter fullscreen mode Exit fullscreen mode

If we just want to import the default export of a module, the curly braces are no longer required:

// Import the default export of the hello module
import helloWorld from "./hello.js";

// Execute the function
helloWorld();
Enter fullscreen mode Exit fullscreen mode

If you need to import both a default export, and one or more non default exports, these can be combined in the import statement

// @filename: maths.ts
export const pi = 3.14;
export default class RandomNumberGenerator {}

// @filename: app.ts
import RandomNumberGenerator, { pi } from "./maths.js";
Enter fullscreen mode Exit fullscreen mode

Import Aliasing

If an import would conflict with a locally declared resource, or you'd prefer to access it via an alternative name, you can alias a an import with the following syntax

// Import the pi variable from the math module, but use the local alias `π`
import { pi as π } from "./maths.js";

// Use our imported variable by it's alias
console.log(π);
Enter fullscreen mode Exit fullscreen mode

Import All Exports

You can also import all exports of a module into a single namespace with the following syntax.

// Import all exports from the math module, giving the a `math` namespace
import * as math from "./maths.js";

// Use an imported resource prefixed with the namespace
console.log(math.pi);
Enter fullscreen mode Exit fullscreen mode

Conclusion

There is more that you can do with ES Modules, but I think this covers the core use cases that most will need day to day.

Coming from a C# background the import syntax is not that disimilar to the using syntax so it's not an entirely new concept.

Nevertheless, this is likely to be relatively new to those who are only familiar with extending the back office in Angular so it's yet another concept you will need to get to grips with.

Additional Resources

Top comments (0)