Babel generating broken code when exporting react components from .jsx files - javascript

Consider below code:
src/bar.jsx:
import React from "react";
export default function Bar() {
return (
<>
<span>Bar</span>
</>
);
}
src/baz.jsx:
import React from "react";
export default function Baz() {
return (
<>
<span>Baz</span>
</>
);
}
src/foo.jsx:
import React from "react";
export default function Foo() {
return (
<>
<span>Foo</span>
</>
);
}
src/index.js:
export { default as Foo } from "./foo.jsx";
export { default as Bar } from "./bar.jsx";
export { default as Baz } from "./baz.jsx";
.babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": [
["#babel/transform-runtime"]
],
"ignore": [
"**/*.stories.js"
]
}
package.json:
{
"devDependencies": {
"#babel/cli": "7.19.3",
"#babel/core": "7.19.3",
"#babel/eslint-parser": "7.19.1",
"#babel/plugin-transform-runtime": "7.19.1",
"#babel/polyfill": "7.12.1",
"#babel/preset-env": "7.19.4",
"#babel/preset-react": "7.18.6",
"#babel/register": "7.18.9",
"eslint": "^8.25.0",
"eslint-plugin-react": "^7.31.10",
"prettier": "^2.7.1"
},
"engines": {
"node": "17.8.0 || 18.11.0",
"npm": "8.5.5 || 8.19.2"
},
"main": "./index.js",
"name": "mcve_babel",
"peerDependencies": {
"react": "17.0.2",
"react-dom": "17.0.2",
"react-router-dom": "6.2.2"
},
"scripts": {
"build": "babel src -d out --delete-dir-on-start --source-maps inline --copy-files --no-copy-ignored"
},
"version": "0.0.1"
}
And when i try to run npm run build I'll get
dist/index.js:
"use strict";
var _interopRequireDefault = require("#babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Bar", {
enumerable: true,
get: function get() {
return _bar["default"];
}
});
Object.defineProperty(exports, "Baz", {
enumerable: true,
get: function get() {
return _baz["default"];
}
});
Object.defineProperty(exports, "Foo", {
enumerable: true,
get: function get() {
return _foo["default"];
}
});
var _foo = _interopRequireDefault(require("./foo.jsx"));
var _bar = _interopRequireDefault(require("./bar.jsx"));
var _baz = _interopRequireDefault(require("./baz.jsx"));
The problem here is the dist tree will look like this:
dist/
├── bar.js
├── baz.js
├── foo.js
└── index.js
So If I tried to use this library in a webapp I'd get import errors because the babel generated code is broken (you can see the generated requires are pointing out to unexistent jsx files).
One possible workaround obviously would be by having exports without using extensions in the first place or by not using .jsx files but .js files instace. That said, I'd like to figure whether it's possible to have jsx files in place and still being able to transpile the code using babel without the final dist being broken code.
Am I missing any babel plugin/config?

Related

Component "font-awesome-icon" has already been registered in target app (NuxtJS 3)

