I am using babel as transpiler and I want to mangle some methods with uglifyjs.
Here is a demo:
class A {
methodA() {}
}
And its output by babel:
var A = function () {
function A() {
_classCallCheck(this, A);
}
_createClass(A, [{
key: "methodA",
value: function methodA() {}
}]);
return A;
}();
However when I try to mangle methodA, it does not work. Because methodA in the output is a string.
But the same code output by typescript works, it is not a string:
var A = /** #class */ (function () {
function A() {
}
A.prototype.methodA = function () { };
return A;
}());
So my question is: How can I mangle method name when using babeljs ?
OK, I found the answer.
Just use loose mode:
[ ['#babel/preset-env', { loose: true }] ]
The result will be closer to TS.
Related
Is there a way to abstract this Closure to my MerchantUser model in a way similar to using scopes on with()?
So far I have this which works:
$merchant_user->load(['permissions' => function ($query) use ($merchantId) {
if ($merchantId) {
$query->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
But I'd like to do something like this:
$merchant_user->loadPermissions($merchantId);
In my Model:
public function scopeLoadPermissions($query, $merchantId = null)
{
return $query->load(['permissions' => function ($q) use ($merchantId) {
if ($merchantId) {
$q->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
}
Which at the moment just returns an error:
"Method Illuminate\Database\Query\Builder::load does not exist."
For this case you dont need add scope. Instead if you can add this function in your model
public function loadPermissions($merchantId = null)
{
return $this->load(['permissions' => function ($q) use ($merchantId) {
if ($merchantId) {
$q->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
}
and usage
$merchant_user->loadPermissions($merchantId);
I defined many custom type in Utils.js: http://plnkr.co/edit/BGqDoWEC7DTmomEFHygd?p=catalogue
I want to add trim() in parseValue
parseValue: function (oValue) {
if(oValue !== null) {
return oValue.trim();
}
return oValue;
},
Copy and paste this function is kind of dumb, so I want to do sth. like :
trimString : function(oValue) {
if(oValue !== null) {
return oValue.trim();
}
return oValue;
},
mandatoryValueType : SimpleType.extend("text", {
formatValue: function (oValue) {
return oValue;
},
parseValue: this.trimString,
validateValue: function (oValue) {
if (!oValue) {
throw new ValidateException(Utils.i18n("MANDATORY_VALIDATE_ERROR"));
}
}
}),
But scope in mandatoryValueType seems can not access to this.trimString, what can I do?
this scope in parseValue function, no trimString function:
Another working sample : http://plnkr.co/edit/ahS6NlUHHL0kdvdddvgd?p=preview
Reference: https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.InputChecked/preview
Maybe you can put the trimString function outside the var Utils object, and set it as a global function.
here is the example: http://plnkr.co/edit/u64DEP0RnT5CJADZyXJg?p=catalogue
edit:
corrected by #boghyon, the trimString function should be a function in a closure, instead of a global function :)
in this case the this keyword contains the object which invokes the function: the controller which invokes mandatoryValueType of utils.js.
initialise in utils.js in the upper scope of mandatoryValueType a var that = this. then use inside of mandatoryValueType instead of this.trimString the that.trimString.
edit
self reference to a property of an object in a literal declaration of an object:
var Utils = {
...
trimString: function() {
...
},
...
parseValue: function() {
this.trimString();
}
..
}
I currently have this code:
// Imports
const {utils: Cu, Constructor: CC} = Components;
Cu.import('resource://gre/modules/Services.jsm');
Services.scriptloader.loadSubScript('chrome://trigger/content/webextension/scripts/3rd/polyfill.min.js');
function install() {}
function uninstall() {}
function shutdown() {}
function startup() { // this gets automatically called by the environment i am designing for
Services.prompt.alert(Services.wm.getMostRecentWindow('navigator:browser'), 'title', 'body');
}
async function doAsync() {
return await new Promise(() => setTimeout(()=>resolve('done'), 5000));
}
However after compiling with babel with this .babelrc:
{
"presets": ["es2015", "es2017"],
"plugins": ["transform-object-rest-spread"],
"ignore": [
"3rd/**/*",
]
}
It moves my doAsync function to the top. Before the imports. Which is a problem. Because the import needs to happen right away. As startup gets called right away.
The compiled code becomes this:
'use strict';
var doAsync = function () {
var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return new Promise(function () {
return setTimeout(function () {
return resolve('done');
}, 5000);
});
case 2:
return _context.abrupt('return', _context.sent);
case 3:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
return function doAsync() {
return _ref.apply(this, arguments);
};
}();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
// Imports
var _Components = Components,
Cu = _Components.utils,
CC = _Components.Constructor;
Cu.import('resource://gre/modules/Services.jsm');
Services.scriptloader.loadSubScript('chrome://trigger/content/webextension/scripts/3rd/polyfill.min.js');
function install() {}
function uninstall() {}
function shutdown() {}
function startup() {
// this gets automatically called by the environment i am designing for Services.prompt.alert(Services.wm.getMostRecentWindow('navigator:browser'), 'title', 'body');
}
Is there anyway so that if I use async/await that it doesn't move stuff to above my imports? If my imports at the top of the file, it fails to run. Because the imports brings in the polyfill.min.js
I have a class with over 80 methods, and each method accepts an object containing some defined interface.
class Stuff {
/* many more */
getAccount(req: IAccount, callback: ICallback) {
return this._call('getAccount', req, callback);
}
getIds(req: IIDs, callback: ICallback) {
return this._call('getIds', req, callback);
}
/* many more */
}
pretty 'boring' stuff, since it's just mapping to the underlaying _call method and making it type safe for each of the methods.
But sometimes these req param objects are made up from 2 interfaces or more, and instead of creating another interface for each time there's an "awkward", like this:
export interface ILoled extends IAccount {
loled: boolean;
}
export interface IRofloled extends ILoled {
rofled: boolean;
}
class Stuff {
getLols(req: ILoled){
}
getRofls(req: IRofloled){
}
}
is there any way I can just put it as an "inline" mixin of interfaces inside the method parameter list? like (which obviously don't work):
class Stuff {
getMoreStuff(req: <{} extends IAccount, ITime>) {
}
}
Yes you can, as of Typescript 1.6. Called Intersection types, use the & operator to combine types.
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U> {};
for (let id in first) {
result[id] = first[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
result[id] = second[id];
}
}
return result;
}
var x = extend({ a: "hello" }, { b: 42 });
x.a; // works
x.b; // works
is there any way I can just put it as an "inline" mixin of interfaces inside the method parameter list
No. You cannot extend an interface inline
I'm learning Mootools classes at the moment and there's something that I can't seem to get my head around or find a decent example.
Basically, I need to be able to call a function within a different function of the same class; example below:
var Bob = new Class({
initialize: function () {
this.message = 'Hello';
},
someOther: function() {
this.message2 = 'Bob';
},
getMessage: function() {
return this.someOther();
},
});
window.addEvent('domready', function() {
var map = new Bob;
alert(map.getMessage());
});
From this code, I would have thought that the alert would produce 'Bob' which has been set in the function 'someOther' but it's outputting a undefined message.
Can anyone help or point out where I'm going wrong?
Thanks in advance,
er not quite.
someOther has no return value in itself, it's a setter. you invoke it and it will set this.message2 into the class but it returns nothing. methods should return this (the instance, so making it chainable) or a value, when a getter.
anyway, you can make it set the property and return it like so:
var Bob = new Class({
initialize: function() {
this.message = 'Hello';
},
someOther: function() {
return this.message2 = 'Bob'; //bad
},
getMessage: function() {
return this.someOther(); // why
},
});
window.addEvent('domready', function() {
var map = new Bob;
alert(map.getMessage());
alert(map.message2); // bob
});
though, semantically, you want to have 1 getter. .getMessage should just return this.message - you can write a different method that calls someOther and returns it.
have a look at this pattern for a getter/setter in a class context I wrote the other day:
http://fragged.org/using-overloadsetter-overloadgetter-to-make-flexible-functions-in-mootools_1451.html
etc etc. for more help, look at the keetology blogs or davidwalsh.name - or the mootorial - plenty of examples of class use and structure.
most key ones are listed here: https://stackoverflow.com/tags/mootools/info