How to pack my library in a self executing function? (emscripten) - javascript

I've created a library in C++ using Embind and Emscripten.
Some hand written JS code is also added to the library using --pre-js
The library works. But I would like to rearrange the code, to this:
var MYLIB = (function(){
// ... Original Code ...
return Module;
})();
So the code would not pollute the global namespace, and the code minifier could do better optimizations.
Are there build in functions for this in emcc ?
The library will only run in webbrowsers, not in nodejs.

What you're looking for are the MODULARIZE and EXPORT_NAME options. Check the documentation in settings.js.
Quoting from that file:
// By default we emit all code in a straightforward way into the output
// .js file. That means that if you load that in a script tag in a web
// page, it will use the global scope. With MODULARIZE set, we will instead emit
//
// var EXPORT_NAME = function(Module) {
// Module = Module || {};
// // .. all the emitted code from emscripten ..
// return Module;
// };
//
// where EXPORT_NAME is from the option of the same name

Related

How to use this in javascript module pattern?

I'm studying module pattern and have a question.
I want to use 'settings' anywhere.
script1.js
var MODULE = (function() {
var t = {};
this.settings = { // this == Window
users: ['john', 'emma']
}
return t;
})()
script2.js
MODULE.dom = function() {
var t = this; // this == MODULE
document.querySelector('p').textContent = t.settings.users[0]; // error
function _say() {
return t.settings.users[1] // error
}
return {
say: _say
}
}
MODULE.DOM = MODULE.dom.call(MODULE)
When use this.settings = {...}, 'this' means Window so code doesn't work.
When use t.settings = {...}, 'this' means MODULE so code works but when write MODULE in dev console, settings is exposed in MODULE variable. Is it ok?
I'd greatly appreciate any help, thank you!
When use t.settings = {...}, 'this' means MODULE so code works
That's the right way to do it.
but when write MODULE in dev console, settings is exposed in MODULE variable. Is it ok?
It's mostly OK.
If you're worried about the client being able to type in the variable name and see the code that gets run - there's no way to avoid that. They can just look at the devtools to see what the network requests are, and what is downloaded - or look at the Sources panel.
If you're worried about running into naming collisions with larger scripts, then - sometimes, libraries deliberately assign themselves to the window to allow other parts of the code to access them. Perhaps you'd like your MODULE to be like this. If not, then you should utilize JavaScript modules instead, which allow for scripts to be imported inside other scripts without polluting the global namespace at all or having any possibility of naming collisions. For example, you could do
// script1.js
export const MODULE = {
settings: {
users: ['john', 'emma'];
}
};
// script2.js
import { MODULE } from './script1.js';
// proceed to use MODULE
And you can do import { MODULE } from './script1.js'; from any script file, not just script2.js.
Personally, I consider the IIFE module pattern in JavaScript to be mostly obsolete nowadays. For any reasonable-sized script, better to write code in separate files and then import and export as needed. (A 1000 line file is somewhat hard to debug and refactor. Ten 100 line files are easier to debug and refactor.)

How do you manage namespace in Meteor?

So here is my problem :
Currently, I have a dozen of functions related to WEBRTC within a template js file. My objective is to have those functions in a separate file, called webRTCWrapper.js for example, and to call those functions in my template without using global variable.
I think I must use namespaces, am I correct ?
If so, how do you use them ?
EDIT : For anyone interested, this is exactly what I was looking for :
http://themeteorchef.com/snippets/using-the-module-pattern-with-meteor/
Make a directory called packages/ parallel to your .meteor/ directory. You can create a package that exports a single object/function. On the command line, use meteor create --package <yourpackagename> and meteor add <yourpackagename> You can edit the js file to add a namespace.
MyNamespace = {};
MyNamespace.myFunction = function () { };
Then, in the package.js, simply export that namespace.
api.export('MyNamespace');
You can use a common pattern of having a global object and your functions inside that object.
Greetings = {
hello: function(name) { return "Hello "+name+" how are you?"; }
}
And then you can call it inside the template helpers :
Template.GreetingsTemplate.helpers({
sayHello: function() { return Greetings.hello('Maxence'); }
})
Take note of the loading order of files in Meteor, anything inside the lib folders is loaded first. If you run into problems where "Greetings" object is not defined, then its because that file was not loaded already.
Edit:
You can reuse the same pattern for adding more functions in different files (you could use App = App || {} but it will throw error in Chrome for example).
App = (typeof App === 'undefined')? {} : App;
App.someFunction = function(){};
or even, if you use underscore.js:
App = (typeof App === 'undefined')? {} : App;
_.extend(App, {
someFunction: function(){}
});
Since now the regular way to use the code from another file was going through a global (server and client). As Joao suggested you can make your own global App variable where you will store or more generically a global MODULE one (basically the same solution as Joao but with explanation).
But with with the arrival of ES2015 support, we will very soon be able to have an official pattern to achieve this. However as the 1.2 does not supports yet the import/export syntax:
Note, The ES2015 module syntax (import/export) is not supported yet in Meteor 1.2.
If you want to start using those features earlier, I would recommend using this package which is an temporary solution to fill the current import/export gap, the meteor team development are currently looking for an elegant solution to support this.

How to keep a reference to a RequireJS module?

