How to preserve export{my_function} in the output when using the Google closure compiler - google-closure-compiler

I have a simple task. The input is like this:
function my_function()
{
}
export {my_function};
I want to preserve the line in the output:
export {my_function};
The motivation is to use the output in my script later.
<javascript type="module">
import {my_function} from 'my_compiled.js';
</javascript>
I tried many options, but the output file does not have the "export" statement in it. Could you please help me achieve that?
Thanks.

As explained in Closure Compiler docs, you should set your exports on global object:
function my_function()
{
}
window["my_function"] = my_function;
export {my_function};
And later:
<javascript type="module">
var my_function = window.my_function;
</javascript>
Note that you need to use array accessor when setting export on global object, so that Closure Compiler does not rename it: window["my_function"] = ..

Related

firebase functions with top level variables state

I have firebase functions defined in index.ts file. This is importing another .ts file as below
import * as CommonCode from './common-code'
The common-code.ts have few variables declared at the top like below
export let baseUrl = ''
There are two functions inside index.ts as follows:
exports.function1 = functions.https.onRequest(async (req:any, res:any) => {
CommonCode.baseUrl = 'MyXXX.mydomain.com'
})
exports.function2 = functions.https.onRequest(async (req:any, res:any) => {
var x = CommonCode.baseUrl
})
if i make a call to function1 which is setting value of baseUrl. And then make call to function2 then will function2 persist the value set as a result of function1 or will be blank?
my understanding is that it should become blank when i call function2 every time as i am not setting it anywhere in function2. But with some observed weird behavior looks like my understanding is not correct. So what is the expepected behavior here?

Redux toolkit actionCreator warn: Invalid number of arguments, expected 0

it's action:
export const someAction = createAction('SOME_ACTION')
Is there a way to fix it?
Invalid number of arguments, expected 0
dispatch(someAction({key: 'val'}))
Okay, I found how, you just need to add function prepare by second argument like this
export const someAction = createAction('SOME_ACTION', prepare)
well, after this the next warn in saga
Unresolved variable type someAction.type
function* watch() {
yield takeLatest(someAction.type, getOneClientWork);
}
OMG!
As for your second problem: Try
function* watch() {
yield takeLatest(someAction, getOneClientWork);
}
But in general, those are TypeScript warnings that come from your IDE applying TypeScript to pure, untyped JavaScript code - in the hopes of giving you better autocompletion and hints. Unfortunatley, stuff like that goes wrong a lot of times.
So if you were writing TypeScript, you'd write
export const someAction = createAction<PayloadType>('SOME_ACTION')
and if you don't do that, it goes back to the default behaviour:
export const someAction = createAction('SOME_ACTION')
// defaults to
export const someAction = createAction<void>('SOME_ACTION')
and would mean "this takes no payload".
Now your IDE blindly applies TypeScript there, uses the default void and you end up with warnings that don't really concern you.

What is a good practice for adding flow type annotations on project specific named exports

Please correct me if i am wrong. As far as i understand it up till now; type annotations can be added to a file or in libdefs (for shareable code)
For example in a project specific file helpers.js
// #flow
export function square(value: number): number {
return value * value
}
export function someOtherFunction(arg: string): string {
}
etc...
And in a libdef helpers.js
declare module 'helpers' {
declare export function square(value: number): number;
declare export function someOtherFunction(arg: string): string;
}
What would be a good practice for writing flow annotations on project specific code and especially lots of code. For example helpers exposing 20+ named exports, as this is the point where i am starting to think having a libdef would be more clearer to reason about.
And is it at all possible to use that libdef file as the single entry? I've fooled around a bit and i always had to annotate in the file itself even though i had added the libdef and told flow through the config to include these libdefs.
In our project, we use the following approach:
// #flow
export const square: SquareType = (value) => {
return value * value;
}
So you can declare SquareType in the helpers.js file just above the function or you can move it to a separate file and import it then into helpers.js
Many third-party modules don’t have types or only TypeScript types.
And libdefs need for one reason. To declare types for untyped modules!
More info: https://flow.org/en/docs/libdefs/

Custom functions for knex

