Babel not transpile files from parent dir - reactjs

How can I tell babel to transpile files that are not in current (root) directory?
Here is my project structure:
|-project
|build
|-node_modules
-.babel.rc
-package.json
|src
|test
My source files are in "src", my test files are in "test".
I want to run mocha test from my package json script. I use babel to transpile my src files (ES6, React) on the fly.
Here is my package.json:
"scripts": {
"test": "mocha --require #babel/register '../test/**/*Test.js'"
}
and .babelrc:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
But when I run yarn test, I get error message like this:
/src/App.spec.js:1
(function (exports, require, module, __filename, __dirname) { import React from 'react';
^^^^^^
SyntaxError: Unexpected token import
I'v tried milion config combination, but nothing works, I don't want to have package.json and babel config files in the project root (that works) and I couldn't figure it out how to tell babel what to transpile, without changing project structure.

From the error you posted, it seems your babel configuration cannot process jsx syntax. You can resolve this by installing #babel/plugin-transform-react-jsx plugin.
And configuring it like so:
.babelrc
{
...
"plugins": ["#babel/plugin-transform-react-jsx"]
}

I finally came to this solution:
package.json:
"test": "NODE_PATH=$PWD/node_modules:$PWD/../src/ mocha --require babelRegister.js ../test/**/*.spec.js"
babelRegister.js:
require('#babel/register')({
extends: './.babelrc',
ignore: [/node_modules/],
});
Both "extends" and "ignore" must be set, otherwise it's not working. Looks hackish but I didn't find better solution.

Related

Issues trying to extend ESLint in a create-react-app project

Create-react-app allows you to extend the ESLint config that comes with create-react-app:
https://create-react-app.dev/docs/setting-up-your-editor#experimental-extending-the-eslint-config
However when I try to do this in my own project i just get this error
(Image of error)
Error
Error: Cannot find module 'eslint-config-shared-config'
Command run
eslint --ignore-path .gitignore --ext .js,.ts,.tsx .
.eslintrc
{
"extends": ["react-app", "shared-config"],
"rules": {
"additional-rule": "warn"
},
"overrides": [
{
"files": ["**/*.ts?(x)"],
"rules": {
"additional-typescript-only-rule": "warn"
}
}
]
}
A safe way to setup a base ESLint config file to build upon is by following the ESLint usage guide
$ npx eslint --init
# or
$ yarn run eslint --init
Like #jonrsharpe said, shared-config is just an example that cannot be used literally, the docs was trying to explain that you could use shared configurations.
For example, if you add an ESLint plugin with a shared-config rule set, then you could use that as indicated by the example.
Difference between plugins and extends in ESLint
EXTEND_ESLINT flag was removed in react-scripts v4

Craco build fails, taking aliased folder as external package

I'm using craco and craco-alias to implement aliases for imports in my Create React App project.
Followed instructions in https://github.com/gsoft-inc/craco/blob/master/packages/craco/README.md#installation and https://github.com/risenforces/craco-alias#readme
I configured package.json to use craco instead of react-scripts for starting dev server, tests and production build
...
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"lint:css": "stylelint './src/**/*.css'",
"lint:js": "eslint 'src/**/*.js'",
"test:w": "craco test --watch",
"postinstall": "patch-package"
},
...
Then I created jsconfig.json file w aliases paths
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#components": ["components/*", "components"],
"#constants": ["constants/*", "constants"],
"#assets": ["assets/*", "assets"],
"#store": ["store/*", "store"],
"#utils": ["utils/*", "utils"]
},
"include": ["src"],
"exclude": ["node_modules", "build", "coverage"]
}
And craco.config.js file, which uses craco-alias plugin
/* craco.config.js */
const CracoAlias = require('craco-alias');
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
baseUrl: './src',
source: 'jsconfig',
}
}
]
}
Now I'm using aliases for imports in my app like this
// root index.js file
...
import Layout from '#components/Layout';
import store from '#store'; // this line causes error on CI build
function App() {
return (
<Layout>
/* inner components */
</Layout>
);
}
Everything works fine (aliased imports works on dev-server, in jest tests and even if I serve locally built project) until I push it to github repo. That repo has configured github actions to build and test project on remote server and it fails with error on build step, after installing all packages.
Run yarn build
yarn run v1.22.4
$ craco build
Creating an optimized production build...
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
Failed to compile.
./src/index.js
Cannot find module: '#store'. Make sure this package is installed.
You can install this package by running: npm install #store.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
##[error]Process completed with exit code 1.
Could somebody help me understand what wrong with my code? Why craco or webpack expect '#store' to be external package instead of aliased import of internal module?
In my case problem wasn't in craco or webpack, but in my previous actions and OS filesystem differences. I'm using Windows 10 and WSL in VS Code terminal. So before I use '#' symbol for aliases I tried to use CamelCase for my folders and renamed it via windows explorer (because for me it was simpler to close VSCode and rename files via explorer than to open new bash terminal in new VSCode window after closing opened files).
Then I prefer to use '#' symbol and rename folders back to lowercase. I configured aliases and pushed changes to remote github repo, where CI actions were run. When CI was running actions it can't find 'store' folder (because previously I renamed it to 'Store' and it was last saved path to folder in git), so it tried to find external package named 'store'.
To fix this I change git config to stop ignoring namecasing for my folder by running command git config core.ignorecase false. Git history was updated, I push it to remote repo and CI actions succeeded.

Importing react app into existing Webpack project

