goog.inherits present in the output file - javascript

I'm trying to use Closure Compiler and Closure Library.
When I use the library everything is ok, I'm including "base.js" in my simulation and it works with all my javascript files.
The problem is present when I "compilate" my application: In the output file I've got a reference to a closure library'sfunction "goog.inherits".
From what I've read, it's not necessary to include "base.js" in production. I'm working on a library, so I don't want to force users to have a reference to the Closure Library.
How can I do?
Here is my code:
NM.ObjectEvent = function( type )
{
goog.base(this);
}
goog.inherits( NM.ObjectEvent, NM.Event );
And the script look like that:
java -jar compiler.jar --compilation_level SIMPLE_OPTIMIZATIONS --js_output_file myLib.js `find ../src/ -name '*.js'`

What you have heard does not apply to SIMPLE_OPTIMIZATIONS. With ADVANCED_OPTIMIZATIONS everything unused in base.js is removed, with SIMPLE_OPTIMIZATIONS only function local optimizations are performed and unused methods are not removed.
Regardless of the mode, if you use goog.inherits it will remain in some form. Something needs to do the work that goog.inherits does to setup the prototype chain.

Like John said, if you have references to goog.base and goog.inherits, you're referencing the library. Fortunately, you can emulate those functions... Something like this should work...
NM.ObjectEvent = function( type )
{
NM.Event.call(this, type);
}
(function(){
var temp = function(){};
temp.prototype = NM.Event.prototype;
NM.ObjectEvent.prototype = new temp();
}();
If you're using goog.base elsewhere (for example, to call superclass methods), then you'll need to do more work, but the above should suffice if you're only using base and inherits where shown in your original post.

Related

V8 console.log does not print

I am attempting to embed v8 into my application, I am messing about seeing what is included in the V8 environment (duktape does not include a console implementation) and it seems like v8 does include an implementation however when I call console.log it does not print anything, instead it just prints undefined (which i assume to be the return value of console.log) So how would one go about linking the default std::cout output with console.log.
This is my code currently, I am working with the default hello world code very slightly modified.
int main(int argc, char* argv[]) {
// Initialize V8.
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(isolate);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);
{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8(isolate, R"(
console.log("does not print?")
)",
v8::NewStringType::kNormal)
.ToLocalChecked();
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
}
// Dispose the isolate and tear down V8.
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
delete create_params.array_buffer_allocator;
std::cin.get();
return 0;
}
and I am using the prebuilt v8 binaries here
Try the following:
#include "src/debug/interface-types.h"
define your own "console delegate" class, deriving from debug::ConsoleDelegate
override any methods you're interested in, e.g. void Log(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) override;
instantiate it and call debug::SetConsoleDelegate(isolate, &your_console_delegate); after creating your Isolate
To see an example, start at https://cs.chromium.org/chromium/src/v8/src/d8/d8-console.h?l=14&gsn=D8Console and trace where it's used.
So for anyone in the future that is dealing with this, this is the process I used to fix it.
download the source from here, only the src folder is needed.
extract it and link it in to your project where ever you put vendor code in addition to the bundle.
put it in the a src folder because otherwise its includes don't work
you will need to make a bunch of include directories for it to compile, mine include v8/src, and v8
make sure to link it with the nuget package, you may not have to do this, one machine needed it the other didn't.
you do not need to generate builtins-generated/bytecodes-builtins-list.h

JS function names compression

