Need to import non ES6 library without export to VueJS - javascript

I have a strange problem to solve.
In a future VueJS project we need to use a library which is quite outdatet but there is no time to rewrite it.
It is a JS file containing a lot of silly var's declared, some functions and prototypes.
It is mainly structured like this:
var t1 = 'test1';
var i1 = 2;
function testclass(arg) {
object1 = this;
this._t1 = null;
return object1;
}
testclass.prototype = {
dosth: function () {
console.log('doing');
}
}
But its about 10.399 Lines of code so no way of rewriting it to a object or integrating export to each function.
Do you guys have any good idea or tool to manage this problem.
The only whay until now would be to import it seperatly as script tag but then our linter would cry and it also would look quite ugly.

Use eslint cli and run it with the --fix flag. This can fix a lot of these issues with the linter. https://eslint.org/docs/user-guide/migrating-from-jscs#--fix
Other than stylistic changes and es6 syntactic sugar, it will work just fine in the browser, so there's no need to rewrite anything.

Related

What's a good alternative to Object.assign?

I have
var shared = {
}
var stuff = Object.assign(Object.create(shared),{
//stuff
});
But Object.assign doesn't work on Safari and I don't wanna use something like Babel since my website is already kinda laggy. Is there any good alternative to make it so I can do this while maintaining "stuff" inheritance to "shared"..
var shared = {
}
var stuff = Object.create(shared);
stuff = {//stuff
};
I realize I can simply assign properties one by one to "stuff" but I have a lot of properties there and it would make the code a lot less organized
If you want another way to copy properties, how about something like this (copies everything from A to B):
const a = {hello:1, world:2};
const b = {};
Object.keys(a).forEach(k => b[k] = a[k]);
// b is now {hello:1, world:2}.
If you want quick dirty solution with minimal change to your codebase, try this pkg https://github.com/rubennorte/es6-object-assign
In my opinion, you should use bundling framework, say webpack, alongside with babel. There are many ways to reduce the bundled file size like tree-shaking, minifying, separating vendor files and sending JS files gzipped to the browser and it is not laggy at all.

Preserve prototypes in ADVANCED mode