I have a Rails app that uses Webpack to bundle its assets. It doesn't currently use React.
In a separate repository, I have created a React app. This React app basically implements a complex custom UI element. The plan is that I can import this react component into my main application.
So far I have added the git repo to my package.json file and can see that the source code of my react app is being downloaded into the /node_modules folder.
I can get Webpack to bundle the app by adding:
To the React app package.json:
"prepare": "npm run build"
And in my main application webpack.config
module.exports = {
...
resolve: {
...
alias: {
MyReactApp: 'my-react-app/dist/bundle.js'
}
}
}
But it seems to be bundling all the libraries that my React app uses inside bundle.js and not adding them to the dependency tree.
It appears that the prepare command is basically bundling my React app into a /dist/bundle.js file and Webpack is simply including this file as-is. I need Webpack to manage the dependencies of my React app, such that I don't have unnecessary libraries duplicated in the final Webpack output.
Is there a better way to achieve what I am trying to achieve?
It is better to bundle them together. Basically, it is trying to bundle already bundled code.
This may work:
resolve: {
alias: {
MyReactApp: 'my-react-app/index.js'
}
}
index.js should be main jsx starting point.
Additionally, you need to add compile rules for jsx files, I never bundled Rail apps but React apps you should follow these steps;
Add rule to webpack.config.js
module: {
rules: [
{
// this is so that we can compile any React,
// ES6 and above into normal ES5 syntax
test: /\.(js|jsx)$/,
// we do not want anything from node_modules to be compiled
exclude: /node_modules/,
use: ["babel-loader"]
},
...
]
}
Install Babel modules:
npm install #babel/core #babel/node #babel/preset-env #babel/preset-react babel-loader
create a file called .babelrc and paste the following code
{
"presets": ["#babel/env", "#babel/react"],
"plugins": ["#babel/plugin-proposal-class-properties"]
}
Run webpack though babel-node like following script
"webpack": "babel-node ./node_modules/webpack/bin/webpack"
This would be my approach to solve this problem. It will still import react to your project. But instead of adding the compiled project, it will add jsx files and will compile them during the bundling process.
Note:
babel/core this is used to compile ES6 and above into ES5
babel/node this is used so that we can import our plugins and packages inside the webpack.config.js rather than require them
(it’s just something that I like, and maybe you’ll like it too)
babel/preset-env this will determinate which transformations or plugins to use and polyfills (i.e it provides modern
functionality on older browsers that do not natively support it)
based on the browser matrix you want to support
babel/preset-react this is going to compile the React code into ES5 code
babel-loader this is a Webpack helper that transforms your JavaScript dependencies with Babel (i.e. will transform the import
statements into require ones)

react native transform - error couldn't find preset "babel-preset-react-native-stage-0

I started ejecting expo, after so much struggle I could able to solve all build issues.
When I run the app using 'sudo react-native run-android' I started getting following error
Error:
The development server returned response code 500
Bundling `index.android.js` [development, non-minified, hmr disabled]
0.0% (0/1), failed.
error: bundling failed: "TransformError:
/Development/SourceCode/MobileApp/index.android.js:
Couldn't find preset \"babel-preset-react-native-stage-0/decorator-support\" relative to directory \"/Development/SourceCode/MobileApp\""
I tried almost all possible fixes given in github and SO
uninstalling latest version of babel-preset-react-native and re-installing sudo yarn add babel-preset-react-native#2.1.0
Clear cache Yarn Cache, npm cache
deleting build folder, deleting npm modules and reinstall all modules
Few people fixed the issue by removing watchman, but I am not using watchman at all.
Adding .babelrc mentioning decorator-support for preset as follows, this fix also didn't work.
.babelrc file looks like this
{
"presets": [
"react-native",
"babel-preset-react-native-stage-0/decorator-support"
],
"env": {
"development": {
"plugins": [
"transform-react-jsx-source"
]
}
}
}
None of those fixes worked for me. using babel-preset-react-native#2.1.0 also didn't fix the issue because that was the major fix.
Try to use normal babel preset 0 as per: https://babeljs.io/docs/plugins/preset-stage-0
so
"presets": ["react-native", "stage-0"]
You can create .babelrc file in root of you project with following content if you cany use old version of React Native:
{
"presets": ["react-native"]
}
If you did use Expo in your project,
try:
$ cd your_project
$ nano .babelrc (Or any editor that you wants)
Copy and paste #A
If you didn't have .babelrc in your project, then:
$ cd your_project
touch .babelrc
copy and paste #A
#A
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": ["transform-react-jsx-source"]
}
}
}

Running Babel across a monorepo of packages/components

I'm trying to build a React component library, but each component will have its own unique dependencies. To keep it tidy, I've started a monorepo using Yarn's Workspaces. It currently looks like this:
components
component1
src
index.js
dist ???
package.json
component2
src
index.js
dist ???
package.json
node_modules
package.json
.babelrc
etc.
I'd like to be able to run a Babel command at the root level that compiles each src/index.js to its relative dist/index.js. Is this possible? Or can anyone recommend a tool that can iterate this?
Figured it out. Install Lerna at root-level (with Workspace flag, to allow it to install).
yarn add --dev lerna -W
Initialise lerna.
node_modules/lerna/bin/lerna.js init
Update lerna.json to point to the "components" directory.
{
"lerna": "2.5.1",
"packages": ["components/*"],
"version": "0.0.0"
}
Add script to root-level package.json
"scripts": {
...
"build-components": "NODE_ENV=production lerna exec --parallel -- babel src -d dist",
...
},

Resources