Stop Emscripten from creating global "Module" - javascript

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

Related

using uglyfyjs 3 output file same as original

I have some simple JavaScript file named test.js the file contain the following code:
function foo(){
console.log('hi');
}
Since all client code is exposed to the client, I am trying to 'hide' it or to make it unreadable.
I downloaded uglify-js, I tried to run the command
uglifyjs test.js --output test.min.js
Then the output file contains the following:
function foo(){console.log("hi")}
i.e almost the same code, readable code
Am I missing something?
Your function foo is defined in the global scope, so its name can't be obfuscated/minified. Changing it might break other codes that were calling this function.
All other words are either keywords (function), built in objects (console), object methods (.log) or string literals ('hi'). These can't be changed without breaking your code.
So, all in all, there is no changes because nothing can be changed.

Accessing variables and methods from another file

In this case, How do I access the variable and method declared in a file from another file?
File one
jQuery(function(t) {
var myVar = 'myValue',
e = function(t) {
console.log('myLog');
}
});
File two
jQuery(function($){
// ????
});
You don't. It has nothing to do with files (JavaScript largely doesn't care about files unless they're ES2015+ modules), it has to do with the fact that both myVar and e are entirely private to the anonymous function you're passing into jQuery in the first code block. Even other code outside that function in the same file would be unable to access them.
You'd have to change the first file to make that information accessible outside that function. You could do that by making them globals (blech), or by having a single global you use for all of your things like this with an object with properties for these things (slightly less "blech" :-) ), or by using something like Webpack and true modules.
It really depends on how you setup your scripts. For instance:
<script src="fileOne.js"></script>
<script src="fileTwo.js"></script>
Then you will be able to do the following:
File One:
- Declare variable x
File Two:
- Access variable x
I recommend taking a look at this, it'll help with understanding variable scope (however this doesn't cover ES6's let): https://www.w3schools.com/js/js_scope.asp

goog.inherits present in the output file

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.

Can a require.js module depend on itself

We have two modules that get loaded (with 'define') by require.js:
ds.test.js
ds.js
As you might guess, the former tests the latter. The preamble to ds.test.js is as follows, with some console/logging I've added:
define(["ds", "test", "assert"], function (ds, test, assert) {
console.log(arguments);
// the rest is a 'pure' module --
// no executable code outside of a returned object/map of methods
The output from the console/logging being what I expect: [Object, Object, Object]
The preamble (with console/logging) of ds.js is as follows:
define(["ds"], function (ds) {
console.log(arguments);
// the rest is a 'pure' module
The output from the console/logging however is: [undefined]
Why would the former (ds.test.js) be able to successfully load ds, but ds.js itself cannot? This causes one of my tests to fail, as one of the methods returned by ds refers to a method within itself, i.e.: 'ds.assoc()'. Interestingly before require.js we used a home-rolled dependency manager, and the test did not fail on the same method -- ds.js was able to refer to itself.
Would this be an issue of a so-called "circular dependency"? In that ds.test.js relies on ds.js, and ds.js relies on itself. If so how might I resolve my issue?
For what it's worth, ds.test.js gets loaded first -- it gets picked up as a global var named "SUITE" by 'test.runner.js', the preamble of which is as follows:
define(["test", SUITE], function (test, suite) {
Then whatever test suite gets loaded (in this cast, ds.test.js) in turn loads the module which it is testing (e.g. "ds")
Some final context is that I've just inherited this code in the last few weeks, and what I'm doing is based on our existing conversion of another application from our home-rolled dependency manager to require.js. So I guess I'm asking that be taken into consideration before any sniping with comments such as "why are you using a global variable"; if you've got suggestions for a concrete alternative, great I look forward to it.
(Comment added as an answer by request.)
If ds refers to a method within itself, couldn't you call your example function of assoc() directly, rather than try to use ds.assoc()? (This also eliminates the perceived need for ds to load itself.)

javascript linking

I'm going to build a rather complicated application in html5 with some heavy javascripting.
In this I need to make some objects which can be pass around. But since there is no like #import foobar.js.
Then I assume that if my html page loads the scripts, then all the scripts can access eachother?
I read (here) that ajax somehow is able to load a .js file from within another .js file. But i dont think this is what I need?
Can go more into details if needed, thanks in advance.
In our projects, we do the following: Suppose you're going to call your project Foo, and have a module called Bar in it,
Then what we do is declare a file called Foo.js that just defines an equivalent to a Foo namespace:
Foo = (function(){
return {
};
})();
Then we create a file called Foo.Bar.js that contains the code for the Bar module:
Foo.Bar = (function(){
// var declarations here that should be invisible outside Foo.Bar
var p, q;
return {
fun1 : function(a, b){
// Code for fun1 here
},
fun2 : function(c) {
// Code for fun2 here
}
} // return
})();
Note that how it is a function that executes immediately, and returns an object that gets assigned to Foo.Bar. Any local variables, like p and q are available to fun1 and fun2 because they're in a closure, but they are invisible outside of Foo.Bar
The functions in Foo.Bar can be constructors for objects and so on.
Now in your HTML you simple include both files like so:
<script type="text/javascript" src="Foo.js"></script>
<script type="text/javascript" src="Foo.Bar.js"></script>
The result will be that you can call Foo.Bar's functions in the JavaScript of your main HTML file without any problems.
You should check out the module pattern:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth/
This describes alternatives for creating modular code in javascript, how you can protect your code and share APIs and data among them.
You should also consider using and AMD. Require.js is quite popular, but I tend to prefer head.js for this. Keep in mind that these put some requirements on how you structur your code in files, and personally, I don't think it's worth it, compared to a concatenated and minified file included in the bottom of the page.
Then I assume that if my html page loads the scripts, then all the scripts can access eachother?
Yes.

Categories

Resources