I'm trying to figure out how RequireJS works, but the RequireJS website is very unclear on explaining the basics, especially concerning how to use the 'require' and 'define' methods.
I have the following example running:
//module1.js
define([], function () {
var returnedModule = function () {
var _name = 'whoa I am a module';
this.getName = function () {
return _name;
}
};
return returnedModule;
});
//main.js
require(['module1'], function(temp_reference){
var m = new temp_reference();
console.log("created module: " + m.getName());
});
// ... some other code ...
// now, if I need the module1.js again, do I need to require it again??
My question: do I need to "require" this module1.js file every time I want to do something with it? (in this case creating a new m() object from the temporary reference).
Can't I keep the result of the require call somewhere instead of only having it available inside the callback?
EDIT
I thought I could solve the issue by keeping a reference this way:
// keep the required module available
var myModule = require("module1");
But this generates an error: module1 is not yet loaded.
Require JS is an AMD - Async module definition meaning the modules are loaded into the document when you require it. It kinda provides a functional scope/modular approach to your JavaScript code, say like import keyword in Java or Using key word in C#.
Now answer to your question : Yes you need to reference the defined module in your require module to get its reference as a functional parameter.
For example consider the below code
http://jsfiddle.net/NssGv/52/
define('a', {
add: function(x, y){
return console.log(x + y);
}
});
// Use the module (import)
require(['a'], function(a){
a.add(1, 2);
});
require(['a'], function(a){
a.add(4, 6);
});
In this code context , a - is module definition that is imported by the other modules to access add() method of the defined module.
Require JS constructs a module tree and saves all the defined module in this tree with the name of the module. In tis example its - a (this is called named module)
This tree can be accessed as below through dev console
window.requirejs.s.contexts._.defined.a
And my output would like this:
When ever your load an external modular file Require JS creates a <script> tag and appends it into the document <head>
Consider your example:
Working plunker link : http://plnkr.co/edit/eNQkcfwftkYSY00wMPeI?p=preview
When the below entry point codes are executed
HTML:
<script src="xdomain/require.js" data-main="script"></script>
JS:
require(['module1'], function(temp_reference){
var m = new temp_reference();
console.log("created module: " + m.getName());
});
Require JS attaches 2 files namely script.js (referenced in script tag in HTML head as main script file) and second is module1.js (referenced in script.js)
After attaching this file to the head asynchronously the code in the modules is executed and the resultant of the module will be pushed to the requirejs module tree as mentioned earlier.
Later these modules are injected into the reference modules based on your dependencies definition you pass as array to the require function.
require([{{YOUR_DEPENDENCIES}}], function({{INJECTED_REFERENCES}}){
--Your code--});
This is what you are trying to achieve(Not suggested)
http://plnkr.co/edit/5SYoNf8xNL1DcMfjuy0Y?p=preview
var myModule; //Global variable
require(['require', 'module1'], function(require){
myModule = require("module1");
var m = new myModule();
console.log("created module: " + m.getName());
});
You can also try this Hacky!
http://plnkr.co/edit/Rr34HlhOiyja6XnwH8fw?p=preview
var myModule; //Global variable
require(['module1'], function(){
myModule = window.requirejs.s.contexts._.defined.module1;
var m = new myModule();
console.log("created module: " + m.getName());
});
Finally
Require JS is giving the javascript modularity approach and on demand loading of scripts rather than preloaded in the memory. This saves some memory and also contribute to the speed of your web app. Your code becomes structured automatically and will be easy to maintain.

convert a javascript library to AMD

I'm trying to use a library -- Google's libphonenumber -- in my require application that is not AMD. What is the best way to consume this? I know I can create a module like this:
define(['module'], function (module) {
// insert and return library code here.
});
But that doesn't seem great. It seems like I would have to refactor some of their code to get that working (e.g., turn it all into an object and return that object). I see a lot of libraries using a different pattern where they use an immediately invoked function that defines the module on the window object and returns it.
(function() {
var phoneformat = {};
window.phoneformat = phoneformat;
if (typeof window.define === "function" && window.define.amd) {
window.define("phoneformat", [], function() {
return window.phoneformat;
});
}
})();
** UPDATE **
Is there any reason not to just do this?
define(['lib/phoneformatter'], function(phoneformatter) {
});
I get access to all of my methods but now it seems they are global because I did not wrap the library in a define...
Use RequireJS's shim. It'll look something like this
requirejs.config({
shim: {
'libphonenumber': {
exports: 'libphonenumber' // Might not apply for this library
}
}
});
This will load libphonenumber and put its variables in the global scope
This ended up working for me:
define(['module'], function (module) {
// insert and return library code here.
});
I am not entirely sure why 'module' was necessary. But it doesn't work without it. Also, I just returned an object and attached functions to it like so:
return {
countryForE164Number: countryForE164Number,
nextFunction: nextFunction,
// more functions as needed.
}
There is not much in the way of documentation for using 'module' but from what I can ascertain: Module is a special dependency that is processed by requireJS core. It gives you information about the module ID and location of the current module. So it is entirely possible that I messed up the paths in config.

different ways to parse and build with Grunt

In my project, i use an external library that it has some private functions on its local scope, it seems like this:
(function(window, undefined) {
var isArray = function() {...}
var forEach = function() {...}
var int = function() {...}
{(this))
The external lib gives me some funcionality, but additionally i will use these functions i mentioned in my project, so, I need to put externalLib private functions on window scope. To avoid that, i'm going to build myLib.js with my code and the externalLib code.
So, i need to put some code from externalLib.js (basically i only need to remove first and last line from the code).
What do you think about the best form to accomplish this task in GruntJS? I hope I explained well
You can preprocess files during grunt.js build using grunt-preprocess module. This requires some additional directives in your code:
// #ifdef DEBUG
(function(window, undefined) {
// #endif
var isArray = function() {...}
var forEach = function() {...}
var int = function() {...}
// #ifdef DEBUG
{(this))
// #endif
Where DEBUG can be any environment variable added either via command line switch or configuration file.
Also you can use #exclude directive that will simply remove code from grunt.js processed files. More on this here - https://github.com/onehealth/preprocess#directive-syntax

Categories

Resources