I can't seem to find a JS minifier that performs function names compression. For example, given this pseudo-code:
//non pure function
function test() {
//do some computations...
return <whatever>;
}
alert(test());
Would then, for example, be minified to this:
function t(){//do some computations... return <whatever>}alert(t());
So far I have not found any JS tool that does this sort of compression. Does anyone know any?
When you use UglifyJS it will not mangle top-level names, or names available to the global scope.
You can still achieve this if you turn on the -mt or --mangle-toplevel flag in the command line like so:
Here is some code I posted in the demo link you provided:
function longfunctionname(a) {
return function reallylongfunctionname(b) {
return a + b;
};
}
Here is the mangled code without top level mangling turned on:
function longfunctionname(n){return function u(n){return n}}
As you can see the top level function is not mangled, but the inner function is
go here to read more: http://lisperator.net/uglifyjs/
Definitely! You can use a task runner (i.e. Grunt or Gulp) to assist, but the process you are describing is normally defined as "uglifying" or "mangling" JS. Check out gulp-uglify or grunt-contrib-uglify to get started.
EDIT: Per comments on this answer, using a task runner is not necessary, as you can use UglifyJS on its own.
Its good habit to write code that doesn't pollute the global space. By wrapping in an anonymous function the code will minify and will not collide with other global references.
(function (){
function test() {
//do some computations...
return "something";
}
alert(test());
})();
If you run UglifyJs with --mangle the output will look like this
!function(){function t(){return"something"}alert(t())}();
I used https://skalman.github.io/UglifyJS-online/ to get generated UglifyJs code

Stop Emscripten from creating global "Module"

Is there a way to prevent emscripten from creating window scoped global "Module"?
I generate some .js using something like emcc --bind -O3 --memory-init-file 0 whatever.... If I include the output script, window object gets flooded with various internal emscripten functions and objects.
I tried to wrap generated code like this:
Some.Namespace.Whatever = (function() { ...generated code...; return Module;})();
Everything seems to work fine, but emscripten still creates window scoped global "Module" (other internal functions are gone).
Since this commit from February 4th this year, which I believe is part of Emscripten > v1.29.9, if the code is wrapped by some method, the Module object is not exposed on the global scope.
Maybe you can use the pre and post js options to wrap the code in a self executing anonymous function? [0] So he pre js would be (function () { and post js would be })();. This could just as easily be done manually as part of a build step with Unix cat.
That or shove it in a worker. [1]
I don't think emscripten assigns window.Module or this.Module in emitted code, but I'm not a computer to check right now, maybe you could?
[0] https://github.com/kripken/emscripten/blob/1c12291bcb77fac633d9fbe08c817746c4ce24c3/site/build/text/docs/tools_reference/emcc.txt#L269-L277
[1] https://github.com/kripken/emscripten/blob/1c12291bcb77fac633d9fbe08c817746c4ce24c3/site/build/text/docs/tools_reference/emcc.txt#L468-L474

Removing debug code from inside a function using Closure Compiler simple optimisations

I'm looking for a way to strip out debug code from functions so I can add test hooks to closures. I've read
Google Closure Compiler advanced: remove code blocks at compile time and tested out removing debug code with the following:
/** #define {boolean} */
var DEBUG = true;
if (DEBUG) {
console.log('remove me');
}
Simple optimisation with --define='DEBUG=false' reduces this to var DEBUG=!1;. The same applies for this:
/** #const */
var DEBUG = false;
if (DEBUG) {
console.log('remove me');
}
Where I run into trouble is using this convention inside a function:
/** #const */
var DEBUG = false;
function logMe() {
if (DEBUG) {
console.log('remove me');
}
}
This reduces to the following:
var DEBUG=!1;function logMe(){DEBUG&&console.log("remove me")};
I would expect it to reduce further to:
var DEBUG=!1;function logMe(){};
Is there a reason this is not working as expected? I'm really just looking for a clean way to strip debug code and am not ready to take the plunge into advanced optimizations.
Update
Per #John's answer, I implemented my own compiler and have found that the following configuration will remove if (DEBUG) {} from inside and outside the code for the case of a #define:
CompilerOptions options = new CompilerOptions();
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
//options.setInlineConstantVars(true);
options.setInlineVariables(CompilerOptions.Reach.ALL);
options.setDefineToBooleanLiteral("DEBUG", false);
This works well enough for a single file with the following limitations:
This requires var DEBUG to be defined in each file, which is bad practice.
When combining multiple files, you can only have a single var DEBUG or the compiler can't optimize around it. This could be avoided by compiling each file individually and merging them.
Because the value is defined at the beginning of the file, there's no flexibility to receive the value beforehand.
I've toyed with the idea of removing all var DEBUG definitions from the files and injecting it into the source or extern before execution, but I've run into two issues:
Defining it in extern appears to do nothing.
Undefined DEBUG in the uncompiled code throws a reference error in the browser.
The ideal option would be to test window.DEBUG, which does not throw a reference error. Unfortunately, while injecting /** #const */ var window = {}; /** #const */ window.DEBUG = false; works at the top level, reducing if (window.DEBUG) {}, the optimization is actually reverted if placed in a function.
Unless another compiler option works the only option that would really make sense is to go with window.DEBUG and before compilation inject /** #const */ var DEBUG = false; and to a global replace of /\bwindow.DEBUG\b/ with DEBUG. Is there a better way?
Use #define annotation:
#define {boolean}
DEBUG = true;
And compile with option
--define="DEBUG=false"
A custom build of the compiler would allow you to do this. You basically want to "inline constant variables":
options.setInlineConstantVars(true);
You could add it here, in applySafeCompilationOptions:
http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilationLevel.java?r=706
Or you could use the Java API and add the option (without modifying the compiler's code). Michael Bolin given an example of how to do this here:
http://blog.bolinfest.com/2009/11/calling-closure-compiler-from-java.html
This is an old answer, but I found a way that's not mentioned here.
(function(){
var DEBUG = true;
if (DEBUG) {
if (something === "wrong") {
console.warn("Stop! Hammer time!");
}
else if (something === "as expected") {
console.log("All good :-)");
}
}
foo();
})();
With ADVANCED_OPTIMIZATIONS this compiles to this:
"wrong" === something ?
console.warn("Stop! Hammer time!") :
"as expected" === something && console.log("All good :-)");
foo();
In our build script we can rewrite the DEBUG line to set it to false, which would then yield this output.
foo();
The reason this happens is Closure will remove unreachable code. By creating the closure, and defining a local variable, Closure can see that we can't do something like window.DEBUG === true, so the code is guaranteed to never be run.
Your DEBUG variable is currently global. GCC will not remove or rename global variables in simple optimization mode, so they'll remain available to any code in other scripts that might possibly want to access them. Try enclosing your code into anonymous function.
The way i solved the problem of "removing debug functions from closure compiled javascript using SIMPLE_OPTIMIZATION" was by combining a similar method as #John proposes as well as using some of #Brian Nichols update. I could only get the compiler to remove the lines by placing this is the global scope of my main js file and doing a custom compile (using multiple .js files this still removed them)
/** #const
* #type {boolean}
*/
var DEBUG = false;
//and used this format for my debug function
DEBUG && myLog('foo');
and then compiling the closure-compiler java with ant to include this option options.setInlineVariables(CompilerOptions.Reach.ALL);
under the applySafeCompilationOptions function in the CompilationLevel.java file as #john suggests. This worked for me and didnt break my codebase as ADVANCED did...
Remove var DEBUG = true; from your code and convert all your conditions that check if (DEBUG) to if (goog.DEBUG). Modify your compiler option to read --define goog.DEBUG=false. The goog variable is built into the Closure Library API to provide options and flags for the compiler.

Javascript Modular Layout : How to call a function defined in one module from another?

Below is an example of a modular layout of a javascript application. I want to start using such a structure for my work. I am struggling to get my head round how it works and need to understand how to call a function that is defined in one module from a different module? Is this definitely the bet way to layout a JavaScript heavy application?
window.MainModule = (function($, win, doc, undefined) {
var modules = {};
// -- Create as many modules as you need ...
modules["alerter"] = (function(){
var someFunction = function(){ alert('I alert first'); };
return {
init: someFunction
};
}());
modules["alerter2"] = (function(){
var someFunction = function(){ alert('I alert second'); };
return {
init: someFunction
};
}());
return {
init: function(){
for (var key in modules){
modules[key].init();
}
}
};
}(jQuery, this, document));
$(window.MainModule.init);
Modularity with RequireJS:
module1.js
define( ["dependency"] , function( dep ){
return {
speak: function(){
alert( dep.message );
}
}
} );
dependency.js
define( {
message: "Hello world!"
} );
impl.js
if ( $(".someCssExpression").length ) {
require( [ "module1" ] , function( mod ){
mod.speak();
});
}
index.html
...
<script src="require.js" data-main="impl"></script>
...
Your file structure will be modular.
Your implementation will be modular.
And no clunky namespacing or weird constructs to make it feel organised.
Takes some getting used to, but totally worth it.
Also read:
ScriptJunkie article
In order to access anything it needs to be available in the scope from where you are calling. "Module" - or any capsulation method for that matter - in JS always means "function". A module is just an anonymous (unnamed) function. So to access an element defined in another function B(module) from inside function A it either has to be made available in GLOBAL SCOPE (in browsers: the window object), OR it must have obtained access some other way, e.g. by having received a reference through some function call. YUI3 ([http://developer.yahoo.com/yui/3/]) is an interesting example for the latter, there nothing of your application ever is available in global scope (I consider YUI3 one of the by far best JS frameworks for SERIOUS softwarfe development, also definitely DO check out http://developer.yahoo.com/yui/theater/, especially any videos from Douglas Crockford, a Javascript God (and I'm not usually given to giving these kinds of statements).
What you have to keep in mind with Javascript is that part of what in languages such as C is done by the compiler now happens at runtime. For such things like immediate function invocations that return a function (causing encapsulation through usage of closures) you should remember that that code runs exactly ONCE DURING LOADING, but during runtime completely different code is executed - which depends on what the on-load code execution did.
In your example the function after window.MainModule=... is executed on loading of the JS code. Note that window.MainModule does NOT POINT TO THAT FUNCTION!!!
Instead, that function is, as I said, executed on load, and the RESULT is assigned to window.MainModule. What is the result? Well, there is just one return statement, and it returns and object, and the object has just one property "init" which points to an anonymous function.
Before returning that object, though, that function creates a variable "modules" in its local scope, which points to an object. The object has two properties, and those properties are assigned functions the same way that window.MainModule is assigned one, so you have three closures all in all.
So after loading you have one global variable
window.MainModule = {
init: function(){...}
So after loading you have one global variable
window.MainModule = {
init: function(){...}
}
In the last line that function is executed.
}
In the last line that function is executed.
The example does not make a lot of sense though, because you don't really encapsulate anything. You make available the private function with double pointers: from init to the local variable someFunction, nothing is hidden. Check out the above URLs (Yahoo Developer Theater) for better examples and very thorough explanations. It is MUST-WATCH even if you never touch YUI3 - especially the videos from D. Crockford are general JS knowhow.
Well umm..
It all depands on what you need from your application.
I would suggest sticking to the jQuery plugins for as long as you touch the gui.
You could use the Namespace pattern like yahoo, and just forge a great framework for your
application.
You probably don't need your modules to run on every page, like you did when instantiating the main module (There is no point to it unless f.e. you have a widget in every page on your website).
After you finish to abstract all the actions you need from your javascript into function and modules, build a module that will load the logic according to each page/action/whatever whenever you need it.
By the way, You can always develop OO style using mootools and this is endless really. It all boils down to your application needs
I would really recommend you to watch some lectures of Douglas Crockford(As been stated before me) and here is a nice article about modules that may help you understand it a bit further. Good luck!

Categories

Resources