Babel cli preset config - ecmascript-6

Due to some certain reason I don't wish to use .babelrc file even though I'm well aware of the fact that I'm supposed to follow the rules. Anyways, for the run time I'm using the following code
require('babel-register')({
babelrc: false,
presets: [
'stage-0',
['env', {
targets: {
node: 'current'
}
}]
],
plugins: [
'transform-async-to-generator',
'syntax-async-functions'
]
});
require('../server/core');
Now I need the same config to be executed from shell. E.g.
babel config --out-dir
Thanks for your help

There is currently no way to pass plugin/preset options via CLI arguments. https://github.com/babel/babel/issues/4161 so if you don't wish to use a .babelrc then there's no easy way to get args in via the CLI command.
Given that, your next best bet would be to use something like gulp-babel to put together your own build pipeline with programmatic arguments like babel-register has.

Related

Gulp require alias

I am looking for a safe way of doing require aliases using gulp.
The idea is similar to what webpack offers with resolve alias.
For example, I put on my source code something like require('#plugin/utils') and it is translated to something of my choice, like require('$/plugins/longer/namespace/utils'). You probably have noticed that it does not match to any actual file path, and that is intentional (they are tiddlywiki files if anyone is interested).
The best thing I found is gulp-replace, but that relies on strings replacements at worst and regular expressions at best.
Ideally I would want something more reliable, something that is AST aware,so I'm sure that I never replace the wrong string (for example, a template string).
I am also using babel, so if there is a babel plugin that I can use I will also be happy about that.
As a last resort I may try to write some babel plugin or a gulp plugin using esprima, but esprima is not up to modern JS standard (doesn't parse object spread) and I would prefer creating another tool.
Thanks in advance
Finally I found a babel module (babel-plugin-module-resolver) that I can integrate with gulp, and with some extra configuration magic with eslint.
So, this is what I added to my gulp pipeline (simplified)
const babelCfg = {
plugins: [[
require.resolve('babel-plugin-module-resolver'),
{
root: [ `${pluginSrc}/**` ],
alias: { '#plugin': `$:/plugins/${pluginNamespace}` },
loglevel: 'silent',
}
]],
};
return gulp
.src(`${pluginSrc}/**/*.js`)
.pipe(babel(babelCfg))
.pipe(gulp.dest(outPath.dist));
That converts all the references to require('#plugin/xxxx') with the proper path.
With some extra configuration you can even make eslint warn you about bad path resolutions.
You need to configure it differently because eslint needs the real path, while the output files needs a special namespace. After installing both eslint-import-resolver-babel-module and eslint-plugin-import this is what you should add to your eslint config to make it work:
plugins:
- import
env:
node: true
browser: true
settings:
import/resolver:
babel-module:
root: ./src/**
alias:
"#plugin": ./src/the/real/path
rules:
import/no-unresolved: [2, { commonjs: true }]

How to pass options to UglifyJS through html-minifier on Windows command line?

HTMLMinifier (html-minifier) (3.5.14) for Node.js (v8.11.1), installed with npm install html-minifier -g, can be run via command line (Windows CMD), e.g. html-minifier --help produces the usage info (excerpts):
Usage: html-minifier [options] [files...]
Options:
-V, --version output the version number
...
--minify-js [value] Minify Javascript in script elements and on* attributes (uses uglify-js)
...
-c --config-file <file> Use config file
--input-dir <dir> Specify an input directory
--output-dir <dir> Specify an output directory
--file-ext <text> Specify an extension to be read, ex: html
-h, --help output usage information
The option --minify-js [value] relies on UglifyJS to "compress" the JavaScript embedded inside the HTML file(s) passed to html-minifier. UglifyJS can remove console.log() function calls (Can uglify-js remove the console.log statements?) from the JavaScript, by enabling the drop_console option (also see pure_funcs).
But --minify-js drop_console=true does not have an effect, nor does something like "uglify:{options:{compress:{drop_console:true}}}" or "compress:{pure_funcs:['console.log']}".
How can such an option be set, ideally via the html-minifier command line (alternatively by config-file, though it just sets "minifyJS": true)?
I was very close.
I started digging through the code (installed in %appdata%\npm\node_modules\html-minifier) to see what happens with the options provided, i.e. adding debug output with console.log(xyz); (using an actual debugger probably would be a better idea).
So, here's my "trace":
option: https://github.com/kangax/html-minifier/blob/gh-pages/cli.js#L118
option handling: https://github.com/kangax/html-minifier/blob/gh-pages/cli.js#L144
argument parsing using [commander][2]
createOptions() https://github.com/kangax/html-minifier/blob/gh-pages/cli.js#L197
options then contains e.g. minifyJS: 'compress:{pure_funcs:[\'console.log\']}',
passed on to minify() https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L806 which immediately runs
processOptions() https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L616
where finally in line https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L667 options.minifyJS is handled, before it's run as var result = UglifyJS.minify(code, minifyJS); in https://github.com/kangax/html-minifier/blob/gh-pages/src/htmlminifier.js#L680.
But there our option string compress:{pure_funcs:['console.log']} gets cleaned because it's not yet an object, resulting in {}.
Or, in a different trial with a different string you may encounter the error Could not parse JSON value '{compress:{pure_funcs:'console.log']}}'
At least it gets that far! But why doesn't it work?
First, it's a good time to revisit the JSON spec: https://www.json.org/index.html
Second, see if the string could be parsed as valid JSON, e.g. with the JSON.parse() demo at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
Third, figure out how to get that string through the CMD as argument (escaping the double quotes).
Finally, make sure the data structure to configure UgliFyJS is correct. That's quite easy, since it's documented: https://github.com/mishoo/UglifyJS2#minify-options-structure
And behold, simply escaping the double quotes with a backslash works for me:
html-minfier ... --minify-js {\"compress\":{\"pure_funcs\":[\"console.log\"]}} ...
and it properly shows up in the options as
...
{ compress:
{ pure_funcs: [ 'console.log' ],
...
For ex. curl can read config from a file, like proxies, etc...
Many programs do so. git, maven, gradle.... No matter how and where you call them, they look for the config you or the system provides: first from the current directory, then from the user home and then the system /etc/...
If no batteries included with these node packages, they can only be used on separate html and js files.

babel-jest with ES6 modules

I'm happily using node 8.6 with the experimental ES6 modules option (--experimental-modules) turned on. This allows me to perfectly write plain ES2015 code for node without the need of babel.
The problem is when I try to create some tests with jest, it fails complaining about a syntax error: "Unexpected token import".
The .babelrc configuration is the following:
{
"env": {
"test": {
"presets": [
["env", {
"targets": {
"node": "8.6"
}
}]
]
}
}
}
My jest.config.js is as follows:
module.exports = {
testMatch: ['/tests/**/*.js', '**/?(*.)test.js'],
}
The error thrown:
/app/tests/integration/controller/data-provider/Credentials/CredentialsList.action.test.js:2
import { Credentials, AdWordsCredentials } from '../../../../../imports/models/data-provider/Credentials.mjs';
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
at Generator.next (<anonymous>)
at Promise (<anonymous>)
Relevant packages:
babel-core#^6.26.0
jest#^21.2.1
babel-jest#^21.2.0
babel-preset-env#^1.6.0
Any help will be appreciated.
Thanks :)
UPDATE: I've tried calling jest without babel, with the following command, without any change: node --experimental-modules node_modules/.bin/jest
Jest has a custom implementation of require to help with mocking. Unfortunately, this makes jest incompatible with node --experimental-modules. Babel is probably the best way to use ES6 modules with jest. See https://github.com/facebook/jest/issues/4842
I was not used jest, and I am not sure if this will solve, but I hope this can help you.
Node still doesn't support all syntax. If you really are looking a faster way to start develop, using source code with all features of Ecmascript2017, you need a module like #kawix/core https://www.npmjs.com/package/#kawix/core
How the README.md says, allows you to use all features including "imports" and "async/await" and also supports typescript, and other good features all without a LOT OF DEPENDENCIES. You can use directly with cli:
> npm install -g #kawix/core
> kwcore /path/to/fullsyntaxtsupport.js
Or if you want inclute programatically, create a file example main.js to import the fully syntax file
var kawix= require("#kawix/core")
kawix.KModule.injectImport()
kawix.KModule.import("/path/to/fullsyntaxtsupport.js").catch(function(e){
console.error("Some error: ",e)
})

