Compressing Javascript code having classes - javascript

I am writing in Javascript using classes. Example:
'use strict';
class MyClassName
{
myGame;
constructor(game)
{
this.myGame = game;
}
startGame()
{
this.startActions();
}
startActions()
{
//
}
}
When i try to compress it in PhpStorm by using Assets Compressor, i get error:
[ERROR] 3:6:identifier is a reserved word
How i can make correct compressing my code in PhpStorm? Are there any ways to compress JS code that uses classes?

Assets Compressor plugin only supports ECMAScript 2015, it will throw errors on new syntax.
Please try following the instructions from https://www.jetbrains.com/help/idea/minifying-javascript.html: install either UglifyJS or the Closure Compiler and set it up as a file watcher to run from the IDE

Related

"ReferenceError: $jscomp is not defined" when changing output language spec by google-closure-compiler jar

I've downloaded the most recent version of compiler and i've tried to optimize js code with these flags:
java -jar closure-compiler-v20211006.jar -W VERBOSE -O WHITESPACE_ONLY
--language_out ECMASCRIPT5 $script_path_in --js_output_file $script_path_tmp
closure compiler has optimized this lines of code:
for(var extraProperty of extraProperties){
option.setAttribute(extraProperty,initialOption[extraProperty]);
}
into
for (var $jscomp$iter$0 = $jscomp.makeIterator(extraProperties), $jscomp$key$extraProperty = $jscomp$iter$0.next(); !$jscomp$key$extraProperty.done; $jscomp$key$extraProperty = $jscomp$iter$0.next()) {
var extraProperty = $jscomp$key$extraProperty.value;
{
option.setAttribute(extraProperty, initialOption[extraProperty])
}
}
And as a result i receive such error in browser:
all_compressed.js Uncaught ReferenceError: $jscomp is not defined
Is there a way to change language spec with this compiler without adding side dependencies into the project, or maybe it's a bug?
Git bug tracker
The best option for white space only mode is to set the language out to the latest ECMASCRIPT version used by the source code (or later) to avoid runtime dependencies.

Trying to understand how to import web-assembly package via webpack

I'm on webpack#4.43.0 and am trying to use this web assembly library https://github.com/vislyhq/stretch As per docs I am importing some classes from it i.e.
import { Allocator, Node } from 'stretch-layout';
class Base {
public layoutNode;
public constructor() {
this.layoutNode = new Node(allocator, {});
}
}
However when I am trying to build it with webpack (not using any loaders and I have .wasm in my resolve.extensions webpack config) I am getting following error
WebAssembly module is included in initial chunk. This is not allowed,
because WebAssembly download and compilation must happen asynchronous.
Add an async splitpoint (i. e. import()) somewhere between your
entrypoint and the WebAssembly module:
To my understanding I need to use import() for this module, but how do I make these imports available to my class? Application will fail since we need to await that import? If I do something like this I get an error saying that Allocator and Node are not constructors.
let Allocator: any = null;
let Node: any = null;
import('stretch-layout').then(module => {
Allocator = module.Allocator;
Node = module.Node;
});
I was able to solve this using latest beta of webpack 5, by adding following experimental flags to config
experiments: {
asyncWebAssembly: true,
importAsync: true
}
this way you don't have to worry about any async import() statements at all

Minify JavaScript using the Google Closure Compiler and Gradle

I have a small Java web application being built with Gradle that includes some custom vanilla JavaScript. I'd like to minify the custom JS code using Google Closure Compiler.
All of the documentation for the Closure Compiler seems to be around using the CLI or the JSON API for minifying JS. I'd much prefer to call the Java API directly from Gradle in e.g. a Copy task.
I'd like to avoid
Node solutions
Calling out to the CLI and using java -jar
HTTP calls to the JSON API
This example is out-of-date and does not reflect the most recent Java API. This question is several years old, though most of the API calls seem similar to the current Java API.
Has anyone else minified JavaScript from Gradle using the Google Closure Compiler Java API directly?
I have a working solution:
task processWebapp(type: Copy) {
from('src/main/webapp') {
include "**/*"
}
eachFile {
if (it.sourceName.endsWith('.js') && !it.sourceName.endsWith('.min.js')) {
it.exclude()
Reader reader = it.file.newReader()
String source = ""
try {
source = reader.readLines().join("\r\n")
} finally {
reader.close()
}
com.google.javascript.jscomp.Compiler compiler = new com.google.javascript.jscomp.Compiler(System.err)
CompilerOptions options = new CompilerOptions()
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(
options)
SourceFile extern = SourceFile.fromCode("externs.js", "")
SourceFile input = SourceFile.fromCode(it.sourceName, source)
compiler.compile(extern, input, options)
String transpiled = compiler.toSource()
def directoryPath = it.relativePath - it.sourceName
File theDir = new File("build/resources/main/${directoryPath}")
if (!theDir.exists()) {
theDir.mkdirs()
}
PrintWriter writer = new PrintWriter("build/resources/main/${it.relativeSourcePath}", "UTF-8")
try {
writer.println(transpiled)
} finally {
writer.close()
}
}
}
destinationDir = file('build/resources/main')
}
This task copies everything from src/main/webapp to build/resources/main while transpiling (minifying) all files ending in .js (but not ending in .min.js) en-route. Gradle then packages and embeds those resources in the resulting jar.
Hope this helps someone else out there using Google Closure Compiler and Gradle.

