babel-preset-env runtime version check - babeljs

babel-preset-env allows to automatically determine the needed polyfills and transformation but how does it check at runtime if the target versions specified at compile time are really available.
Let say I target safari 10 using
"targets": {
"safari": 10
}
but the code is run on an older version of safari.
How does babel-preset-env recognize this or what are the typical ways to deal with this common problem?

babel-preset-env does not carry out any runtime checks. It enables only the transforms that are required for your specified environment. You're effectively setting your minimum supported environment, and opting out of any transforms that would be required to support lower versions.
For example, if all of the browser versions specified in my config supported ES2015 classes, Babel would not transform classes into an ES5-supported form, since it's not necessary to do so!

Related

Specifying build requirements as a file in a setuptools pyproject.toml

Setuptools supports dynamic metadata for project properties in pyproject.toml, and as a PEP517 backend, it also has the option to specify build requirements by implementing get_requires_for_build_wheel. But I cannot figure out whether it uses the chance and does implement a way to specify build requirements based on configuration options, and if so, how to specify it in the pyproject.toml.
I naively tried
[build-system]
requires = {file = "requirements-build.txt"}
but that understandably leads to pip complaining “This package has an invalid build-system.requires key in pyproject.toml. It is not a list of strings.” And adding
[project]
dynamic = ["build-system.requires"]
also doesn't work, because the possible options of dynamic are explicitly enumerated. I would be somewhat surprised if there wasn't an option for this, given that all the infrastructure elements are available, but how do I specify it?
As far as I know, it is not possible.
If it is really necessary for your use case, and you think it is worth the cost, maybe it is possible to add some dynamic behavior here by (mis-)using the "in-tree build backends" feature.

`#babel/runtime` and `#babel/plugin-transform-runtime` versions

Are #babel/runtime and #babel/plugin-transform-runtime supposed to be on the same version (e.g. both 7.2.0 exactly)? Or can I (as a library author) specify #babel/runtime dependency as ^7.0.0, whilst having the latest #babel/plugin-transform-runtime?
I'm aware that during the beta versions of Babel 7, there was a breaking change in beta.56 (see https://stackoverflow.com/a/51686837/2148762), but I'm guessing this should no longer be the case with the current stable version?
The reason I ask this is I'd ideally want the helpers from #babel/runtime to be shared across different packages, and to me leaving the version range open seems like a good idea. But at the same time, I'm not sure how low I should go (^7.0.0 or ^7.2.0), and whether there's an implicit contract between #babel/runtime and #babel/plugin-transform-runtime with regards to version numbers.
By default, #babel/plugin-transform-runtime is only allowed to output references to #babel/runtime that work on ^7.0.0 because it does not know what version you'd otherwise want to use, and doing anything else would cause lots of issues for users. This means that what you want to do is safe. The downside of this is that, if we add new helpers moving forward, your code would not be able to take advantage of the #babel/runtime version of them (because you might still be using a #babel/runtime version that doesn't have them.
Users can specify the version in the arguments for the transform, if you want to specifically make use of helpers that may have been added to Babel since 7.0.0, e.g.
{
"plugins": [
["#babel/plugin-transform-runtime", { version: "^7.2.0" }],
]
}
would then require you to have "#babel/runtime": "^7.2.0" in your package.json.
For instance, since support for the newer decorators proposal didn't land until Babel 7.1.5, if you use transform-runtime and non-legacy decorators, the decorators helper will still be inserted into every file where you use decorators, instead of importing it from #babel/runtime. To get the shared helper, you need to specify version: "^7.1.5" in your options for transform-runtime.
Can I (as a library author) specify #babel/runtime dependency as ^7.0.0, whilst having the latest #babel/plugin-transform-runtime?
Yes, this is safe.
I'm guessing this should no longer be the case with the current stable version?
Correct, that issue was because people failed to take the beta versioning into account.

babel-polyfill vs babel-plugins

I am a bit lost in the Babel options / config. I want to use recent js features and compile (with webpack) to browser code.
What is the difference between babel-polyfill and babel plugins with babel-preset-env?
Are they intended to work together?
Answer from this article:
The distinction between a babel transform plugin versus
babel-polyfill / babel-runtime is whether or not you can
reimplement the feature today, in ES5. For example, Array.from can
be rewritten in ES5 but there is nothing I can write in ES5 to add
arrow function syntax to JavaScript. Therefore, there is a transform
for arrow functions but none for Array.from. It will have to be
provided by a separate polyfill like babel-polyfill, or
babel-runtime.
As a side note, here is my current understanding of the babel eco-system.
Babel is a javascript compiler: it parses, transforms and outputs transformed code.
babel-core
This is the parse and output parts.
It does not do any transformation.
It can be used from the command line or from a bundler (webpack, rollup and co.)
babel-polyfill / babel-runtime
Acts on the transform part by prepending es5 javascript to your code to emulate es2015+ functions (like Object.assign).
Relies on Regenerator (to polyfill generators) and core-js (to polyfill all the rest).
Difference between babel-polyfill and babel-runtime: the former defines global methods (and pollutes the global scope) whereas the latter transforms your code to make the same functionnality available as explained in this answer.
babel plugins
Transform the code you wrote.
babel syntax / transform plugins: parse and transform es2015+ syntax (like arrow functions) to convert it to es5.
babel-plugins-stage-x (from stage-0 to stage-4): transform future javascript syntax which is not in the JS specs yet, starting at stage-0 (just an idea) down to stage-4 (will land in the babel-plugins soon).
babel-preset-env
babel-preset-env determines the Babel plugins and polyfills needed for a specific environment.
With no configuration, it will load all the plugins (including es2015, es2016 and es2017) required to transpile es2015+ to es5.
With a target option, it loads only the plugins required to run on a specific target.
With the builtIn option, it uses only the babel-polyfill which are not built-in the target.
Does not work with babel-transform-runtime yet (as of nov. 2017). (see this issue)
babel-preset-env is a Babel preset meant to automatically set up babel plugins and include the necessary babel polyfills based on a set of target environments checked against a feature compatibility table.
In order to make a fully working ES2015+ environment run on a non-ES2015+ client, simple code transpilation is sometimes not enough:
ES generators are enabled using regenerator library (provided by babel-polyfill)
Missing ES2015+ methods (like Promise, Map, Object.assign...) are polyfilled with core-js (provided by babel-polyfill, too)
Any other transpilable feature is generated by standard babel plugins, often used trough pre-configured babel-presets
So, back to your question, it's babel-preset-env that makes use of babel-polyfill and babel plugins.