How can I turn off ESLint's no-restricted-syntax rule just for ForOfStatement?

I am using ESLint for my ES6 program, with the AirBNB rule-set. For good and adequate reasons, I am using the for...of construction in my code, but ESLint objects to it, issuing a no-restricted-syntax error.
The documentation at http://eslint.org/docs/rules/no-restricted-syntax explains how I can specify in my .eslint file the set of syntax-tree nodes that it objects to: for example, if all I dislike is the with statement, I can use:
"no-restricted-syntax": ["warn", "WithStatement"]
But I don't want to specify a whole set of unapproved constructions, I just want to say that I consider one such construction OK. Something conceptually similar to
ESlint.rules['no-restricted-syntax'].removeEntry('ForOfStatement');
Is there a way to do this in the ESLint file? Or, failing that, is there at least a way to get it to tell me what its current no-restricted-syntax configuration is, so I can manually remove ForOfStatement from it?
Check existing config
Based on the current master branch, eslint-config-airbnb currently disables four syntax forms:
ForInStatement
ForOfStatement
LabeledStatement
WithStatement
You can verify this or see if there are any differences by using ESLint's --print-config CLI flag:
$ eslint --print-config file.js
ESLint will print out the config it would use to lint file.js, and you can find the config for the no-restricted-syntax rule there.
Override no-restricted-syntax
If you want to override Airbnb's preset, you can do so in the rules section of your .eslintrc.json file:
{
"rules": {
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"]
}
}
There's no way to configure the rule to use the no-restricted-syntax config inherited from Airbnb's preset excepting only a single syntax form.
Add the below lines of code to restrict this error in your application in .eslintrc.js file
module.exports = {
extends: ['airbnb-base', 'plugin:prettier/recommended'],
plugins: ['no-only-tests'],
rules: {
'no-only-tests/no-only-tests': 2,
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"]
},
};

