Disable promise transpilation using babel-preset-env? - javascript

I'm using babel-preset-env (Babel 6) and I can't find out how to disable the "promise" transpilation.
I tried to use:
{
"presets": [
[
"env",
{
"exclude": ["transform-async-to-generator", "es6.promise"]
}
]
],
"plugins": [
"transform-object-rest-spread",
"transform-class-properties",
[
"fast-async",
{
"spec": true,
"compiler": { "promises": true, "generators": false }
}
]
]
}
and, while it doesn't throws any errors (unlike it happens when an invalid option is passed), it still transpiles promises into runtimeGenerator functions.
How can I make so that babel-preset-env will transpile everything but preserve promises?

Okay, now with the actual .babelrc and mention of fast-async and so on... A .babelrc like this seems to be enough to use fast-async instead of regenerator-runtime etc.
{
"presets": [
[
"env",
{
"exclude": ["babel-plugin-transform-async-to-generator", "babel-plugin-transform-regenerator"]
}
]
],
"plugins": [
[
"fast-async",
{
"spec": true,
"compiler": { "promises": true, "generators": false }
}
]
]
}

Promises shouldn't be transpiled to anything using babel-preset-env. async/await is, though. You can see here in the Babel playground that
const x = () => new Promise((res) => res('hi'));
const y = async () => {
const z = await x();
};
gets transpiled to
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var x = function x() {
return new Promise(function (res) {
return res('hi');
});
};
var y = function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var z;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return x();
case 2:
z = _context.sent;
case 3:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));
return function y() {
return _ref.apply(this, arguments);
};
}();
using the default env settings. If you change the env string to, say, chrome>60 (or, in fact, interestingly >4%!), the code is passed through as-is, as Chrome > 60 supports async/await and arrow functions natively.

Related

Is there a way to write ts modules as native code in the JavaScript data file when compiling?

I want to divide an app in a TypeScript development environment into function files - so that each file contains only one function.
I would like to realise this with TS modules. In the compiled JavaScript file, however, these modules should not get imported at runtime, but compiled as native code.
For example, from this app.ts
type ArbitraryAttribute = any //can refer to any value valid at runtime
declare interface App {
get? (key: string): ArbitraryAttribute | void,
set? (key: string, val: ArbitraryAttribute): void,
helper?: AppHelper,
}
declare interface AppHelper {
deepGetter? (key: string): ArbitraryAttribute | void,
deepSetter? (key: string, val: ArbitraryAttribute): void,
}
import { get } from "./get";
import { set } from "./set";
import { helper } from "./helper/index";
const app:App = {
get,
set,
helper,
}
this app.js is to be generated:
var app = {
get: function (key) {
if (app.helper && app.helper.deepGetter) {
return app.helper.deepGetter(key);
};
},
set: function (key, val) {
if (app.helper && app.helper.deepSetter) {
app.helper.deepSetter(key, val);
};
},
helper: {
deepGetter: function (key) {
// get anything
},
deepSetter: function (key, val) {
// set anything
},
},
};
Neither in the TypeScript configuration nor in webpack have I found a solution for this.
This should be feasible, right? Does anyone know a solution or a library that solves this problem?
As #Dimava mentions, via tsconfig there is the possibility to merge a number of typescript files into a single js file, but the result for my aproach is really messy. The previosly postet js file will look like this:
System.register("get", [], function (exports_1, context_1) {
"use strict";
var get;
var __moduleName = context_1 && context_1.id;
return {
setters: [],
execute: function () {
exports_1("get", get = function (key) {
if (app.helper && app.helper.deepGetter) {
return app.helper.deepGetter(key);
}
;
});
}
};
});
System.register("set", [], function (exports_2, context_2) {
"use strict";
var set;
var __moduleName = context_2 && context_2.id;
return {
setters: [],
execute: function () {
exports_2("set", set = function (key, val) {
if (app.helper && app.helper.deepSetter) {
return app.helper.deepSetter(key, val);
}
});
}
};
});
System.register("helper/deepGetter", [], function (exports_3, context_3) {
"use strict";
var deepGetter;
var __moduleName = context_3 && context_3.id;
return {
setters: [],
execute: function () {
exports_3("deepGetter", deepGetter = function (key) {
// get anything
});
}
};
});
System.register("helper/deepSetter", [], function (exports_4, context_4) {
"use strict";
var deepSetter;
var __moduleName = context_4 && context_4.id;
return {
setters: [],
execute: function () {
exports_4("deepSetter", deepSetter = function (key, val) {
// set anything
});
}
};
});
System.register("helper/index", ["helper/deepGetter", "helper/deepSetter"], function (exports_5, context_5) {
"use strict";
var deepGetter_1, deepSetter_1, helper;
var __moduleName = context_5 && context_5.id;
return {
setters: [
function (deepGetter_1_1) {
deepGetter_1 = deepGetter_1_1;
},
function (deepSetter_1_1) {
deepSetter_1 = deepSetter_1_1;
}
],
execute: function () {
exports_5("helper", helper = {
deepGetter: deepGetter_1.deepGetter,
deepSetter: deepSetter_1.deepSetter,
});
}
};
});
System.register("index", ["get", "set", "helper/index"], function (exports_6, context_6) {
"use strict";
var get_1, set_1, index_1, app;
var __moduleName = context_6 && context_6.id;
return {
setters: [
function (get_1_1) {
get_1 = get_1_1;
},
function (set_1_1) {
set_1 = set_1_1;
},
function (index_1_1) {
index_1 = index_1_1;
}
],
execute: function () {
app = {
get: get_1.get,
set: set_1.set,
helper: index_1.helper,
};
}
};
});
I haven't get it working for "--module es2015 --moduleResolution classic",
only for for "--module system --moduleResolution node".
And the file weighs almost six and a half times as much!

