How can Haxe be used in JavaScript without causing pollution to the global namespace?

This question pertains to Haxe versions prior to 2.10

While I've been aware of Haxe for some time, I only recently began experimenting with it. Out of curiosity, I decided to port showdown.js, which is a JavaScript adaptation of markdown.pl, to Haxe. The process was fairly simple, and the generated JavaScript code seems to function correctly (edit: To see it in action, visit here).

However, I observed that the resulting code pollutes the global namespace significantly... and even worse, it does so by assigning values to undeclared identifiers without utilizing the var keyword, making them global even within a closure.

For instance...

if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...

I managed to tidy up most of this using sed, but I'm also troubled by things like this:

{
 String.prototype.__class__ = String;
 String.__name__ = ["String"];
 Array.prototype.__class__ = Array;
 Array.__name__ = ["Array"];
 Int = { __name__ : ["Int"]}
 Dynamic = { __name__ : ["Dynamic"]}
 Float = Number;
 Float.__name__ = ["Float"];
 Bool = { __ename__ : ["Bool"]}
 Class = { __name__ : ["Class"]}
 Enum = { }
 Void = { __ename__ : ["Void"]}
}
{
 Math.__name__ = ["Math"];
 Math.NaN = Number["NaN"];
 Math.NEGATIVE_INFINITY = Number["NEGATIVE_INFINITY"];
 Math.POSITIVE_INFINITY = Number["POSITIVE_INFINITY"];
 Math.isFinite = function(i) {
  return isFinite(i);
 }
 Math.isNaN = function(i) {
  return isNaN(i);
 }
}

This JavaScript appears quite messy.


Queries

Is there a modified version or clone of Haxe available that doesn't introduce global contamination? Should I consider altering the Haxe source code to achieve my desired outcome, or has someone already addressed this issue? My attempts at researching have yielded minimal results. I am open to any suggestions. In the meantime, I am eager to witness the PHP code this tool will generate... :D


Solutions?

Below are some approaches I've experimented with:

Postprocessing

Here's my basic build script; it effectively removes redundant elements, though not all. I am cautious about removing modifications to default constructor prototypes as that could potentially cause issues. Rectifying everything might be quite a challenge, and I'd prefer not to commence unless the work has already been done...

haxe -cp ~/Projects/wmd-new -main Markdown -js markdown.js

echo "this.Markdown=(function(){ var \$closure, Float;" > markdown.clean.js;

sed "s/^if(typeof js=='undefined') js = {}$/if(typeof js=='undefined') var js = {};/g ;
     s/^\([ \x09]*\)\([\$_a-zA-Z0-9]* = \({\|function\)\)/\1var \2/g ;
      /^[ \x09]*\(else \)\?null;$/d ;
     " markdown.js >> markdown.clean.js

echo "return Markdown}());" >> markdown.clean.js;

java -jar closure/compiler.jar --js markdown.clean.js \
--compilation_level SIMPLE_OPTIMIZATIONS \
> markdown.cc.js

--js-namespace switch saves the day

Credits to Dean Burge for suggesting the namespace switch. This essentially resolved my dilemma, with minor assistance. Here's my current build script. I believe this captures all global variables...

NS=N\$

haxe -cp ~/Projects/wmd-new -main Markdown --js-namespace $NS -js markdown.js 

# export our function and declare some vars
echo "this.markdown=(function(){var \$_,\$Main,\$closure,\$estr,js,"$NS"" > markdown.clean.js;

# strip silly lines containing "null;" or "else null;"
sed "/^[ \x09]*\(else \)\?null;$/d ;" markdown.js >> markdown.clean.js

# finish the closure
echo "return "$NS".Markdown.makeHtml}());" >> markdown.clean.js;

Answer №1

To manage and organize global root types, I leverage the namespace switch feature in the compiler.

Answer №2

Using Haxe for creating a stand-alone reusable component in a JavaScript web application may not be the most efficient approach. This is illustrated by the fact that the compiler generates standard library code with every compilation. The best practice for targeting JavaScript with Haxe is to develop the entire application using Haxe and incorporate external elements using untyped blocks while hoping for compatibility. It is important to view the Haxe output as a self-contained entity, similar to a flash clip, operating independently of its surrounding environment.

Alternatively, consider encapsulating the code within a with() block for added functionality.

Answer №4

The JSTM JavaScript generator macro enhances haxe output through various methods:

  1. Segmenting the javascript output into individual files based on type
  2. Optimizing these files for better performance
  3. Utilizing a loader script to asynchronously load required types
  4. Utilizing only one global variable: jstm
  5. Downloading only necessary code for running your application
  6. Loading new types at runtime for highly scalable applications

For more information, visit http://code.google.com/p/jstm/.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to establish communication between JAVA and Javascript using Sockets?

Recently, I developed a Java application that generates some data and saves it in a text file on my computer. Instead of saving this data in a text file, I am looking to send it via Socket. Here is an example: Java public static void main(String argv[] ...

Understanding the Importance and Benefits of Using the Classnames Utility in React Components

Can you break down for me the purpose of utilizing the Classnames utility in React code? I've reviewed the Classnames documentation, but I'm still struggling to comprehend why it is used in code like this: import classnames from 'classnames ...

angular 6's distinctUntilChanged() function is not producing the desired results

I have a function that retrieves an observable like so: constructor(private _http: HttpClient) {} getUsers(location){ return this._http.get(`https://someurl?location=${location}`) .pipe( map((response: any) => response), ...

The functionality of the JavaScript animated placeholder seems to be malfunctioning

I am currently working on a code that updates the placeholder text every 2 seconds. The idea is to have it type out the letters one by one, and then erase them in the same manner. Unfortunately, the code is not functioning as expected. As a newcomer to J ...

React's constant rerendering of an overflowed component results in a jarring page jump

To view the code as a reference, click here. After pressing the button, the state changes and #container1 gets replaced with #container2. Despite this change, the page height remains constant and the outer containers maintain their original height. Howeve ...

Display all saved bookmarks by utilizing JavaScript

How can I utilize Javascript to display a complete list of my bookmarks? Any advice on achieving this would be greatly appreciated. Thank you in advance. ...

Troubleshooting Firebase import issue in Node.js, React, and Chakra UI framework

https://i.sstatic.net/ZPTmf.png Running "yarn dev" in my project directory is causing me to encounter this error. The code in firebaseConfig.js looks like this: // Import necessary functions from Firebase SDKs import { initializeApp } from "firebase/app" ...

Is the memory usage of node.js proportional to the number of concurrent requests, or is there a potential memory leak?

Running the following node.js code: var http = require('http'); http.createServer(function(req,res){ res.writeHead(200,{'Content-Type': 'text/plain'}); res.write("Hello"); res.end(); }).listen(8888); Upon starting the server ...

Creating dynamic image carousels using the latest versions of Bootstrap and AngularJS

I have created an array that stores various images using angularJS: $scope.docImg = [ '../../Content/Image/BackGrounds/abra.png', '../../Content/Image/BackGrounds/background_black.jpg', '../../Content/I ...

Storing user information in Angular after login and implementing JWT authentication

Is it advisable to save any user information other than JWT in local storage or cookies after a successful login? (The user profile object is already saved and encrypted in the JWT payload sub-part.) I need the user profile object ready before initializing ...

Understanding the inner workings of a Mongoose model without the need for

server.js process.env.NODE_ENV=process.env.NODE_ENV || 'development'; var mongoose=require('./config/mongoose'); express=require('./config/express'); var db=mongoose(); var app=express(); app.listen(3000,function(){ ...

What is the method for identifying the points where two faces of two bufferGeometryBox objects intersect?

I am currently working on a 3D configurator project. In this project, a cube is initially displayed on the scene. When a side of the cube is clicked, a rectangle is supposed to appear. However, the issue I am facing is that upon clicking the same side of t ...

Verifying the invocation of a callback function through the use of $rootScope.$broadcast and $scope.$on

I have been testing to see if a callback was called in my controller. Controller (function () { 'use strict'; angular .module('GeoDashboard') .controller('CiudadCtrl', CiudadCtrl); CiudadCtrl.$i ...

What could be causing my dropdown links to malfunction on the desktop version?

I've been developing a responsive website and encountering an issue. In desktop view, the icon on the far right (known as "dropdown-btn") is supposed to activate a dropdown menu with contact links. However, for some unknown reason, the links are not f ...

Altering the dimensions of a <div> based on the retrieved data

I am currently retrieving data from an API and displaying certain properties using mapping. I would like to adjust the width of the component based on the value of these properties. <h5> <span className="viewcount" ref={boxSize}> ...

Sorting a list based on user-defined criteria in Ionic 3

Currently working on a project using Ionic and Firebase, I am faced with the task of comparing arrays produced by users with those stored in Firebase. This comparison is essential for filtering a list of products. The user can reorder a list containing 3 ...

Issue encountered in the express route when attempting to send an email to the user with nodemailer and reactjs

When attempting to send an email to the user who submitted the application using ReactJS and Nodemailer, an error stating "route not found" is encountered. Warning: Location "/contact?name=milan&email=xedikaka%40gmail.com&phone=9843698469&city ...

Slow auto page refresh in local development for Angular2 on Windows can be quite frustrating

Recently diving into angular2 and following the heros tutorial from docs. Struggling with a sluggish development experience while working with angular2. It's taking approximately 5 seconds for angular2 to recognize changes in files, followed by anothe ...

Encountered a problem during the installation of tensorflowjs for node | Received an error: Command failed: node-pre-gyp install

While attempting to install @tensorflow/tfjs-node, I encountered the following error: Command failed: node-pre-gyp install --fallback-to-build. Is there a solution to resolve this issue? Below is the complete log: npm ERR! code 1 npm ERR! path E:\ ...

Discovering a method to detect clicks outside of a React functional component

Looking to identify when a click occurs outside of a React functional component. After stumbling upon an article, I followed the provided code but unfortunately, it didn't work as expected. Despite identifying the issue, I am still searching for a so ...