What are some ways to override local babelrc configurations? - babeljs

I have a .babelrc file with certain configurations that I want to override in select situations (not environment-related). Unfortunately, babel documentation is not very clear on order of precedence for configs that are passed(i.e., .babelrc, babel-loader, babel.transform, babel-cli, etc).
Also, is it possible to pass query-parameters or options to babel presets such as es2015 when using babel-cli?

Related

Best way to make #types packages visible in an nx workspace

Background
I'm trying to remove resize-observer-polyfill from an nx workspace that I'm working on because it's natively supported in the browsers that we are targeting. Once I removed the polyfill, I needed to add #types/resize-observer-browser because the workspace currently uses typescript#4.0.5 and my understanding is that TypeScript does not have a "native" type for ResizeObserver until v4.2 which I'd love to update to, but can't atm.
Problem
In order to make TypeScript happy, it seems like I have to go in and manually add "resize-observer-browser" to individual tsconfig compilerOptions.types entries. This didn't seem that bad to me at first. I just updated the tsconfig.lib.json file of the libraries that happened to utilize ResizeObserver. However, I soon realized I needed to also add it to the tsconfig.spec.json of the libraries so that the unit tests could run, and then I also needed to add it to the tsconfig.app.json of any applications that happened to import those libraries.
Question
Is there an easier way in an nx workspace to handle this sort of problem?
I think that I could remove the default types overrides in each of the tsconfig files, since that would let TypeScript just utilize everything that exists under node_modules/#types when compiling. I didn't want to take that path since I assume there is a good reason for the default nx library/app generators to add the types override (I assume it's to force you to be explicit and not accidentally get away with accidental imports of test code from business logic).
The docs seem to recommend against this for #types packages, but /// <reference types="..." /> (e.g. /// <reference types="resize-observer-browser" />) can be also be used to include types, and might be easier to manage if the type is only used in a few places.
Docs: https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-

Using rollup in combination with babel and commonjs plugins doesn't resolve all modules

I'm using rollup with the Babel and CommonJS plugins, like this:
const inputOptions = {
input: "...",
plugins: [
resolve(),
babel({
exclude: "node_modules/**",
externalHelpers: true,
include: "**/components/**/*.js",
}),
commonjs(),
],
};
But what happens is that modules referenced from components don't seem to be recognized by the CommonJS plugin, they end up as plain require(...) statements in the output (just like the source input) where of course they cannot be resolved. Modules imported (also through require() statements) by modules outside the components directory get picked up properly and included in the bundle.
I have tried moving the babel plugin up (before the resolve plugin), but this had no effect. I also tried moving it down, but then Rollup chokes on the JSX in the components.
I also tried removing the include option, so that all files go through Babel and then the result is that no modules get picked up besides the entry point, so it really seems like the Babel and CommonJS plugins aren't playing along nicely, though I can hardly imagine I'm the only one with a setup like this. Am I missing something?
Update: One other thing that I notice is that the files for which the requires() aren't recognized, aren't properly exported either. Instead, for each component that fails, I see this in the output bundle:
module.exports = ComponentName;
var componentName = /*#__PURE__*/Object.freeze({
});
The module.exports line comes from the source, but that Object.freeze() statement is something rollup adds, maybe because it doesn't see any default export?
To add a bit of extra confusion: There's actually one component that gets transpiled by Babel and for which the module resolution works and the requires() get replaced like you'd expect, but all the components included from that component in turn have the defective behavior described above.
Update 2: I have been able to reproduce the problem in a minimal example as well, and it allowed me to pinpoint why things worked for the one component, but not by the components it includes in turn. Apparently, functional React components work properly, but class components trigger the issue. So now my hypothesis is that the Babel transform for ES6 classes somehow confuses the CommonJS plugin.
Update 3: As I believe this is a bug, I have also created issues with the relevant projects: https://github.com/rollup/rollup-plugin-babel/issues/297 and https://github.com/rollup/rollup-plugin-commonjs/issues/369

reference.conf vs application.conf files in Akka

I am new in Akka and I am trying to understand the difference between the reference.conf and application.conf files?
What is the proper way to use them? What kind of variables should I have in each file?
reference.conf is a file for library developers. All properties required by the library should be mentioned there and filled with reasonable default values when possible.
application.conf is a file for application developers. A developer can set values for properties used by libraries in case they are not the same as defaults.
Also he/she can declare his own properties and refer them from the code.
When ConfigFactory.load is called all reference.conf and application.conf files are merged into one configuration and application.conf has higher precedence.

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.

What is a babel preset? What does stage mean?

What is a babel preset and why do I need it?
There are several questions about specific babel presets but none explain the need for it (e.g. what's the difference between babel-preset-stage-0, babel-preset-stage-1 etc)
Also the babel docs do not explain the necessity: https://babeljs.io/docs/plugins/preset-latest/
Babel Presets:
Technically presets are collections of plugins (as Quentin says)
The usecase is the support of particular language features.
Read this excellent post: https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets
A preset is a set of plugins used to support particular language features.
The two presets Babel uses by default:
es2015: Adds support for ES2015 (or ES6) JavaScript
react: Adds support for JSX
... ES2015 is just another name used for ES6 ... [1]
Preset stages:
Stages represent the status of experimental features. Pre stage-3 should be used with caution.
... Beyond ES7, proposed JavaScript features can exist in various stages: [1]
stage-0 - Strawman: just an idea, possible Babel plugin.
stage-1 - Proposal: this is worth working on.
stage-2 - Draft: initial spec.
stage-3 - Candidate: complete spec and initial browser implementations.
stage-4 - Finished: will be added to the next yearly release. [2]
[1] https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets
[2] https://babeljs.io/docs/plugins/
From the docs:
Presets are sharable .babelrc configs or simply an array of babel plugins.
Babel is a tool for transforming JS.
A plugin a some code for performing a particular transformation.
You have to specify which plugins you want to use with a config.
A preset is just a prewritten config you can use to get common sets of transforms.