This article describes DXP infrastructure to minify JavaScript source files. It is related to Resource Serving in DXP.
These three pieces form the basic infrastructure available in DXP to minify JavaScript code.
-
JavaScriptMinifier
: describes the interface that services to minify JavaScript must implement. -
MinifierUtil
: provides a way to retrieve theJavaScriptMinifier
with highest service ranking currently deployed to DXP. Note that you can also obtain a reference to aJavaScriptMinifier
(or all of them) using standard OSGi mechanisms (for example:@Component
orServiceTracker
). -
frontend-js-minifier
: this project contains the two default minifiers that DXP ships out-of-the-box (Google and Yahoo). See the two following sections for more details.
Note that, even though,
JavaScriptMinifier
andMinifierUtil
are insideportal-impl
to maintain backward compatibility, the implementation of the minifiers has been extracted to an OSGi module (frontend-js-minifier
) for modularity.
This is the default DXP minifier (because it is deployed with a higher service ranking than the other ones available).
It uses Google Closure Compiler under the hood. Because this is an internal library from Google (thus unsupported and subject to big breaking changes) updating it usually has a significant cost so it is not done very often.
This uses YUI Compressor from Yahoo!, which is still active but unmaintained (except for some PRs that get merged from time to time). The last commit at the time of this writing (Sep 2020) is from May 2019.
Unless someone has a very good reason to use it, this shouldn't be the choice for any production site but it is still shipped for compatibility reasons.
Currently, the following components in DXP use the minifier services.
This is a filter used to minify inline JavaScript code contained in <script>
tags and embedded in the HTML code.
It also does transformations for
<input>
,<textarea>
,<pre>
and<style>
but that's out of the scope of this document.
It filters any resource with its URL starting with (as specified in liferay-web.xml
):
/c/...
/group/...
/user/...
/web/...
And it can be configured with:
- portal.properties:
minifier.inline.content.cache.enabled
: set totrue
to make the filter minify<script>
tags content (by default,true
).minifier.inline.content.cache.skip.javascript
: this defines a comma separated list of tokens to look for in the<script>
content so that, if any is found, the minified response is not cached. By default, any<script>
containinggetSessionId
orencryptedUserId
is not cached.strip.ignore.paths
: list of paths to ignore (by default,/document_library/get_file
).strip.mime.types
inportal.properties
: defines the MIME types of responses that should be processed by the filter (by default,text/html*
andtext/xml*
). Note that you can put a*
at the end of the config values to catch all MIME types starting with the string to the left of the*
.
- Request parameters:
ensureContentLength
: set totrue
if you want to make sure theContent-Length
header is returned from the server.strip
: set tofalse
to disable the filter.p_p_lifecycle
: if it is1
(PortletRequest.ACTION_PHASE
) or2
(PortletRequest.RESOURCE_PHASE
) the filter is disabled.
If all the rules match and a <script>
is minified, the filter simply invokes MinifierUtil.minifyJavaScript()
to do its duty.
This filter is already described in Resource Serving in DXP.
This servlet aggregates several .js
or .css
files and serves them as a single request to ease caching and reduce connection count. It also caches its responses.
It honors the work.dir.override.enabled
portal property so if it is set to true
it diverts requests to development project folders when using fast deployments.
The way to invalidate this servlet's cache is to check if any of the aggregated files has changed. If the portal property combo.check.timestamp
is set to false
(and by default, it is, in production systems) the check is not performed and the cache is never invalidated. Otherwise files are tested for changes every combo.check.timestamp.interval
milliseconds (where combo.check.timestamp.interval
is a configuration value of portal.properties
).
Finally, each .js
file aggregated by the servlet has its name tested for the -min.js
or .min.js
suffixes and, if they are NOT found, its content is minified using MinifierUtil.minifyJavaScript()
.
This servlet services request to the /js_loader_config
URL, which returns the AMD Loader configuration so that the browser side can access it.
For example, it sets the following loader properties: explainResolutions
, logLevel
, resolvePath
and waitTimeout
.
It also controls the value of Liferay.EXPLOSE_GLOBAL
which causes Liferay.Loader.define()
method to be published under window.define
(this is for compatiblity reasons, but its use is strongly discouraged as it can cause issues with third party libraries).
Even though it is small, this servlet minifies its response with MinifierUtil.minifyJavaScript()
and also caches it for efficiency.
This servlet services request to the /js_bundle_config
URL, which is the configurator of the legacy AUI
loader.
This servlet does not cache its response but minifies it leveraging MinifierUtil.minifyJavaScript()
.