How to Use JavaScript in TYPO3’s Backend
JavaScript is everywhere. It’s one of the most important programming languages today, and it’s ever-growing. Some of the earlier implementations of JavaScript were full of bugs, which reflected badly on its reputation in the IT market. Since then, it has come a long way.
JavaScript is used for purposes well beyond pixel manipulation
JavaScript can be found in any of the layers of a software system that interact with a browser, e.g. backend tasks, web servers and data processing. As JavaScript also interacts with HTML and CSS (both markup languages), it can also be used for adding dynamic, interactive content to web pages.
JavaScript can be used to build any kind of dynamic function and interactive feature - be it in a website, a video game, or in a highly complex and powerful software like TYPO3 CMS.
Over the years, we’ve had our fair share of experience with the many JavaScript frameworks, and TYPO3 CMS has come a long way with this powerful programming language. Vanilla JS, jQuery script.aculo.us, Prototype, Ext JS …. we’ve used them all - and not subsequently, but all at once: from random snippets throughout TYPO3’s core, to a wide range of frameworks, to AMD modules implemented in TYPO3’s backend.
Let’s take a look back, and then towards the future.
TYPO3 & JavaScript: a glance at the past
JavaScript is all over TYPO3. Besides the occasional code snippets all of you may know (and hate), quite a bit of technical debt piled up in the code in the course of time. At their time, they may have been great parts of the software. But their half-lives were long overdue and to put it plainly: this technical debt was a pain in the neck.
The last bits of script.aculo.us and Prototype were finally removed in the process of developing TYPO3 v7, which was a tremendous relief. And the next step was to remove Ext JS. That was just about completed in the course of developing TYPO3 v8, and now there’s only one final step to go - Ext JS will belong to TYPO3’s past as soon as its functionality in the page tree has been replaced.
TYPO3 today: RequireJS
Large applications often require a number of JavaScript files, and handling things can get tough and slow. Module based coding is used to break large applications into smaller blocks of manageable code, that only get loaded when they’re needed.
Asynchronous Module Definition (AMD) is a mechanism for defining modules and their dependencies. It allows developers to encapsulate code in smaller files that are loaded asynchronously if desired.
RequireJS - a JavaScript file and module loader - is used for managing these dependencies in JavaScript projects. It allows you to define code modules that will only execute once their dependencies exist.
TYPO3 v7 - and above - support AMD modules by using RequireJS.
The AMD format comes with a variety of improvements to support developers write JavaScript:
it handles dependencies by itself - there’s no need for a specific js file
there’s less chance of losing track of the file somewhere in your system
AMD modules are only loaded if needed, which means less traffic and more performance for your website
It's easy to use RequireJS in your own extension
To be able to use RequireJS at all, some prerequisites must be fulfilled:
Each AMD has to have a namespace and a module name.
The namespace is TYPO3/CMS/<EXTKEY>, whereby <EXTKEY> is the extension key and is declared in UpperCamelCase, e.g. ext:foo_bar = FooBar.
That namespace maps automatically to the Resources/Public/JavaScript directory of the extension.
One should only write one module per file (anything else is bad practice) and the filename is the module name + .js
Example: TYPO3/CMS/FooBar/MyMagicModule is located in EXT:foo_bar/Resources/Public/JavaScript/MyMagicModule.js
Take a closer look at our RequireJS documentation to see how easy it is to create your own module.
Use legacy JavaScript with RequireJS
Sometimes you need to reuse some old code in an AMD driven environment. Fortunately, you can extend the RequireJS configuration.
GeneralUtility::makeInstance(PageRenderer::class)
->addRequireJsConfiguration([
'paths' => [
'custom-lib' => '/typo3conf/ext/my_ext/foo.lib.js',
],
'shim' => [
'custom-lib' => ['jquery'],
],
]);
Here you define your own lib in your extension as an AMD module 'custom-lib', as well as the dependency for jQuery. Now every module that requires your ‘custom lib’ will also take care of loading jQuery.
Answers to frequently asked technical questions
You'll find answers to other frequently asked technical questions, instructional clips and all sorts of helpful videos on our TYPO3 YouTube channel. Come along and join us there. If you find this useful, please share the link on your network.
Thanks for reading! If you’ve enjoyed this or any of my previous posts on this site, consider leaving a comment or sharing this post with a friend!