I'm using NuxtJS 3 with FontAwesome. I've managed to get it working, but I receive a warning the console of my IDE which says:
[Vue warn]: Component "font-awesome-icon" has already been registered in target app.
Where does it come from? Is this a problem? And how to fix this?
Here is my package.json:
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview"
},
"devDependencies": {
"#nuxtjs/google-fonts": "^3.0.0-0",
"nuxt": "3.0.0-rc.6",
"sass": "^1.54.0",
"sass-loader": "^13.0.2"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^6.1.2",
"#fortawesome/free-brands-svg-icons": "^6.1.2",
"#fortawesome/free-regular-svg-icons": "^6.1.2",
"#fortawesome/free-solid-svg-icons": "^6.1.2",
"#fortawesome/vue-fontawesome": "^3.0.1",
"#nuxtjs/fontawesome": "^1.1.2",
"firebase": "^9.9.1"
}
}
My nuxt.config.ts:
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
plugins: [
'~/plugins/fontawesome.ts',
'~/plugins/firebase.client.ts'
],
buildModules: [
'#nuxtjs/google-fonts'
],
googleFonts: {
display: 'swap',
prefetch: true,
preconnect: true,
preload: true,
families: {
Nunito: true,
}
},
css: [
'#fortawesome/fontawesome-svg-core/styles.css',
],
runtimeConfig: {
FIREBASE_API_KEY: process.env.FIREBASE_API_KEY,
},
})
And the fontawesome plugin in ~/plugins/fontawesome.ts:
import { library, config } from '#fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
import { fas } from '#fortawesome/free-solid-svg-icons'
import { far } from '#fortawesome/free-regular-svg-icons'
import { fab } from '#fortawesome/free-brands-svg-icons'
import { defineNuxtPlugin } from "nuxt/app";
config.autoAddCss = false
library.add(fas)
library.add(fab)
library.add(far)
export default defineNuxtPlugin((nuxtApp) => {
// This line creates problems with TypeScript whereas it is not raising any runtime error
// #ts-ignore
nuxtApp.vueApp.component('font-awesome-icon', FontAwesomeIcon, {});
});
Several problems:
TypeScript doesn't like calling nuxtApp.vueApp.component() like this because apparently there is no such function declared for 3 arguments given by the FontAwesome documentation
The warning is annoying and I don't find anything that could help me.
My icons do show up (so it looks like this is working despite the warning).
Did I do something wrong?

Could not find a declaration file for module 'bootstrap/dist/js/bootstrap

I'm working on a nextjs application and installed bootstrap. The styles work but when I try to import the bootstrap.bundle.js file I get an error
Could not find a declaration file for module 'bootstrap/dist/js/bootstrap'. 'c:/Users/HP/OneDrive/Documents/webapps/nft-marketplace/node_modules/bootstrap/dist/js/bootstrap.js' implicitly has an 'any' type.
This is my pacakage.json
{
"name": "nft-marketplace",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"#nomiclabs/hardhat-ethers": "^2.0.2",
"#nomiclabs/hardhat-waffle": "^2.0.1",
"#openzeppelin/contracts": "^4.3.1",
"#popperjs/core": "^2.10.2",
"axios": "^0.21.4",
"bootstrap": "^5.0.0-beta3",
"chai": "^4.3.4",
"dropzone": "^5.9.3",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.4.6",
"hardhat": "^2.6.4",
"ipfs-http-client": "^52.0.3",
"next": "11.1.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"web3modal": "^1.9.4"
},
"devDependencies": {
"#types/bootstrap": "^5.1.6",
"autoprefixer": "^10.3.4",
"eslint": "7.32.0",
"eslint-config-next": "11.1.2",
"postcss": "^8.3.6",
"tailwindcss": "^2.2.10"
}
}
This is my app.js file
import "bootstrap/dist/css/bootstrap.css";
import "../styles/globals.css";
import { useEffect } from "react";
import "../styles/app.css";
function MyApp({ Component, pageProps }) {
useEffect(() => {
import("bootstrap/dist/js/bootstrap");
}, []);
return <Component {...pageProps} />;
}
export default MyApp;
I have searched and tried different solutions. I have also installed #types/bootstrap but still didn't work. What am I doing wrong? I need help this issue has me so confused.
this worked for me
useEffect(() => {
typeof document !== undefined
? require('bootstrap/dist/js/bootstrap')
: null
}, [])
If you use bootstrap 5 try to install propperjs
npm install #popperjs/core --save
Here are a couple fixes that seemed to work for me. Make sure #types/bootstrap is installed.
Option 1: Instead of import("bootstrap/dist/js/bootstrap");, try just import("bootstrap");.
Option 2: You can tell typescript where the types are for the "bootstrap/dist/js/bootstrap" module by using the paths option in tsconfig.json. That would look something like this:
{
...
"compilerOptions": {
"paths": {
"bootstrap/dist/js/bootstrap" : ["./node_modules/types/bootstrap"]
}
},
...
}
If you are using Vue Vite and have already downloaded npm i --save-dev #types/bootstrap.
You will try this next step which is to add a line of code in the env.d.ts folder, add declare module "boostrap"

I'm having issues setting up my jest config react native Cannot Import Components

I'm having issues related somehow maybe to babel configs or package.json file... in short i can't import any component from outside the test file
here's the error:
E:\.......\src\components\ButtonInstance.jsx:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React from 'react';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import React from 'react';
2 | import { render, fireEvent } from '#testing-library/react-native';
> 3 | import ButtonInstance from '../src/components/ButtonInstance';
| ^
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (__tests__/index.test.js:3:1)
here's my test file:
import React from 'react';
import { render, fireEvent } from '#testing-library/react-native';
import ButtonInstance from '../example/src/ButtonInstance';
test('Button', () => {
const onPressMock = jest.fn();
const { getByText } = render(<ButtonInstance onPress={onPressMock} />);
fireEvent.press(getByText('Press me'));
expect(onPressMock).toHaveBeenCalledTimes(1);
});
and here is my button instance Component
import React from 'react';
import { Text, TouchableHighlight } from 'react-native';
export default function ButtonInstance(onPress) {
return (
<TouchableHighlight onPress={onPress}>
<Text>Press me</Text>
</TouchableHighlight>
);
}
package.json file
{
"name": "components-example",
"description": "Example app",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start"
},
"dependencies": {
"#iconscout/react-native-unicons": "^1.0.3",
"react": "16.13.1",
"react-native": "0.63.4",
"react-native-svg": "^9.5.3",
"react-native-svg-transformer": "^0.14.3"
},
"devDependencies": {
"#babel/core": "^7.12.10",
"#babel/runtime": "^7.12.5",
"babel-plugin-module-resolver": "^4.0.0",
"metro-react-native-babel-preset": "^0.64.0"
}
}
and last file babel.config.js
module.exports = {
presets: [
'#babel/preset-flow',
'#babel/preset-react',
[
'#babel/preset-env',
{
targets: {
node: '10',
},
bugfixes: true,
},
],
],
plugins: ['#babel/plugin-proposal-class-properties'],
};
folders structure
|__ __tests__
|__ index.test.js
|__ node_modules
|__ src
|__ components
|__ ButtonInstance.jsx
|__ babel.config.js
|__ package.json
I've solved this issue it was related somehow to babel configs you can add these files to your app here is the new babel working config file (maybe it helps someone):
babel.config.js
module.exports = (api) => {
api.cache(true);
return {
env: {
development: {
plugins: [
[
'module-resolver',
{
root: ['./src'],
extensions: ['.js', '.jsx'],
},
],
],
},
},
presets: [['#babel/preset-env', { targets: { node: 'current' } }]],
};
};
And the jest config file:
jest.config.js
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['js', 'jsx', 'json', 'svg'],
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)x?$',
transform: {
'^.+\\.jsx?$': '<rootDir>/node_modules/react-native/jest/preprocessor.js',
'^.+\\.svg$': 'jest-svg-transformer',
},
testPathIgnorePatterns: ['\\.snap$', '<rootDir>/node_modules/'],
cacheDirectory: '.jest/cache',
transformIgnorePatterns: [
'node_modules/(?!(react-native|react-navigation|react-navigation-tabs|react-navigation-redux-helpers|react-native-safari-view|react-native-linear-gradient|react-native-blur|react-native-animatable|react-native-wkwebview-reborn|react-native-safe-area-view|react-native-popup-menu|redux-persist)/)',
],
};

How to configure babel7 to support `import {}` from `export default` in javascript

I am using webpack 4 and babel 7 for a javascript project. I doesn't work when I use import { ... } syntax. Below is the source code:
./test.js
const a = 1;
export default { a };
./index.js
import { a } from './test';
console.log(a);
The output is undefined. It works fine if I change index.js as below:
import a from './test';
console.log(a.a);
I wonder how I should configure babel7 to support import {}. Below is my .babelrc:
{
"presets": [
"#babel/preset-env"
]
}
I also tried a few plugins but none of them works:
{
"presets": [
"#babel/preset-env"
],
"plugins": [
["#babel/plugin-proposal-decorators", { "legacy": true }],
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-async-to-generator",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-syntax-export-default-from",
"#babel/plugin-proposal-export-namespace-from"
]
}
Below is the dependencies:
devDependencies": {
"#babel/cli": "^7.2.3",
"#babel/core": "^7.2.2",
"#babel/plugin-proposal-class-properties": "^7.2.3",
"#babel/plugin-proposal-decorators": "^7.2.3",
"#babel/plugin-proposal-export-default-from": "^7.2.0",
"#babel/plugin-proposal-export-namespace-from": "^7.2.0",
"#babel/plugin-proposal-object-rest-spread": "^7.2.0",
"#babel/plugin-syntax-export-default-from": "^7.2.0",
"#babel/plugin-transform-arrow-functions": "^7.2.0",
"#babel/plugin-transform-async-to-generator": "^7.2.0",
"#babel/preset-env": "^7.2.3",
"#babel/preset-es2015": "^7.0.0-beta.53",
"babel-loader": "^8.0.4",
"jest": "^23.6.0",
"webpack": "^4.28.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.14"
},
Below is my webpack configuration for babel-loader:
module: {
rules: [
{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader'
}
]
},
This has nothing to do with Babel. The problem is that you need to read up on how named exports work.
import { a } from './test';
is trying to import the named export a from test.js. The brackets {} syntax is for importing named exports.
Instead, go with
import a from './test';
which is the syntax for importing the default export,
or change test.js to do an export named a:
const a = 1;
export { a };
Your test.js only has a default export, and none named a.
you need to change the format from this
const a = 1;
export default { a };
to this
const a = require('1')
module.exports = { a: {} };
also you need to create a intermediate file webpack.config.js
point to the webpack.config.babel.js file with this code
require('babel-register');
module.exports = require('./webpack.config.babel.js');

Jest encountered an unexpected token

Not sure why it's complaining on this line:
const wrapper = shallow(<BitcoinWidget {...props} />);
/Users/leongaban/projects/match/bitcoin/src/components/bitcoinWidget.test.js: Unexpected token (17:26)
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
- To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
- If you need a custom transformation specify a "transform" option in your config.
- If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
15 |
16 | describe('when rendering', () => {
>17 | const wrapper = shallow(<BitcoinWidget {...props} />);
18 | ^
19 | it('should render a component matching the snapshot', () => {
20 | const tree = toJson(wrapper);
Entire test:
import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
// Local components
import BitcoinWidget from './bitcoinWidget';
const props = {
logo: 'foobar',
coin: {
price: 0
},
refresh: jest.fn()
}
describe('when rendering', () => {
const wrapper = shallow(<BitcoinWidget {...props} />);
it('should render a component matching the snapshot', () => {
const tree = toJson(wrapper);
expect(tree).toMatchSnapshot();
expect(wrapper).toHaveLength(1);
});
});
The component
import React from 'react';
const BitcoinWidget = ({ logo, coin : { price }, refresh }) => {
return (
<div className="bitcoin-wrapper shadow">
<header>
<img src={logo} alt="Bitcoin Logo"/>
</header>
<div className="price">
Coinbase
${price}
</div>
<button className="btn striped-shadow white" onClick={refresh}>
<span>Refresh</span>
</button>
</div>
);
}
export default BitcoinWidget;
And my package.json
{
"name": "bitcoin",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-redux": "^5.0.7",
"react-scripts": "1.1.5",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject",
"test": "yarn run test-jest:update --verbose --maxWorkers=2",
"test-jest:update": "jest src --updateSnapshot",
"test-jest": "jest src"
},
"now": {
"name": "bitcoin",
"engines": {
"node": "8.11.3"
},
"alias": "leongaban.com"
},
"jest": {
"verbose": true,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/client/assetsTransformer.js"
},
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules"
]
},
"devDependencies": {
"enzyme": "^3.4.4",
"enzyme-to-json": "^3.3.4",
"jest": "^23.5.0"
}
}
Add this in your package.json jest config.
"transform": {
"\\.js$": "<rootDir>/node_modules/babel-jest"
},
Let me know if the issue still persists.
For anyone using create-react-app, only certain jest configurations can be changed in package.json when using create-react-app.
I have issues with Jest picking up an internal library, Jest would display 'unexpected token' errors wherever I had my imports from this library.
To solve this, you can change your test script to the below:
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(<your-package-goes-here>)/)'",
For anyone who struggled with this issue and none of the above answers worked for them.
After a long time of searching, I reached for this solution:
edit your jest.config.js to add transformIgnorePatterns
//jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
testMatch: ["**/__tests__/**/*.ts?(x)", "**/?(*.)+(test).ts?(x)"],
transform: {
"^.+\\.(js|ts)$": "ts-jest",
},
transformIgnorePatterns: [
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.js$",
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.ts$",
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.tsx$",
],
}
put the packages that you want to ignore inside [] and separate them by |
in my case [#autofiy/autofiyable|#autofiy/property]
I also encountered the same error while setting up Jest in my React app created using Webpack. I had to add #babel/preset-env and it was fixed. I have also written a blog article about the same.
npm i -D #babel/preset-env
And then add this in "presets" in .babelrc file. E.g.
{
"presets": ["#babel/react", "#babel/env"]
}
https://medium.com/#shubhgupta147/how-i-solved-issues-while-setting-up-jest-and-enzyme-in-a-react-app-created-using-webpack-7e321647f080?sk=f3af93732228d60ccb24b47ef48d7062
I added the jest update to my package.json
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(<package-name>|<second-package-name>)/)"
]
},
Feel free to remove the |<second-package-name> if not required.
You can also do it as part of your script as mentioned #paulosullivan22
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(<package-name>)/)'"
In my case, the issue was that I was importing the original module in the mocked module:
import urlExist from "url-exist";
async function stubbedUrlExist(): Promise<boolean> {
// do something
}
export default stubbedUrlExist;
The solution was to not import url-exist in the url-exist mock. This might have lead to a circular import. Jest was perhaps catching this error in a generic try<>catch block dealing with the loading of modules.
Below works for me.
Create babel.config.js file.
module.exports = {
presets: [
[ '#babel/preset-env', { targets: { esmodules: true } } ],
[ '#babel/preset-react', { runtime: 'automatic' } ],
],
};
I updated some dependencies (react, jest and others), and I also got the error:
Jest encountered an unexpected token - SyntaxError: Cannot use import statement outside a module
I had dev dependencies with needed to be transpiled.
What I did first was start all over:
$ jest --init
A jest.config.js is now generated (before I just had Jest configuration in my package.json).
In the error message under details you can see the reporting module, for me it looked like this:
Details: /<project_root>/node_modules/axios/index.js:1
Adding the following transform ignore in jest.config.js solved my problem:
transformIgnorePatterns: [
"node_modules/(?!axios.*)"
],
The axios module was now nicely transpiled and gave no more problems, hope this helps!
https://jestjs.io/docs/27.x/getting-started
Below works for me
module.exports = {
presets: [
["#babel/preset-env", { targets: { node: "current" } }],
"#babel/preset-typescript", "#babel/react"
]
};
could not get it working with transforms, I ended up mocking the dependency:
Create a file: <path>/react-markdown.js
import React from 'react';
function ReactMarkdown({ children }){
return <>{children}</>;
}
export default ReactMarkdown;
On jest.config.js file add:
module.exports = {
moduleNameMapper: {
'react-markdown': '<path>/mocks/react-markdown.js',
},
};
credits to juanmartinez on https://github.com/remarkjs/react-markdown/issues/635

Categories

Resources