Unable to merge mochaweasome reports

I have the below config in my test runner and trying to merge all the mochaweasome.html file as single mocha file.
Runner.js
async function testRunner(fixture) {
return cypress.run({
config: {
"reporter": "mochawesome",
"reporterOptions": {
"reportFilename": "sample" + `${fixture}`,
"reportDir":"./cypress/reports/",
"charts": true,
"overwrite": false,
"html": true,
"json": true
}
},
env: {
testcaseID: `${fixture}`,
},
spec: './cypress/integration/' + `${param.getSpec()}` + ".spec.js",
});
}
TestRunner.js:
const testRunner = require("./Runner.js");
const options = {
files: [
'./cypress/reports/*.html',
],
}
async function generateReport(options) {
return merge(options).then(report => marge.create(report, options))
}
async function runner(dataSet) {
for (let i = 0; i < dataSet.length; i += 1) {
await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](10000);
try {
await testRunner(dataSet[i]).then((result) => {
console.log(JSON.stringify(result, null, " "));
generateReport(options);
if (result.runs[0].stats.failures === 1) {
retry.push(result.config.env.testcaseID);
}
},
error => {
generateReport(options);
console.error(error);
process.exit(1);
});
}
catch (err) {
process.exit(1);
}
}
}
Test Report is created like below:
But It's not merged as single report as per the code.
Can someone help me to fix this. I just want single mochaweasome_final report which contains all the result in a single .html file.
Updated:
Used cypress-mochawesome-reporter and followed all the steps. But still the report is not merged. How can I merge all the 5 html files into single one.
Output:
First, you have to install mocha reporter using npm i cypress-mochawesome-reporter command.
and then you have to put this import in support/index.js
import 'cypress-mochawesome-reporter/register';
And import this line in plugin/index.js
module.exports = (on, config) => {
require('cypress-mochawesome-reporter/plugin')(on);
};
And then in your cypress.json file
"reporter": "cypress-mochawesome-reporter",
"reporterOptions": {
"reportDir": "cypress/reports",
"charts": true,
"overwrite": false,
"html": false,
"json": true,
"reportPageTitle": "My Test Suite",
"embeddedScreenshots": true,
"inlineAssets": true
Reference: https://www.npmjs.com/package/cypress-mochawesome-reporter

Tree shaking not working with webpack if class contains more than one function

I'm using Webpack for a project (and I'm starting to regret that) and tree shaking is not working.
I created a simple test library which I bundle using Rollup since Webpack cannot generate esm libraries (see here for more info about that: https://github.com/webpack/webpack/issues/2933).
Here is the content of my library (which uses Typescript):
export class Test1 {
addOne(x: number) {
console.log('addOne');
return x + 1;
}
}
export class Test2 {
addTwo(x: number) {
console.log('addTwo');
return x + 2;
}
}
Once I bundle it with Rollup, I get this:
var n = function () {
function n() {}
return n.prototype.addOne = function (n) {
return console.log("addOne"), n + 1
}, n
}(),
o = function () {
function n() {}
return n.prototype.addTwo = function (n) {
return console.log("addTwo"), n + 2
}, n
}();
export {
n as Test1, o as Test2
};
Then, I use webpack to bundle my test app that is using this library. Here is the code of the app:
'use strict';
import { Test1 } from './test.esm';
const f = new Test1();
console.log(f.addOne(1));
Once I look at the generated bundle, the Test2 code is tree shaken and does not appear in the bundle.
So far, so good.
If then I add a new function to my Test2 class, like this:
export class Test1 {
addOne(x: number) {
console.log('addOne');
return x + 1;
}
}
export class Test2 {
addTwo(x: number) {
console.log('addTwo');
return x + 2;
}
addThree(x: number) {
console.log('addThree');
return x + 3;
}
}
I get the following output from Rollup:
var o = function () {
function o() {}
return o.prototype.addOne = function (o) {
return console.log("addOne"), o + 1
}, o
}(),
n = function () {
function o() {}
return o.prototype.addTwo = function (o) {
return console.log("addTwo"), o + 2
}, o.prototype.addThree = function (o) {
return console.log("addThree"), o + 3
}, o
}();
export {
o as Test1, n as Test2
};
If then I generate my app bundle with webpack and this new library, without changing anything to the code of the app using the lib, the content of Test2 is added to the output.
What am I doing wrong here?
I'm using webpack 5.12.3.
My webpack config is:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
});
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
resolve: {
fallback: {
'fs': false,
}
},
entry: {
'sample-face': './src/sample-face.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{ from: 'src/index.html', to: path.resolve(__dirname, 'dist') },
{ from: 'src/sample-face.html', to: path.resolve(__dirname, 'dist') },
{ from: 'src/assets', to: path.resolve(__dirname, 'dist/assets') },
]
})
]
};