There's a number of operations that I do all the time and I was hoping there would be a way to "extend" knex to be able to do them.
I would like to something like:
oneExists
result = knex.count(id).from('table').where({'code': 25})
if (result.length === 0) return false
if (result.length === 1) return true
throw an error
I would like to be able to do something like
knex.oneExists.count('id').from('table').where({'code': 25}).
at the moment i'm writing the code like this:
KnexUtil.oneExists(knex.select('id').from('table').where({code: 25}))
which returns a promise
I've looked through the knex codebase and i'm not sure:
how to chain this (and whether i would do this in /lib/query/compiler.js)
how to just make an extension to knex so i don't need to modify the original codebase
Starting from v0.19.1, knex have build-in ability to extend QueryBuilder
import Knex from 'knex'
Knex.QueryBuilder.extend('someFn', function (arg) {
console.log('Do Smth', arg)
return this
})
const knex = Knex({ client: 'pg' })
knex.select().from('table').someFn(0).toString()
Sure you can. I would recommend just creating your own plugin, something like the following:
// my-plugin.js
'use strict';
module.exports = function (Bookshelf) {
Bookshelf.Model = Bookshelf.Model.extend({
foo: function ( bar ) {
if( bar )
console.log('Method foo was called on a model with the arguments:', arguments.join(', '));
}
});
Bookshelf.Collection = Bookshelf.Collection.extend({
foo: function ( bar ) {
if( bar )
console.log('Method foo was called on a collection with the arguments:', arguments.join(', '));
}
});
};
Then inside your main application file, add:
Bookshelf.plugin( require( './my-plugin' ) );
BookshelfJS plugins basically allow you to extend the models and collections (and more), which allows you to add your own method, or overwrite existing ones (while still being able to call the original method from within your plugin)
For a better understanding, it might be a good idea for you to look at some existing BookshelfJS plugins, some already come with bookshelf, inside the plugins directory.
Another plugin that may be good to look at to better understand how the plugins work, would be the Soft Delete Plugin. In that plugin, you can see how some BookshelfJS methods are overridden in both the models and the collections objects, with methods that execute the original version of the method, then return the parsed/modified result (Lines #37-#59 and Lines #37-#57), as well as adding completely new methods (Lines #61-#72)
Edit: Obviously this is more BookshelfJS than KnexJS, but I didn't see any way to create plugins for KnexJS, since it's just a query constructor, all the real magic is in the ORM
If using TypeScript:
import { knex, Knex as KnexOriginal } from "knex";
declare module "knex" {
namespace Knex {
interface QueryBuilder {
customFunction<TRecord, TResult>(
value: number
): KnexOriginal.QueryBuilder<TRecord, TResult>;
}
}
}
knex.QueryBuilder.extend("customFunction", function (value: number) {
console.log("Custom Function:", value);
return this;
});
const pg = knex({ client: "pg" });
pg("table").select("*").customFunction(10).toString()
Check out documentation about how to extend knex

Where to put helper methods used in events for multiple Meteor templates

I know that I can access methods across files by omitting var, but what is the "best practices" project directory structure for defining helper methods that are used by template events across different templates.
For example, I have:
template1.js:
Template.template1.events({
'event': function () {
helper();
}
});
template2.js:
Template.template2.events({
'event': function () {
helper();
}
});
One problem with Meteor's "share code across files with globals" approach is that when you're looking at the file where a function is used, you don't know where the function is defined. I prefer to define a single global variable in each file which needs to export variables. That variable has the same name as the file, with an initial capital (or some other naming convention which identifies it as an "export object"). Exports are stored as properties of that object. So you might create a file named globalHelpers.js:
GlobalHelpers = {};
GlobalHelpers.helper = function () {
// ...
};
And then use it in other files with GlobalHelpers.helper(). If you look at this code later, you know to look in globalHelpers.js to find the helper function.
If a file exports a single class or collection then it's okay to just use that object as the export object. So instead of things.js with Things = {}; Things.Things = new Mongo.Collection... you can just do Things = new Mongo.Collection....
You might need to place the file in a lib directory so it loads before the other files.
Don't register it with Template.registerHelper unless you want to call it directly from templates with {{ }} calls.
I suggest defining such functions in /client/scripts/globalHelpers.js
Example:
Template.registerHelper('foo',function(arg1,arg2){
return arg1 + arg2;
});
Then you can use this function from anywhere by prefixing it with Blaze._globalHelpers.:
var result = Blaze._globalHelpers.foo(param1, param2);

Resources