More than one V4L-DVB driver on the same host machine

I have a question related to V4L-DVB drivers. Following the
Building/Compiling the Latest V4L-DVB Source Code link, there are 3 ways to
compile. I am curious about the last approach (More "Manually
Intensive" Approach). It allows me to choose the components that I
wish to build and install using the "make menuconfig". Some of these components (i.e. "CONFIG_MEDIA_ATTACH") are used in pre-processor directives that define a function in one shape if defined, and a function in another if not defined (i.e.
dvb_attach, dvb_detach) in the resulting modules (i.e. dvb_core.ko)
that will be loaded by most of the DVB drivers. What happens if there are two
drivers (*.ko modules) on the same host machine, one that needs dvb_core.ko with
CONFIG_MEDIA_ATTACH defined and another that needs dvb_core.ko with
CONFIG_MEDIA_ATTACH undefined, is there a clean way to handle this?
What is also not clear to me is: Since the V4L compilation environment seems very customizable (by setting the .config file), if I develop a driver using V4L-DVB structures, there is a big chance that it has conflicts with other drivers since each driver has its own custom settings. Is my understanding correct?
Thanks!
Dave

Supporting multiple versions of Eclipse

I have an Eclipse plugin and I am aiming for 3.1 or 3.2 as a minimum version to support. The problem is that some of my code only works in version 3.5 and above (see my other question: Is there an alternative to CaretListener in Eclipse?).
Now that I have code that works in the older versions and different code that works in the newer versions, is there a way that I can call the newer code only if my plugin is running in version 3.5 or above and then revert to the old code if running anything older?
As a test, I've created two plugins that have the same class within it (just doing slightly different things). I have marked the org.eclipse.ui dependency as a minimum of 3.5 in one plugin and 3.1 as a minimum in the other but I can't get the one that relies on 3.5 to be ignored in older versions...
Can anyone help?
Thanks,
Alan
You could use org.eclipse.core.runtime.Platform to get the org.eclipse.ui Bundle and check the version.
Version ui = Platform.getBundle("org.eclipse.ui").getVersion();
// then do something with that
Register MyListener if >=3.5, and OldMyListener otherwise.
EDIT:
Right, the above is only good for capturing differences in runtime behaviour.
Eclipse supports a couple of tricks for only loading some classes.
The easiest from a development point of view is the trick that #ShiDoiSi mentioned.
Bundle myBundle = org.osgi.framework.FrameworkUtil.getBundle(this.class);
Version ui = Platform.getBundle("org.eclipse.ui").getVersion();
Version cutOff = new Version(3,5,0);
final Executable processListener;
if (ui.compareTo(cutOff)<0) {
Class pc = myBundle.loadClass("my.pkg.OldListenerProcess");
processListener = (Executable) pc.newInstance();
} else {
Class pc = myBundle.loadClass("my.pkg.ListenerProcess");
processListener = (Executable) pc.newInstance();
}
processListener.execute(targetObject);
Another option that uses more of the eclipse framework would be defining your own extension point so that contributions from other bundles can decide which version to use. Basically it's the same pattern as above, except the version checking is done by the dependency ranges on the plugin the contributes the Executable to run. Depend on org.eclipse.ui [0.0.0,3.5.0) for the old way, and simply specifying org.eclipse.ui 3.5.0 (that's an open ended range on 3.5.0) for the current way. Then you can read your extension and instantiate the class provided.
If you were creating extra plugins for this (a little heavy weight for the 2 differences) you could define a command in your main plugin, and have the extra plugins provide the equivalent handler. The plugins would still have to have dependency ranges so that only one would load for the <3.5 or >=3.5 case. Then using the command API you could execute the command (and the correct handler would run).
ICommandService cmdS
= (ICommandService) workbenchWindow.getService(ICommandService.class);
Command process = cmdS.getCommand("my.pkg.ListenerProcess");
ParameterizedCommand cmd = new ParameterizedCommand(process, null);
IHandlerService handlerS
= (IHandlerService) workbenchWindow.getService(IHandlerService.class);
IEvaluationContext ctx = handlerS.createContextSnapshot(false);
ctx.addVariable("toAddListener", targetObject);
handlerS.executeCommandInContext(cmd, null, ctx);
Then your implementation of handler would use HandlerUtil.getVariable(event, "toAddListener") to extract the object you need from the ExecutionEvent.
It sounds to me that you should be supplying two plugins, one supporting version 3.1 to "just below" 3.5, and the other one from 3.5 upwards. So you don't really get to choose, it's basically the Eclipse plugin layer choosing the right one based on your version ranges.
Or if you provide just the compiled class files, then of course you could load the required class dynamically based on testing the version of the running Eclipse.