Avoid making .babelrc file to use for testing with Jest - babeljs

I realize that it is recommended to make a .babelrc file to run tests with Jest according to their docs. But is there any way I could load the babelrc config programmatically and therefore not have to create this file for every React project that I have? Also, I realize I could put something in my package.json file, but I don't want to have to do that either.

You can take advantage of Jest's scriptPreprocessor config setting. I created a file that looked like this and it worked:
const babel = require('babel-core')
const jestPreset = require('babel-preset-jest')
module.exports = {
process: function (src) {
const transformCfg = {
presets: ['es2015', 'react', 'stage-0', jestPreset],
retainLines: true
}
return babel.transform(src, transformCfg).code
}
}

Related

Visual Studio Code snippet dynamic import path

I'm trying to create a TypeScript snippet in Visual Studio Code which includes a bunch of import statements, but I want the path to be set dynamically depending on which directory you use the snippet.
For example, I have a snippet like this:
import { MyComponent } from "../../ui/components";
import { isString } from "../../../../utils/string";
export const Foo = (props) => {
const isStr = isString(props.foo);
/* ...More code... */
return <MyComponent></MyComponent>;
};
How can I make sure that the import paths are set relative to the direcotry I execute the snippet? If this is not possible, are there any other ways you would recommend for achieving this?
Yes, you could. VScode has provided some built-in variables to get relative and full path of your working file.
The structure of my demo project looks like this:
├── index.html
├── style.css
└── test
└── test.ts
And my import path snippet for typescript is:
{
// Place your snippets for typescript here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
"Import path": {
"prefix": "impo",
"body": [
"import { $1 } from \"${2:$RELATIVE_FILEPATH}\";",
],
"description": "Import path depending on relative file path"
}
}
When I type impo in test/test.ts, the snippet expands like this:
If $RELATIVE_FILEPATH is not what you want, you can feel free to change to other variables listed in the documentation.

Import geojson in NextJS

I'm trying to import a GeoJSON file on NextJS but it says:
Module parse failed: Unexpected token (2:8)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
It worked fine when the project was in ReactJS with create-react-app but now that we migrate to NextJS it doesn't.
Maybe I need to configure some loaders on next.config.js but I don't know how to do it
Here is my next.config.js:
const withCSS = require("#zeit/next-css")
const withLess = require('#zeit/next-less');
const withImages = require('next-images')
module.exports = withCSS(withLess({
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["#svgr/webpack"]
});
return config;
},
lessLoaderOptions: {
javascriptEnabled: true,
},
}));
Can someone help me achieve this?
Okay guys, I managed to do it!
I will try to explain what I wanted to accomplish, what was happening and what do I did.
I wanted to load a geojson data from a file into google maps api to load some layers, so I wanted to use it on map.data.loadGeoJson(imported_file.geojson)
First, I needed to make Nextjs load my file from the source so I installed json-loader
npm i --save-dev json-loader
And then added it to next.config.js
const withCSS = require("#zeit/next-css")
const withLess = require('#zeit/next-less');
const withImages = require('next-images')
module.exports = withCSS(withLess({
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["#svgr/webpack"]
});
config.module.rules.push({
test: /\.geojson$/,
use: ["json-loader"]
});
return config;
},
lessLoaderOptions: {
javascriptEnabled: true,
},
}));
And then, no more error message importing the geojson file!
But now, another problem. The layers didn't load! So I read Google Maps API and tried another method to load the geojson.
map.data.addGeoJson(imported_file.geojson)
And it worked! Hope it can help who is in trouble.

Use babel transform with create-react-app

