Jest importing re-exported named exports - javascript

I'm trying to test modules which import re-exported named exports. Basic import statement work properly (both default and named) except the case the title suggests.
A repro-repo: https://github.com/bali182/babel-jest-export-everything-bug
(I think it's a problem with Jest but after opening an issue devs suggested that it's a configuration problem, so I'm asking here)
To demonstrate the issue here:
package.json
{
"name": "babel-jest-export-everything-bug",
"scripts": {
"test": "jest --config .jestrc.json"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-jest": "^21.2.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"jest": "^21.2.1"
}
}
.babelrc
{
"presets": [
[ "es2015", { "modules": "commonjs" } ],
"stage-0",
"react"
],
"plugins": [
"transform-decorators-legacy",
"transform-runtime"
]
}
.jestrc.json
{
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
namedExports.js
export const x = 1
export const y = 2
export const z = 3
reExports.js
export * from './namedExports'
export default { hello: 'world' }
reExports.test.js
import Foo, { x, y, z } from './reExports'
describe('testing re-exports', () => {
it('will never get to this method', () => {
expect(x).toBe(1)
})
})
Which then fails with
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
at Object.<anonymous> (src/reExports.test.js:1:120)
at Generator.next (<anonymous>)
Any suggestions what am I doing wrong here?

solution
this happens due to transform-runtime plugin, in order to fix it, just updated your .babelrc file with
["transform-runtime", { "polyfill": false }]
see example of my file:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": [
"jsx-vue-functional",
"transform-vue-jsx", ["transform-runtime", { "polyfill": false }],
"transform-decorators-legacy",
"lodash"
],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": [
"transform-vue-jsx",
"transform-es2015-modules-commonjs",
"dynamic-import-node",
"transform-decorators-legacy"
]
},
"cli": {
"presets": ["env", "stage-2"],
"plugins": [
[ "babel-plugin-webpack-alias", { "config": "./aliases.config.js" } ],
"transform-vue-jsx",
"transform-es2015-modules-commonjs",
"dynamic-import-node",
"transform-decorators-legacy"
]
}
}
}

Related

How to fix unexpected Webpack error when including #popperjs/core and eslint in code

I am having a problem with #popperjs/core not working in my normal javascript environment.
Here is some code that demos my problem
index.js
import { createPopper } from '#popperjs/core';
console.log("Hello world!");
package.json
{
"name": "popperjsproblem",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack"
},
"dependencies": {
"#popperjs/core": "^2.10.2"
},
"devDependencies": {
"#babel/core": "^7.15.8",
"#babel/plugin-proposal-class-properties": "^7.14.5",
"#babel/preset-env": "^7.15.8",
"#babel/eslint-parser": "^7.15.8",
"babel-loader": "^8.2.2",
"eslint": "^8.0.1",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-webpack-plugin": "^3.0.1",
"eslint-plugin-import": "^2.20.0",
"webpack": "^5.58.2",
"webpack-cli": "^4.9.0"
},
"babel": {
"presets": [
"#babel/preset-env"
]
},
"eslintConfig": {
"extends": [
"eslint:recommended"
],
"root":true,
"parser": "#babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true,
"es6": true
},
"rules": {
"no-debugger": "off",
"no-console": "off",
"no-unused-vars": "warn"
},
"settings": {
"import/resolver": "webpack"
}
}
}
webpack.config.js
const path = require("path");
const ESLintPlugin = require('eslint-webpack-plugin');
const esLintLoaderOptions = {
extensions: [`js`, `jsx`],
exclude: [
`/node_modules/`
]
};
module.exports = {
entry: "./index.js",
mode: "development",
target:"web",
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/dist/",
},
stats: {
colors: true,
},
devtool: "cheap-module-source-map",
plugins: [
new ESLintPlugin(esLintLoaderOptions)
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
],
}
};
When I run "npm run build" I get the following error
ERROR in Failed to load config "./.config/eslint.config" to extend from.
Referenced from: {project directory}\node_modules\#popperjs\core\package.json
If I were to import another 3rd party library instead of #popperjs/core in index.js and run "npm run build" no errors are displayed, the code is correctly transpiled and put in a file called main.bundle.js which is found in the dist folder. I would expect exactly the same to happen with #popperjs/core. So my question is is it possible to change something so that I can import #popperjs/core and get the same behaviour as you get with other libraries. The problem appears to be to do with ESLint. I would ideally like to keep ESLint because it is obviously a very useful tool in development.
When researching the problem I came across this link https://github.com/popperjs/popper-core/issues/1105 which appears to describe a problem similar to mine. However I can't see how I would apply the solutions given my set up.
Strangely the solution appears to be to remove node_modules from the eslint-webpack-plugin options. I.e. change
const esLintLoaderOptions = {
extensions: [`js`, `jsx`],
exclude: [
`/node_modules/`
]
};
to
const esLintLoaderOptions = {
extensions: [`js`, `jsx`]
};
The eslint-webpack-plugin docs say that node_modules are excluded by default so must be something to do with that.

React and laravel mix : Cannot find module '#babel/preset-react '

I am learning unit testing using jest testing library in react js with laravel, here is what I have so far.
.babelrc file
{
"plugins": [
[
"module-resolver",
{
"root": [
"./resources/js"
],
"alias": {
"test": "./test"
}
}
]
],
"env": {
"test": {
"presets": [
["#babel/preset-env", {
"targets": {
"node": "current"
}
}],
["#babel/preset-react ", {
"targets": {
"node": "current"
}
}]
]
},
"development": {
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 2%",
"uglify": true
}
}]
]
},
"production": {
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 2%",
"uglify": true
}
}]
]
}
}
}
package.json
{
............
"devDependencies": {
"#babel/plugin-proposal-class-properties": "^7.5.0",
"#babel/preset-env": "^7.12.1",
"#babel/preset-react": "^7.12.1",
"babel-jest": "^26.6.0",
"babel-plugin-module-resolver": "^3.2.0",
"cross-env": "^5.2.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"jest": "^26.6.0",
"laravel-mix": "^5.0.5",
"react-test-renderer": "^17.0.0",
"resolve-url-loader": "^2.3.1",
"sass": "^1.26.3",
"sass-loader": "^7.1.0"
}
}
Now when I run npm test I get the following error.
What do I need to do to solve this error?

Jest - SyntaxError: Unexpected identifier

Doing some testing of some NodeJS functions using Jest, but it doesn't like import statements, e.g. import DatabaseController from '../util/database-controller'.
I've doing some reading and people suggested installing babel-jest and updating my config (below), but I've not had any luck. What am I missing? From what I understand, it doesn't understand import statements as it's an es6 thing...
Jest part of my package.json:
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"resolver": "jest-pnp-resolver",
"setupFiles": [
"react-app-polyfill/jsdom"
],
"testMatch": [
"<rootDir>/**/__tests__/**/*.{js,jsx}",
"<rootDir>/**/?(*.)(spec|test).{js,jsx}"
],
"testEnvironment": "jsdom",
"testURL": "http://localhost",
"transform": {
"^.+\\.jsx?$": "babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$",
"^.+\\.module\\.(css|sass|scss)$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node"
]
},
Lately I find that I don't need babel-jest at all, and can get by simply with #babel/preset-env, and the following .babelrc:
{
"env": {
"test": {
"presets": [["#babel/preset-env"]]
}
}
}
This worked for my simple set-up:
devDependencies (in package.json):
"devDependencies": {
"babel-eslint": "^10.0.3",
"babel-preset-env": "^1.7.0",
"jest": "^24.9.0",
"parcel-bundler": "^1.12.3"
}
I simply created a babel.config.js as follows:
// babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
Note - make sure to clear the cache before running!
Clear cache:
./node_modules/.bin/jest --clearCache

React Hot Loader seems to work but doesn't update. [babel-preset-env]

I tried to set up a minimal project which utilises the newest versions of Webpack, React, Babel and React Hot Loader.
I have the same issue as described here. However the only difference is that I am using (beside solely the stuff mentioned above) babel-preset-env instead of babel-preset-es2015, thus the fix does not apply for me.
In short: Everything works, React Hot Loader detects changes but the components are not rerendered and the changes are not applied to the website.
You can find the complete project here. (yarn install/yarn start should get it started) You can reproduce the behaviour by changing the testString in /components/App.js and saving the file.
What am I doing wrong?
webpack.config.js
var webpack = require('webpack')
module.exports = {
entry: [
'react-hot-loader/patch',
'./src/index.js'
],
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js'
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
}
}
]
},
devServer: {
contentBase: './dist',
hot: true
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
]
}
.babelrc
{
"presets": [
"react",
[ "env", {
"targets": {
"browsers": "> 10%"
}
}]
],
"plugins": ["react-hot-loader/babel"]
}
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from '../components/App'
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('app'),
)
}
render(App)
if (module.hot) {
const NextApp = require('../components/App').default
module.hot.accept('../components/App', () => { render(NextApp) })
}
package.json
{
"name": "minimal-react",
"version": "0.1.0",
"description": "minimal react",
"main": "index.js",
"repository": "https://github.com/PeterKey/minimal-react.git",
"dependencies": {
"path": "^0.12.7",
"react": "^16.1.1",
"react-dom": "^16.1.1",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.4"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"react-hot-loader": "^3.1.3"
},
"scripts": {
"start": "webpack-dev-server --progress --colors --config ./webpack.config.js"
}
}
Okay I realised that I simply need to set the {"modules": false} property for the "env" preset the same way as for the "es2015" preset.
.babelrc
{
"presets": [
"react",
[ "env", {
"modules": false,
"targets": {
"browsers": "> 10%"
}
}]
],
"plugins": ["react-hot-loader/babel"]
}

Module build failed: Error: Couldn't find preset "transform-class-properties" relative to directory

I've tried putting an arrow function in my class which failed to compile.
I've read that I should install https://www.npmjs.com/package/babel-plugin-transform-class-properties
Now I'm getting the error:
Module build failed: Error: Couldn't find preset
"transform-class-properties" relative to directory
"/home/luke/Documents/myProject"
I've tried the solutions suggested in these posts (and others)
Webpack + Babel: Couldn't find preset "es2015" relative to directory
Error: Couldn't find preset "es2015" relative to directory
My current setup is as follows:
/app/components/App.js
import React from 'react'
import { Switch, Route, BrowserRouter as Router } from 'react-router-dom'
class App extends React.Component{
sayHello = name => `Hello ${name}!`
render(){
return(
<Router>
<div >
...
</div>
</Router>
)
}
}
export default App
/package.json
{
"name": "um-web",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --open",
"build": "NODE_ENV='production' webpack -p"
},
"babel": {
"presets": [
"env",
"react",
"es2015",
"transform-class-properties"
]
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.0.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-env": "^1.6.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.4",
"html-webpack-plugin": "^2.28.0",
"style-loader": "^0.18.2",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5"
},
"dependencies": {
"amazon-cognito-identity-js": "^1.19.0",
"axios": "^0.16.2",
"d3": "^4.9.1",
"lodash": "^4.17.4",
"moment": "^2.18.1",
"prop-types": "^15.5.10",
"query-string": "^4.3.4",
"react": "^15.6.1",
"react-dimensions": "^1.3.0",
"react-dom": "^15.6.1",
"react-measure": "^2.0.2",
"react-router-dom": "^4.1.1",
"recharts": "^1.0.0-alpha.1",
"semantic-ui-react": "^0.69.0"
}
}
/webpack.config.js
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var webpack = require('webpack')
var config = {
entry: './app/index.js',
output:{
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js',
publicPath: '/'
},
module:{
rules:[
{ test: /\.(js)$/, use: 'babel-loader'},
{ test: /\.css$/, use: ['style-loader', 'css-loader']}
]
},
devServer: {
historyApiFallback: true
},
plugins: [
new HtmlWebpackPlugin({
template: 'app/index.html'
})
]
}
if(process.env.NODE_ENV === 'production'){
config.plugins.push(
new webpack.DefinePlugin({
'process.env' : {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}
}),
new webpack.optimize.UglifyJsPlugin()
)
}
module.exports = config
transform-class-properties is a plugin not a preset, so you should put it in your babel plugin config.
Here is an example .babelrc
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"],
"uglify": true
},
"modules": false
}],
"react"
],
"plugins": [
["transform-class-properties", { "spec": true }],
"transform-decorators",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
And the explanation of this plugin:
https://babeljs.io/docs/plugins/transform-class-properties/
Hope this helps.
babel-plugin-transform-class-properties is a plugin not a preset. When you list it under presets, Babel will look for the module with the babel-preset- prefix in addition to the literal module name. See Plugin/Preset Paths for details.
You need to put it under plugins, as the Usage in the README shows.
"babel": {
"presets": [
"env",
"react"
],
"plugins": [
"transform-class-properties"
]
},
I also removed the es2015 preset, because it is deprecated in favour of env which contains everything that es2015 does and more.

Categories

Resources