With RequireJS, you can do something like:
define(['a', 'b', 'c'], function(a, b, c) {
console.log(arguments);
}
Is it possible to do something similar for an ES6 module? Ex:
import a from 'a.js';
import b from 'b.js';
import c from 'c.js';
console.log(imported_objects); // should console log the values of a, b, and c
I'm asking because I'm working on a project that transforms AMD code to ES6 modules. When I do the transform, arguments is undefined because we're no longer inside of a function, but I need to be able to do something similar in ES6. I'm guessing this isn't possible because these are static imports? Thanks for any help
Just write
console.log([a, b, c]);
There is no meta way to get this list from the environment. You can however easily generate it yourself by looking at the list of imports, especially when writing an automated code transform.
Related
To learn more about decorators I would like to create a decorator which caches the output of a function, something like this
class BarFoo {
#Cahced()
doComplexCalc(#CahcedParamIgnore() a, b, c) {
}
}
DEMO
The #Cached decorator caches the response from doComplexCalc based on the values from a, b and c. As you can see in the example, I would also like to be able to ignore one or more method arguments. My question is, what would be the best way for the #CahcedParamIgnore decorator to inform the #Cached decorator about which arguments to ignore?
I'm trying to port the haskell library minisat to JavaScript using ghcjs, for integration in a larger haskell-ghcjs project.
minisat contains a couple of ffi imports from a c library. I've manged to compile the c library to javascript using emscripten, and to export the functions that minisat requires. So far, so good.
However, there are a couple of imports that look like this:
foreign import ccall safe minisat_solve :: Solver -> Int -> Ptr (Lit) -> IO (Bool)
which imports a function that looks like this:
int minisat_solve(minisat_solver *s, int len, minisat_Lit *ps)
My understanding, from the documentation, is that when emscripten exports a function that takes or returns a pointer, the pointer becomes a JavaScript number type.
The ghcjs documentation suggests that it should be possible to leave the existing foreign imports in place, by appropriately wrapping a JavaScript function. However, ghcjs represents pointer types as roughly a pair consisting of a JavaScript object and number.
I think the wrapper code should be roughly
function h$minisat_solve(...){
...
minisat_solve(...)
...
}
function minisat_solve = Module.cwrap('minisat_solve',...,...)
But I'm stumped by the type mismatch.
So, here's the challenge: Explain how to properly wrap an emscripten export for ccall import by ghcjs, using the above wrapper code as an example (or a counterexample, if I've got it completely wrong)
Pointer types can be converted to and from integers: https://hackage.haskell.org/package/base-4.10.0.0/docs/Foreign-Ptr.html#t:IntPtr . Thus, you ought to be able to convert to / from any format that emscripten requires using those functions.
In one of my NodeJS application , I noticed the below code;
const { Function } = require('./modules/helpers.js')
Is this valid? Also any benefits of using const for the require ?
Yes, destructuring assignment is a valid syntax:
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
({a, b} = {a: 10, b: 20});
console.log(a); // 10
console.log(b); // 20
See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
EDIT:
As for the benefits, It is a syntax sugar in most of the case. It allows you to refer the import functions directly as Function instead of Helper.Function.
It can also reduce your bundle.js file size.
Making use of const has some big improvements for yourself. So you can't change your imported modules anymore. This imported modules is so called immutable, which is really good for some points. For more have a look over here: Short Introduction into immutable data structures
Edit: const doesn't really mean that a value isn't changeable anymore, but it means that the object at this point can't be reassigned. (Thanks to #Mark Stosberg for pointing that out again)
(simply the code is more easily to reason about and it is about good code style)
And the syntax is valid ES6 destructing syntax. Make sure that your module exports an variable called Function. For more have a look over here: MDN Destruction Syntax
In JavaScript, specifically in node.js setting, one can spell module.exports = 13; in module.js, then x = import ("module.js"); elsewhere and have 13 assigned to x directly.
This saves some code when a module exports a single function, and I notice a lot of widely used packages (such as through2) make use of it.
Is there a way to do the same in Python? With some black magic, maybe?
I do have heard of a thing called loader that's, I guess, supposed to do some manipulations with a module before making it available. In particular, I think SaltStack makes use of something like that in salt.loader, but the code is too hard for me to follow. I imagine we could write a function similar to this:
def loader(module):
m = __import__(module)
return m["__exports__"]
— Then define __exports__ somewhere in a module we want to import and enjoy functionality very similar to JavaScript's module.exports mechanics. But unfortunately TypeError: 'module' object has no attribute '__getitem__' prevents us from doing that.
Python has importing built in to the language at a more basic level than Javascript does, almost all use cases are covered by a simple import statement.
For your example, all it really boils down to is:
from module import exports as x
So, there's not need to look for code savings by changing module.
The other part of the question is how, as a module author, would you restrict people to seeing only a single symbol.
Generally this is not required except to help users know what are public functions vs implementation details. Python has a few common idioms for this:
Any names that start with a leading underscore, such as _helper, are considered private. They can be accessed as normal, but the implication is you should not.
If a module level variable __all__ = [...] exists, only the strings it contains are considered public. The names must seperatedly be declared in the module.
As well as being documentation, both of these do affect one aspect of the module import:
from module import *
Using a star import is generally discouraged, but only public names will be brought in to the local namespace.
After some thinking I understood that, while we can't say m["__exports__"] due to module object's class not having __getitem__ method, we can still access some of the module's elements with "dot" notation: m.__exports__ works.
Another way: screen all module level names off with an underscore and assign the object to be exported to a variable named after the module, then from module import *.
loader.py:
def loader(module):
m = __import__(module)
return m.__exports__
exports.py:
def _f():
return 13
_a = 31
exports = {"p6": _f, "p8": _a}
__exports__ = exports
Python 2.7:
>>> import loader
>>> e = loader.load ("exports")
>>> e
{'p8': 31, 'p6': <function _f at 0x7fb79d494cf8>}
>>> from exports import *
>>> exports
{'p8': 31, 'p6': <function _f at 0x7fb79d494cf8>}
Python 3:
>>> import loader
>>> e = loader.load ("exports")
>>> e
{'p6': <function _f at 0x7f88ae229ae8>, 'p8': 31}
>>> from exports import *
>>> exports
{'p6': <function _f at 0x7f88ae229ae8>, 'p8': 31}
In the first way proposed, I unfortunately cannot use __all__ in loader.load to filter only listed names from a module being loaded since __getitem__ is not defined for module object.
In the second way proposed I don't get so much control (in that a malicious module can export arbitrary names and manipulate my namespace) and flexibility (in that I cannot assign the module's exported object to arbitrary name anywhere in my code).
So, there is still a bit left to be desired here.
One of the things that really draws me to TDD is the clear development of your spec alongside implementation.
I am seeking to implement a constructor that accepts a configuration object
function MyConstructor(conf) {}
conf is currently spec'd to have two keys: a and b, where a is a RegExp and b is a Function, and as part of my TDD spec elucidation ambitions, I am writing tests that spec out this object as such:
I would like MyConstructor to throw an Error if either a is not a RegExp or b is not a Function.
MyConstructor throws an Error if either a or b is missing from the configuration.
Now, I know that I could encapsulate this behavior in some other constructor, say a Configuration constructor that creates "configuration" objects. But the way I am seeing this now, regardless of where this behavior ends up, this behavior has to be encapsulated somewhere for this spec to be elaborated via TDD.
The problem is: I seems to me that as the number of keys on the conf object grows, so does the number of tests—exponentially! This is especially due to the second bullet above.
For example, say I have 4 keys: a, b, c and d, and I need to make sure that if any are missing an Error is thrown. It seems that this requires that I write a ton of identical, banal tests that cover all the possibilities (combinations!) for missing keys. That doesn't sound right! Yet, I can't think of a good way explicitly or inductively test that all scenarios are covered. Any thoughts?
Objects without a class definition or interface are hard to test. If your objects are ducks you'll need to use ducktyping to check.
You can also wonder about how useful it is to completely test certain functions. You can test the boundaries but you can never test all values;
If your function looks like this:
function sum(a, b) {
if (a === 42) {
throw new Error("All glory to the hypnotoad");
}
return a + b;
}
how are you expected to find this bug?
I would suggest you use Duck Typing to enforce the types. Essentially, what you'll do is use the objects passed in by your keys as you'd expect them to, and let the JS runtime complain if, say, a doesn't behave like a RegEx or you can't call b like a function.