I need to compile my code with closure compiler in ADVANCED mode. I also need to keep prototypes of my objects in my application because I'm looping on Javascript objects prototypes. Trying to get both results in some ReferenceError when starting the application.
When compiling with ADVANCED mode, some prototypes are removed and replaced by a function that is using an object parameter in order to recover "this" keyword. This is due to crossModuleCodeMotionNoStubMethods attribute of CompilerOptions.java.
Example of code before compilation :
function MyClass() = { // Some code }
MyClass.prototype.someFunc = function() { // Some code calling someOtherFunc };
MyClass.prototype.someOtherFunc = function(someParam) { // Some code };
Example of code after compilation :
function MyCompiledClass = { // Some code }
MyCompiledClass.prototype.someCompiledFunc = function() { // Some code calling someOtherFunc }
function someOtherCompiledFunc(that, someParam) = { // Some code }
I first tried to use #this and #preserve JSDoc tags to solve the problem, without success. Using #export is not a solution, because functions will then keep their original names.
I've found two options to solve my problem for now :
Refactor the code as seen here
Build a custom version of Closure Compiler as seen here
Option 1 will need to much modifications in my code and will make it less readable, if it's the only solution, I will have a go for this one.
Option 2 seems to be a nice workaround, but I've read that some changes on CompilationLevel.java may violate some core assumptions of the compiler. Can someone tell me if by modifying setCrossModuleMethodMotion from true to false, will it still respect all core assumptions of the compiler ?
I'm currently building a custom version of the compiler to check if the code is compiling properly, but even if the code is usable, I need to be sure it will be properly obfuscated.
Thank you !
The specific optimization pass you are referring to is DevirtualizePrototypeMethods. The best way to block the optimization would be to use the #nocollapse annotation. It will allow your method to be renamed but not allow it to be removed from the prototype.
I'm not 100% sure it will work for this case, but if it doesn't it should and you can file an issue to have that fixed: https://github.com/google/closure-compiler/issues
You can export constructors and prototype properties in the same way.
For example:
MyClass = function(name) {
this.myName = name;
};
MyClass.prototype.myMethod = function() {
alert(this.myName);
};
window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod;
As in https://developers.google.com/closure/compiler/docs/api-tutorial3

Difference between javascript modularisation and dependency Injection

What 's the difference with the modularisation of a javascript code (with browserify by example) and the dependency injection?
Are they synonymes? Are the two going together? Or Am I missing some point?
Modularisation refers to breaking code into individual, independent "packages".
Dependency injection refers to not hardcoding references to other modules.
As a practical example, you can write modules which are not using dependency injection:
import { Foo } from 'foo';
export function Bar() {
return Foo.baz();
}
Here you have two modules, but this module imports a specific other hardcoded module.
The same module written using dependency injection:
export function Bar(foo) {
return foo.baz();
}
Then somebody else can use this as:
import { Foo } from 'foo';
import { Bar } from 'bar';
Bar(Foo());
You inject the Foo dependency at call time, instead of hardcoding the dependency.
You can refer this article:
Modules are code fragments that implement certain functionality and
are written by using specific techniques. There is no out-of-the box
modularization scheme in the JavaScript language. The upcoming
ECMAScript 6 specification tends to resolve this by introducing the
module concept in the JavaScript language itself. This is the future.
and Dependency injection in JavaScript
The goal
Let's say that we have two modules. The first one is a service which
makes Ajax requests and the second one is a router.
var service = function() {
return { name: 'Service' };
}
var router = function() {
return { name: 'Router' };
}
We have another function which needs these modules.
var doSomething = function(other) {
var s = service();
var r = router();
};
And to make the things a little bit more interesting the function
needs to accept one more parameter. Sure, we could use the above code,
but that's not really flexible. What if we want to use ServiceXML or
ServiceJSON. Or what if we want to mockup some of the modules for
testing purposes. We can't just edit the body of the function. The
first thing which we all come up with is to pass the dependencies as
parameters to the function. I.e.:
var doSomething = function(service, router, other) {
var s = service();
var r = router();
};
By doing this we are passing the exact implementation of the module
which we want. However this brings a new problem. Imagine if we have
doSomething all over our code. What will happen if we need a third
dependency. We can't edit all the function's calls. So, we need an
instrument which will do that for us. That's what dependency injectors
are trying to solve. Let's write down few goals which we want to
achieve:
we should be able to register dependencies
the injector should accept a function and should return a function which somehow gets the needed resources
we should not write a lot, we need short and nice syntax
the injector should keep the scope of the passed function
the passed function should be able to accept custom arguments, not only the described dependencies
A nice list isn't it. Let's dive in.

How to use `require` and dependency injection, service location in JS (browser-side)?

So I've been playing with JS and browserify to allow to split my JS into smaller file chunks. It works great, however, I'm still lost on how to properly use the require function.
For me, it acts as a the Service Locator, because it looks for the proper "file" to load, and return an object. (For example in PHP, require somewhat load the file in the memory but doesn't construct).
Example:
var Foo = function() {
console.log("I'm the Foo object");
};
module.exports = Foo;
Then, to use it I'll do:
var Foo = require('foo');
and
var foo = new Foo();
Note, that the exported function is NOT constructed.
I could have done:
var foo = require('foo')();
None of those methods seems right to me (I may are wrong).
1) Is it common to do it like this? Or should exported the executed function?
Anyway, this introduction is to understand how I should play with the require function.
For example if I've a Foo object, which is depends of Bar, I've two way to do:
Service Location:
var Foo = function() {
var Bar = require('bar')();
Bar.doSomethingAwesome();
};
module.exports = Foo;
or I can do:
Dependency Injection
var Foo = function(bar) {
bar.doSomethingAwesome();
};
module.exports = Foo;
// And at a latter time
var foo = require('foo')(require('bar')); /// eurk
I obviously know that that's two different things and serve different purposes.
2) But I'm wondering what is the common/right way to do in JS, is there any commonly admitted rules?
Browserify allows you to program with modules, there's not much more to it. It's not really a DI container or service locator per se, although you can probably make it work like one.
So doing this is perfectly fine:
var Foo = require('foo');
var foo = new Foo();
In that case, it makes sense to simply place all require calls at the top of your file, similar like you would do with using in C# or import in Java. I personally wouldn't scatter require calls since don't help much with readability.
You can also export an instance which doesn't have to be newed up anymore, as long as that is appropriate for what you want to do (in that case module.exports = Foo() would lead to a singleton).
Also see this related question:
Dependency Injection with RequireJS
The rewire library provides module injection for Node.js.
A couple of solutions have been discussed and presented in this Github issue to support browserify.
Usage example from the project README:
var myModule = rewire("../lib/myModule.js");
myModule.__set__("fs", fsMock); // set private variable
Use Browserify so you can require npm packages from your browser just like node. Then you can use Weather.js or require it, then inject it in any way you like.

Node.js Module plugins

I was hoping to find out what the best practices are for writing Node.js modules, specifically for the type of javascript pattern to follow for code separation.
One style I've been using, is this:
var Something;
Something = (function() {
function Something() {
}
Something.prototype.some = function() {
}
return Something;
})();
module.exports = Something;
Another style would be :
module.exports = {
item: "one",
some: function() {
},
another: function() {
}
}
Is there any reason why the second method would not be advised, in node.js? or is there another format that would be preferred and what would the advantages be?
Thank you!
You run into issues using the 'this' keyword. Which you have to use instead of 'Something'. So Something.some() you can run... But if you wanted to run that on the bottom, you'd have to run this.run(). The scope of this changes within other functions and can get messy.
There are several variants including assigning properties directly to exports, assigning a new object literal to module.exports and a few others. For the most part they are just syntax sugar or syntax alternatives that accomplish exactly the same thing. My personal preference is to leave as much of my code as possible unpolluted pure JS, and keep the CommonJS idioms separate. So I do:
function myFunction() {
}
var MY_STRING = "Forty-two";
module.exports = {
myFunction: myFunction,
MY_STRING: MY_STRING
};
It's a bit boilerplate-y and prone to maintenance mistakes, but I prefer it to the alternatives as I really dislike putting the CommonJS module level names (module, exports) sprinkled throughout my code. CoffeeScript makes the last part easier since you can just do:
module.exports = {
myFunction
MY_STRING
}

Categories

Resources