How to override ASP.NET Core configuration array settings using environment variables

TL;DR
In an ASP.NET Core app, I have an appsettings.json config file which uses a JSON array to configure a collection of settings.
How do I override a setting of one of the array objects using environment variables?
Background
I'm using Serilog in an ASP.NET Core application and using the Serilog.Settings.Configuration, to allow it to be configured using appsettings.json.
The configuration is like this:
{
"Serilog": {
"Using": ["Serilog.Sinks.Literate"],
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "File", "Args": { "path": "%TEMP%\\Logs\\serilog-configuration-sample.txt" } }
],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
"Properties": {
"Application": "Sample"
}
}
}
When deployed, I want to override some of the settings, e.g. the MinimumLevel, and the path to the log file. My preferred option is to do this via environment variables as I'm deploying to an Azure App Service, so I'll use the App settings through the Azure management portal (these are realised as environment variables).
I can easily set the MinimumLevel by adding an environment variable with the name: Serilog:MinimumLevel and the application name Serilog:Properties:Application.
What is the format for specifying a setting with an array?
After looking at the configuration in the debugger I found the answer.
Serilog__WriteTo__0__Args__path (All platforms)
Serilog:WriteTo:0:Args:path (Windows)
Serilog--WriteTo--0--Args--path (sourced From Azure Key Vault)
Note: The Configuration in ASP.NET Core documentation now covers this.
So I need to use the array index (zero-based) as if it were a name.
Here is the screenshot of the debugger, also (thanks to Victor Hurdugaci in the comments), the unit tests are a good place to look for examples.
I know this is an old thread, but the most relevant one I could find for my question:
My appsettings file has a setting like this:
{
"Settings": {
"UserList": [ "devuser1", "devuser2" ]
}
}
I want to put this into a k8s secret(because the list between environments changes), so I set the key-value pair as follows:
Settings__UserList: '[ "devuser1", "devuser2" ]'
But that doesn't seem to be working. I just realized I have yet to try setting it without the brackets:
Settings__UserList: "devuser1", "devuser2"
If that doesn't work, am I going to have to setup my secret like this to really get it to work?
Settings__UserList__0: "devuser1"
Settings__UserList__1: "devuser2"
I didn't see anything in the documentation that covered this type of array value.