JavaScript Module (ES Module)
TcHmi Framework Controls were developed up to version 1.14 in so-called namespace. See Base framework of a control.
namespace TcHmi.Controls {
export namespace FrameworkPrj1 {
export class FrameworkPrj1Control extends TcHmi.Controls.System.TcHmiControl {This Typescript syntax ensures that the class can be accessed in the browser at TcHmi.Controls.FrameworkPrj1.FrameworkPrj1Control during runtime.
This still makes sense for controls, but auxiliary files or libraries can only be used via global objects. If a function is to be outsourced to a separate file, this function must be created in a namespace such as TcHmi.Controls.FrameworkPrj1.sortArray and then used.
Therefore, since version 1.14, JavaScript modules (ES modules) can also be used in addition to classic JavaScript.
Imports via relative paths
This can be used to create a new file helper.ts. In this file, the desired function is marked with the keyword export.
export sortArray(arrayToSort: string[]) {
// implement
}The help function can now be easily imported into the control and simply used:
import { sortArray } from './helper.js';The file helper.js is referenced here via a relative path (relative specifiers). Please note that the JavaScript file created by the Typescript compiler is referenced ('./helper.js' instead of './helper.ts').
Imports via relative keywords
Alternatively, an import can also be carried out using a keyword (bare specifiers). This is often used to integrate external libraries. For example, the marked library could be used in a control.
import { marked } from 'marked';A reference must be created in the project's Manifest.json so that the browser can load the library later. This automatically creates an entry in the application's central importmap.
"esmoduleImports": [
{
"imports": {
"marked": "FrameworkPrj1Control/Lib/marked.esm.js"
}
}
]To ensure that the typescript compiler also has full information about the content, an entry should be added to tsconfig.tpl.json under the item compilerOptions:
"compilerOptions": {
"paths": {
"marked": ["./Lib/marked.esm.d.ts"]
}
}Cross-package exports and imports
All package paths are referenced in the application's central importmap so that cross-package imports can also be used. Many Beckhoff packages have the file index.esm.js in the root directory as a fixed API for package-global exports.
Only this file should be imported for external packages, as this is the only way to ensure that the exports remain accessible even with internal refactoring.
All controls, but also a code-behind file, can thus access functions of the package.
import { ControlFactory } from "Beckhoff.TwinCAT.HMI.Framework/index.esm.js";
// …
let myButton = ControlFactory.createEx('TcHmi.Controls.Beckhoff.TcHmiButton', 'MyButton');The Typescript compiler should also be informed about these paths via compilerOptions in the tsconfig.tpl.json.
"compilerOptions": {
"paths": {
"Beckhoff.TwinCAT.HMI.Framework/*": [ "$(Beckhoff.TwinCAT.HMI.Framework).InstallPath/*" ]
}
}$(Beckhoff.TwinCAT.HMI.Framework).InstallPath is replaced with the correct path when saving.
Dynamic import
Modules can also be imported in classic JavaScript using a special syntax. This enables a step-by-step changeover to modules if required.
import('Beckhoff.TwinCAT.HMI.Framework/index.esm.js').then(({ ControlFactory }) => {
let myButton = ControlFactory.createEx('TcHmi.Controls.Beckhoff.TcHmiButton', 'MyButton');
});![]() | The browser only executes imported modules once, even if they are imported from several files. This means that an export such as |
Examples
A complete example project with the most important functions can be viewed on the following web pages:
See also:
