Details
-
Task
-
Resolution: Fixed
-
Major
-
12.7
-
None
Description
Mixing Velocity code with JavaScript code (inline) can lead to unexpected bugs because the minifier (e.g. Closure Compiler) is run at build time, before the Velocity code is evaluated. We can have two types of problems:
- the Velocity code doesn't appear as valid JavaScript code and thus the minification fails (e.g. the Velocity code is outside of a JavaScript comment)
- the Velocity code looks like JavaScript and the minifier rewrites it (optimizes it) and the result is no longer valid Velocity code, thus failing at runtime (when the Velocity code is evaluated)
One solution is to try to reduce the need for Velocity code but it's not always possible to drop the Velocity code completely. The most common need for Velocity code in JavaScript is:
- paths / URL (e.g. RequireJS configuration, application context path)
- localization
In this case, the solution I propose is to separate clearly the Velocity code from the JavaScript code, i.e. to avoid in-lining Velocity code within JavaScript code. One way to achieve this is to follow this pattern:
/*! ## Velocity code here. #set ($paths = ...) #set ($l10n = ...) ... #[[*/ // Start JavaScript-only code. (function(paths, l10n) { "use strict"; ... // End JavaScript-only code. }).apply(']]#', $jsontool.serialize([$paths, $l10n]));
The benefits are:
- clear separation between Velocity and JavaScript
- the only line where we mix Velocity with JavaScript in-line is the last one, but we know this one is safe
- Velocity parsing is disabled within the JavaScript-only section due to the special Velocity syntax '#[[ ... ]]#'
- the Velocity values/objects that are needed in the JavaScript code are serialized as JSON and passed as arguments to an anonymous function
- writing unit tests for this JavaScript requires mocking only $jsontool.serialize and the Velocity values/objects
Note that JavaScript code located in wiki pages (JSX) is not affected because in this case the minification is performed at runtime after the Velocity code is evaluated.
Attachments
Issue Links
- blocks
-
XWIKI-18210 Cannot add a new gadget in the dashboard
- Closed
- causes
-
XWIKI-18210 Cannot add a new gadget in the dashboard
- Closed
-
XWIKI-18167 Cannot edit a gadget on a dashboard after upgrading an instance
- Closed
- is related to
-
XWIKI-13775 Replace YUICompressor by something else for JavaScript minification
- Closed