I am working on a javaScript / react playground (something like very simple codesandbox.io) and I'm trying to figure out how to transpile the code. I was thinking of using Babel transform but the app itself is built using create-react-app so I do not have access to Babel. My question is, if I do something like the following and install Babel, will it also override how create-rect-app currently transpiles the code for the app?
// transpile.js
const babelOptions = {
presets: [ "react", ["es2015", { "modules": false }]]
}
export default function preprocess(str) {
const { code } = Babel.transform(str, babelOptions);
return code;
}
EDIT:
I've since learned that I can use Babel standalone for exactly this use case! Now it's just to figure out how to configure it. I would still appreciate help but if I find a solution first I will post for others :)
Ok so I have figured this out but it is not straight forward. I will try to add some details here in case anyone else finds it helpful.
I first needed to load Babel standalone and so I used this answer to create a custom hook to load a script:
import { useEffect } from 'react';
const useScript = url => {
useEffect(() => {
const script = document.createElement('script');
script.src = url;
script.async = true;
document.body.appendChild(script);
console.log(`${url} script loaded`);
return () => {
document.body.removeChild(script);
console.log(`${url} script removed`);
}
}, [url]);
};
export default useScript;
then I used it in my component like this:
import useScript from '../../../hooks/useScript';
useScript("https://unpkg.com/#babel/standalone/babel.min.js");
then I later use the code I wrote in the initial question to transpile my code.

no-duplicate-selectors error for different selectors inside the same file

I am using stylelint within a CSS-IN-JS project (here using astroturf, but I face the same pattern using any CSS-IN-JS library such as styled-components as well).
I define different styled elements within the same file, and therefore sometimes end up having duplicated selectors and/or import rules.
/* style.js */
import styled from 'astroturf';
export const StyledComponentA = styled('div')`
transform: scale(0);
&.visible {
transform: scale(1);
}
`;
export const StyledComponentB = styled('div')`
opacity: 0;
/* -> stylelint error: Unexpected duplicate selector "&.visible" */
&.visible {
opacity: 1;
}
`;
Which I compose this way:
import React from 'react';
import { StyledComponentA, StyledComponentB } from './style';
export const Component = ({ isVisible }) => (
<StyledComponentA visible={isVisible}>
<StyledComponentB visible={isVisible}>Whatever</StyledComponentB>
</StyledComponentA>
);
Is there a way to set these stylelint rules on blocks instead of an entire file?
Is there a way to set these stylelint rules on blocks instead of an entire file?
There is not.
Rules like no-duplicate-selectors are scoped to a source and stylelint treats the following as sources:
entire files
code passed to the code option of the node API
stdin passed to the CLI
When writing CSS-in-JS, it might be advisable to turn off the rules scoped to sources. You can turn them off:
entirely in your configuration object e.g. "no-duplicate-selectors": null
on a case-by-case basis using command comments

How to access functions in onPrepare while opening the browser each time in protractor

I am using protractor-cucumber frame work(protractor 5.2.2 and cucumber 3.2.0).I need to login with multiple user credentials.So i need to use incognito window.So i have setup in my config file as given below.
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: ["--incognito"]
}
},
and i have added
browser.restart();
after each logout code.But when i am open new incognito windows,i am not able to access the code inside of onPrepare function.my onPrepare function is given below.
onPrepare: function() {
browser.ignoreSynchronization = true;
browser.manage().window().maximize();
global.testdata = require('./support/testdata.js');
}
so how can i access the code inside of onPrepare function while opening the browser each time.Thanks in advance.
you can wrap the code within onPrepare() into a function and export the function in a .js file.
// onPrepare.js, move the codes in `onPrepare()` at here
module.exports = function onPrepareConfig() {
browser.ignoreSynchronization = true;
browser.manage().window().maximize();
global.testdata = require('./support/testdata.js');
}
// protractor conf.js
onPrepare: function() {
// you need to import `onPrepare.js` within this function
// because the variable `browser` we used in `onPrepare.js`
// are available inside `onPrepare()`
var onPrepareConfig = require('./onPrepare.js');
onPrepareConfig();
}
// the code line where you call browser.restart();
browser.restart();
var onPrepareConfig = require('./onPrepare.js');
onPrepareConfig();
Node.js based on javascript language that is a single thread. So, each test which opens a browser runs in separate process and that's why you don't need incognito mode. The issue is how to share between multiple tests different users. The simplest way is:
create a file in a root of project with different users credentials and in the test beforeAll() get credentials and remove this line from file. At the end of test returns it back.
OR
you create a server with simple API for getting different credentials and use it in the test.
As you can see it is a little bit complicated.