Jest encountered an unexpected token: implementing try/catch

I'm getting the following error:
Jest encountered an unexpected token ....
} catch {
^
I'm assuming that I need babel to transform the files that i'm importing but I don't understand how jest/babel are wired up together. How do I get it to transform my imported file so I can have try/catch.
I have the following code:
babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
package.json
{
"name": "tests",
"scripts": {
"test": "jest"
},
"author": "jonny-b",
"dependencies": {
"jest": "^24.8.0",
"ruby-script": "^1.0.3"
}
}
index.js
class Collection extends Array {
constructor(array) {
super(array.length);
Object.assign(this, array);
}
//....
drill(...indices) {
if (this[indices] === null) return null;
if (indices.length === 1) return this[indices];
let indexes = indices.splice(indices[0]);
try {
let collection = new Collection(this[indices[0]]);
return collection.drill(...indexes);
} catch {
throw `${typeof (this[indices[0]])}`
}
}
}
script.test.js
let Collection = require('<path to file>/index.js');
describe('ruby-script', () => {
it('should error if called on a non collection return value', () => {
let collection = new Collection([1, [2, [3, [4, [5, [6, [7]]]]]]]);
expect(collection.dig(1)).toEqual(true)
})
}

node.js object extended with a mixin can't find function after instantiation

I've managed to get a fairly complex setup (though that's a question for Code Review) for my mixins that looks like this:
TooManyCaps.js
module.exports = {
labelCopyCaps: () => {
if (this.release.tracks.length > 1) {
if (_this._notEnoughLowercase(this.release.title)) {
this._recordError(release, 'LABELCOPYCAPS');
} else {
this.release.tracks.some( (track) => {
if (this._lowerCaseCount(track.label_copy)) {
this._recordError(release, 'LABELCOPYCAPS');
return true;
}
});
}
}
},
_notEnoughLowercase: (str) => {
if ((str.match(/[a-zA-Z]/g)||[]).length > 3
&& str.length - str.replace(/[a-z]/g, '').length) {
return true;
}
return false;
}
};
I then have an Object that would use this as a mixin:
Rule.js
class Rule {
constructor(release) {
this.release = release;
this.errors = [];
}
_recordError(error, options) {
this.errors.push({
release_id: this.release.id,
rule: error,
options: options,
});
}
}
module.exports = Rule;
i then have an index page that joins them together
index.js
const TooManyCaps = require('./TooManyCaps');
const Rule = require('./Rule');
Object.assign(Rule.prototype, [TooManyCaps]);
module.exports = Rule;
And then my main start of the program that does some instantiating of things:
'use strict';
const RuleValidator = require('./job/validation/RuleValidatorMixin');
const Rule = require('./job/validation/rulesmixins/rules/index');
// some logic that's a loop
arr.forEach((value) => {
new RuleValidator(new Rule(value)).validate();
}
and within validate() I have:
validate() {
console.log('VALIDATE');
this.rule.labelCopyCaps();
// console.log(this.rule);
}
But then when I run this, I get:
this.rule.labelCopyCaps is not a function
So where have i gone wrong?
Object.assign does not take an array:
Object.assign(Rule.prototype, [TooManyCaps]);
// ^ ^
should be just
Object.assign(Rule.prototype, TooManyCaps);

Categories