Unable to minify Vue.js application

I have a Vue.js Application with the following excerpt of code:
(function() {
initApp();
})();
function initApp() {
window.myApp = new Vue({
el: '#wrapper',
data() {
return {
somedata: []
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
When I try to minify it, it fails with the error Error : Unexpected token: punc (() but the application runs successfully. I'm not sure why?
Those compressors simply only support an old version of JavaScript. Their support is restricted to at most ES5. To make your code work, convert it:
(function() {
initApp();
})();
function initApp() {
window.myApp = new Vue({
el: '#wrapper',
data: function() { // changed this line
return {
somedata: []
}
}
});
}
And it should compress.
Details:
They use uglify-js: "^3.3.10", that is known for not supporting ES6(uglify-es does) .
From their repo (emphasis mine):
UglifyJS 3
UglifyJS is a JavaScript parser, minifier, compressor and beautifier
toolkit.
Note:
(...)
uglify-js only supports JavaScript (ECMAScript 5).
To minify ECMAScript 2015 or above, transpile using tools like Babel.
Your compressor isn’t ES6 compliant
You’re getting that error because, like pacdcjunior's said, your compressor isn’t ES6 compliant. (I got your same error when I switched from jQuery to Vue.js—using ES6 syntax.)
Solution: Use Terser instead.
It’s ES6 compliant, in active development (at the time of writing), and is a direct replacement for Uglifyjs.
Bonus: How to minify lots of files in one pass with Terser
You can minify a single file in Terser from the command line like this:
$ terser file.js -m -o file.min.js
But if you have a load of files to minify in one go, that will be tedious. I found this excellent answer and modified it just a little. Add this to your .bash_profile:
alias renderjs='rm *.min.js; for f in *.js; do short=${f%.js}; terser $f -m -o $short.min.js; done'
Navigate to your js directory and run renderjs. Now all your *.js files have a minified version. Nice!
Do you mean the compiled js file (app.js)? If that case you just compile for production "npm run production".

How do I expose my TypeScript code to my JavaScript code via RequireJS/AMD?

This is a legacy project so I'm not going to change everything to TypeScript, but I do want to slowly start combining it, so I want to call TypeScript code from normal JS, using RequireJS. I have a 1-login.js and realtimeConnection.ts (that's transformed into realtimeConnection.js):
<script type="text/javascript" data-main="/content/scripts/realtimeConnection.js" src="/content/require.min.js"></script>
...
<script type="text/javascript" src="/content/pages/1-login.js"></script>
This is 1-login.js:
(function ($) {
requirejs(["/content/scripts/realtimeConnection.js"], function (rtCon) {
debugger;
// The probelm: rtCon === undefined
});
...
...
}(jQuery));
realtimeConnection.ts:
export class RealtimeConnection {
}
Which in turn becomes realtimeConnection.js:
"use strict";
var RealtimeConnection = (function () {
function RealtimeConnection() {
}
return RealtimeConnection;
}());
exports.RealtimeConnection = RealtimeConnection;
So how do I expose my TS code to the JS code via RequireJS?
Ok found it: I needed to tell the TypeScript compiler to build it in a RequireJS/AMD style:
Since I'm using Visual Studio 2015, I placed a tsconfig.json file with the appropriate settings ("module": "amd" in particular) in the root content dir, as per this SO answer.
Now it works.
Now to whoever going to mark it as duplicate:
That allegedly duplicate question, which its answer I linked above, has the title "Visual Studio 2015 RC does not create sourcemap when saving Typescript file". The answer is the same, but the question is different.
I found my answer, hope it'll help others as well... BTNOMB.. just saying...

Categories