There is a solution do avoid named input (the lazy way), which is not the final word, but maybe an interesting starting point:
In DML.js, we set the export:
export{h1,h2,....}
Now we import our library as dml and make it accessible in the global scope
<scripttype="module">import*asdmlfrom"../lib/DML.js"dml.h1("h1 test");// Make all functions in dml global(function(){for(const[key,value]ofObject.entries(dml)){window[key]=value// Store the references as variables}})()h1("h1 test")</script>
I know this is a bad solution for many reasons. But it might be a starting point:
The solution above defines all symbols as global variables, which we wanted to avoid. I just did not find a way to define scoped (e.g. local) variables that way. If we could manage to create scoped variables, this has many advantages:
We could use all elements of any library without qualifiers in a local context
All definitions are scoped, so leaving the scope will delete the definitions
No name clashes, as all definitions are local.
We can use dynamic import, which is pretty close to lazy loading in some cases.
So, my question is: Does anybody know a way to create local variables or const dynamically in Javascript?
The final solution could be something like this:
<scripttype="module">import*asdmlfrom"../lib/DML.js"// Make all functions in dml local(function(){for(const[key,value]ofObject.entries(dml)){????????????[key]=value// Your Idea here}h1("h1 test")// call h1 INSIDE the function })()// leave the scope</script>
On the principle that clearer code is better code, you should explicitly import the things you want to use in a module. Using import * imports everything in the module, and runs the risk of confusing maintainers. Similarly, export * from "module"; imports and then re-exports everything in the module, and runs the risk of confusing not just maintainers but also users of the module.
Also keep in mind that in C/C++ include occurs at compile-time so there is no runtime cost to dumping a boatload of unused names into the code. In JavaScript import happens at run time so potential for "more work" comes with the potential for undesirable run time consequences.
That boils down to the fact that any library based on eval, Function, hence the with statement, is practically future hostile. TC39 has no intention to resurrect the with statement, so even if I have libraries based on it, ‘cause it’s an awesome feature, be careful what you pick.
I like any kind of dirty tricks, but 'eval' is really nasty. As this may cause serious security issues I would not try to use it. But I´m sure there will be a solution without.
Calling the constructor directly can create functions dynamically but suffers from security and similar (but far less significant) performance issues to Global_Objects/eval. However, unlike eval, the Function constructor creates functions that execute in the global scope only.
Also functions created with Function don't default to strict mode so it is possible to use the with statement which has been not welcome for the last decade.
The suggested alternative leads us back to
<!DOCTYPE html><!-- index.html --><html><head><title>Giving up on faking implicit imports</title><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1"/></head><body><script type="module">import*aslibAfrom'./libA.js';import*aslibBfrom'./libB.js';consth=Object.assign({},libA,libB);document.querySelector('body').appendChild(app('Test ','this!'));functionapp(first,last){returnh.h1(first,h.em(last));}</script></body></html>
that rollup.js might be perfect.
It would let you work with smaller modules which are less prone to having a large number of exports that are then stitched together at build time - so wildcard imports would be much less problematic. In my judgement rollup.js is probably the most sane bundler solution at this time (even when esbuild is faster; Parcel is way too magical for my taste).
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I will never say to anyone he is a bad programmer,
again, I am very happy to have discovered your library :-)
Your problem could be submited to Andrea Giammarchi from WebReflections.
I am pretty sure he could respond about the possibility of a 'lazy loading'
Regards
1) It may help to organize things into fewer values
2) These type of values are typically managed by an entirely different tool, e.g. Sass (also gorko).
There is a solution do avoid named input (the lazy way), which is not the final word, but maybe an interesting starting point:
In DML.js, we set the export:
Now we import our library as dml and make it accessible in the global scope
I know this is a bad solution for many reasons. But it might be a starting point:
The solution above defines all symbols as global variables, which we wanted to avoid. I just did not find a way to define scoped (e.g. local) variables that way. If we could manage to create scoped variables, this has many advantages:
So, my question is: Does anybody know a way to create local variables or const dynamically in Javascript?
The final solution could be something like this:
Perhaps using 'eval' ?
But as you know it's not recommended.
1.) It is not uncommon for style guides to discourage the use of wildcard imports even when the language supports it. Example:
Wildcard imports should not be used
Also keep in mind that in C/C++
include
occurs at compile-time so there is no runtime cost to dumping a boatload of unused names into the code. In JavaScriptimport
happens at run time so potential for "more work" comes with the potential for undesirable run time consequences.Other than that, for example, Google's style guide with regards to imports.
2.) In your example it looks like you are trying to export functions that are only capable of creating a single type of HTML element
Prior art:
For a while React also had react-dom-factories:
However support was dropped as JSX is the accepted standard among React developers.
Other helper examples: hyperscript-helpers, react-hyperscript.
3.)
Basically strict mode which is the default in ES2015 modules makes that impossible.
However for the time being one can still pull a stunt like this:
I like any kind of dirty tricks, but 'eval' is really nasty. As this may cause serious security issues I would not try to use it. But I´m sure there will be a solution without.
Andrea Giammarchi reminded me, that rollup.js might be perfect. That´s indeed a smart solution!
Great, Andrea is an awesome guy
In fact I have published your TodoList using rollup and it's tree shaking feature :-)
MDN: Function:
Also functions created with
Function
don't default to strict mode so it is possible to use the with statement which has been not welcome for the last decade.The suggested alternative leads us back to
It would let you work with smaller modules which are less prone to having a large number of exports that are then stitched together at build time - so wildcard imports would be much less problematic. In my judgement rollup.js is probably the most sane bundler solution at this time (even when esbuild is faster; Parcel is way too magical for my taste).