returning instanced class + babel JS - javascript

I'm building a "library" on JS, and it is mandatory to be only one .js file.
I just started to build, and i got this until now:
app-es6/main.js
class Sjs {
create(obj) {
console.log(obj);
}
}
index.html
<script src="app/main.js"></script>
<script>
let sjs = new Sjs();
sjs.create({
type: 'select'
});
</script>
.babelrc
{
"presets": ["es2015"]
}
What i need to do:
1) The class should not be instantiated in html, the instance should come ready from js, so i can just type sjs.create(), like jQuery, moment, etc.
2) If i need to import more JS files, to build somehting more structured, can i "wrap" to a single js, minimized?
Thanks in advice.

1) The class should not be instantiated in html, the instance should come ready from js, so i can just type sjs.create(), like jQuery, moment, etc.
Just put it in the main.js, after the class declaration:
let sjs = new Sjs();
let at global scope creates a global variable (though not a property on the global object [usually accessed as window on browsers]). If you want that property as well, use var instead of let or assign to window.sjs (which will also create a global variable; all properties on the global object are globals, it's just that as of ES2015, not all globals are properties on the global object).
That said, if it's a singleton, there isn't much benefit to using class. It's probably also worth noting that jQuery and MomentJS both expose functions (jQuery/$, moment), not non-callable objects.
2) If i need to import more JS files, to build somehting more structured, can i "wrap" to a single js, minimized?
You're looking for a bundler, like Webpack, Rollup, etc. They have plugins for integrating with Babel, doing minification, ...

Related

How to package object prototypes in separate file

I have created a number of String.prototype functions which for maintainability I'd like to have in its own file. That is, I'd like to include the file in a javascript project and thus have all the String functions defined.
I could create a module that exports each function, but then I'd have to assign each function as its own String prototype, yes? Something like
var myStringFunctions = require("myStringFunctions");
String.prototype.func1 = myStringFunctions.func1;
Is there a way to include such a file so that the prototypes are defined as part of the inclusion?
Try it, you will see your code and using require("./myStringFunctions"); works just fine.
./myStringFunctions.js
String.prototype.func1 = function() {
return this.toUpperCase(this);
};
./index.js
require("./myStringFunctions");
console.log("foo".func1()); // FOO
If your JS is going to run in the browser, you can use JS modules with the import and export syntax if you use a module bundling build tool like Webpack: https://webpack.js.org/ .
If your JS is running in a Node.js environment, modules are supported: https://www.w3schools.com/nodejs/nodejs_modules.asp

Global variables are undefined for imported Javascript functions

Trying to figure out if there is a problem due to the import/export method, or if my architecture just bad....
Previously, I had multiple files of javascript. Just functions, no classes. In one "center/main" JS file, there are global variables. These variables are accessed and used/updated by functions in that same file, as well as other files. Each JS file had to have its own tag within the index.html
The move was then to switch to webpack as a module builder which would remove the need for all those script tags. Instead I just have to import/export the functions.
The problem is that now after using that method, the global variables are undefined to the imported functions Below is the setup dumbed down, but I don't see why it would be a problem. Maybe I'm missing something.
main JS file
import * as SettingsFile from './settings';
var myVariableUsed;
$(document).ready(function() {
myVariableUsed = "test";
SettingsFile.startSettings();
});
secondary JS file (settings.js)
export function startSettings(json) {
console.log(myVariableUsed);
}
Hy, i think you can understant what is happening with this article:
https://medium.com/webpack/brief-introduction-to-scope-hoisting-in-webpack-8435084c171f
To be short, webpack creates a new scope for required files, because of 'use strict' declaration on generated code output.
To pass parĂ¢meters to required modules you need to do do something like this:
// somefile
require("lib.js")(param1, param2)
// lib.js
module.exports = function(param1, param2) { }

How to share objects/methods between controllers without circular references?

Pretty straightforward question. Currently, what I do when I need to access objects' methods throughout most of the application, I do this in app.js
Ext.define('Utils', {
statics: {
myMethod: function() {
return 'myResult';
}
}
});
This works, but when I build the application, I get a warning about a circular reference (app.js of course needs all the other controller classes, but then said classes refer back to app.js).
I thought of using a package including a .js file that has all the objects/methods, but sometimes, within these methods I'll need access to the Ext namespace so that won't work.
Is there any better way to do this ?
Thanks!
You should not define the class Utils inside app.js. Each Ext.define statement should be in it's own file. Also the classname should be prefixed with your app name.
Ext.define('MyApp.Utils', {
statics: {
myMethod: function() {
return 'myResult';
}
}
});
should therefore be found in the file app/Utils.js. When compiling your sources into a compiled app.js, Sencha Cmd will take care of the proper ordering in the final file. The requires and uses directives give you enough flexibility to define any dependences between your classes.
Read all the docs about MVC to get a clear understanding.

How can I autoload Moment.JS in Compound.JS?

I want Moment to be available globally, and I understand Compound is capable of auto-loading modules - so how would I use it? If I include "moment" in the autoload array, how can I use it in the application?
I know there's thoughts about redoing the module loading in compound, and I know it's also not easy to find information about how to do it.
I solved it by putting a loadLibs.js in config->initializers where I load modules like so:
module.exports = function(compound) {
compound.module1 = require('module1');
compound.module2 = require('module2');
//etc.
};
modules will then be available on the compound object.
just be careful not to try to overwrite some already existing keys on the compound object. you could also put it under a namespace like compound.myApp.module

Set of CoffeeScript/JavaScript classes and methods available to rest of Rails app

I'm using Rails 3.2.9. When I add CoffeeScript code to a .js.coffee file in the /app/assets/javascripts directory, I get the resulting JavaScript in all of my webpages. The problem is all the JavaScript is wrapped in:
(function() {
// my code
}).call(this);
So any methods I define are not visible in any other CoffeeScript code I write in other files. What's the proper way to write a set of reusable CoffeeScript classes and methods with Rails?
The simplest thing to do is to namespace all your classes. If your application is called "app" then in your initialization code before anything else happens:
// Set up the namespace.
window.app = { }
and then in all your .coffee files:
class app.Pancakes
#...
Then you'd have a global namespace and you'd reference everything through that namespace:
pancakes = new app.Pancakes
Similarly for simple functions:
app.where_is = (pancakes, house) -> ...
# And elsewhere...
x = app.where_is(...)
There are various ways of setting up and partially hiding the namespace but they're all variations on the above and simple namespacing plays nicely with the Rails asset pipeline.
Also, you can define classes within the coffeescript files like this:
class this.Person
constructor: (attr = {}) ->
...
In that way, the definitions are attached to the global namespace.

Categories