Babel-loader not transpiling JSX component. ModuleParseError - javascript

I'm trying to build a standalone component as a package. I'm using webpack to transpile all the CSS and JS/JSX files into JS. I'm able to build the package and pack it into a .tgz file using npm pack. However, when I install the package in another project and try using the component from the installed package. I'm getting this error:
ModuleParseError: Module parse failed: Unexpected token (34:8)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
And, in the terminal of the running project, I get this:
error - SyntaxError: Cannot use import statement outside a module
webpack.config.js
const path = require('path')
module.exports = {
mode:'production',
entry:'./src/components/StandaloneComponent.js',
output:{
path:path.join(__dirname,'dist'),
filename:'StandaloneComponent.js',
libraryTarget:"commonjs2"
},
module:{
rules:[
{
test:/\.js|jsx$/,
exclude:/(node_modules)/,
use:'babel-loader'
},
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
}
]
},
resolve:{
alias:{
'react':path.resolve(__dirname,'./node_modules/react'),
'react-dom':path.resolve(__dirname,'./node_modules/react-dom'),
'next':path.resolve(__dirname,'./node_modules/next')
}
},
externals:{
react:{
commonjs:"react",
commonjs2:"react",
amd:"React",
root:"React"
},
"react-dom":{
commonjs:"react-dom",
commonjs2:"react-dom",
amd:"ReactDOM",
root:"ReactDOM"
},
next:{
commonjs:"next",
commonjs2:"next",
amd:"Next",
root:"Next"
}
}
}
package.json
{
"name": "testcomponent",
"version": "1.0.3",
"description": "A lightweight and easy to use package.",
"main": "./src/components/StandaloneComponent.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [
"NextJS",
"react"
],
"peerDependencies": {
"next": "^12.0.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"prop-types": "^15.7.2"
},
"devDependencies": {
"#babel/core": "^7.16.0",
"#babel/preset-env": "^7.16.4",
"#babel/preset-react": "^7.16.0",
"#babel/preset-stage-0": "^7.8.3",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"next": "^12.0.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"style-loader": "^3.3.1",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1"
}
}
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
I further installed this package in another project like this:
npm install path/to/tgz/testcomponent-1.0.3.tgz
And then imported the component as:
import StandaloneComponent from 'testcomponent'
As a possible workaround, I tried changing the extension of the component file from .js to .jsx and rebuilt the .tgz, but got the same result.
Looking at the error, I feel that babel-loader is unable to convert JSX into JS, which further is causing the import error, but I'm not entirely sure about it.
What could be causing this error?
Any help is appreciated.
Thanks.

The regex rule that you are using to load the JS and JSX file i.e. test:/\.js|jsx$/ seems incorrect in this case. You can fix it in following two ways:
Using capture groups: So when using or you need to capture the both the character sets as /\.(js|jsx)$/. This will consider both js and jsx extension. The earlier version just doesnt match the regex properly because of missing character set.
Using ? occurrence: You can also modify your regex to use the x as an zero or one occurrence using ? matcher. So the other option will be /\.jsx?$/

I believe you need to include the package you installed under include otherwise it looks like Webpack is configured to ignore your node_modules folder:
exclude: /(node_modules)/,
So make sure to let Webpack know what folders in node_modules that you do want to compile
include: [
path.resolve(__dirname, 'node_modules/testcomponent'
]

Related

unable to use scss in storybook in monorepo vue app - module build error lang="scss"

I am adding storybook in an existing monorepo and keep getting error when trying to add scss via <style lang="scss">:
ModuleBuildError: Module build failed (from ./node_modules/style-loader/dist/cjs.js):
TypeError: this.getOptions is not a function
This is the outline of monorepo structure:
package.json
.storybook
|_ main.js
|_ preview.js
client
|_package.json
|_ src
|_components
|_styles
|_stories
The relevant root package.json looks like:
"scripts": {
"build": "yarn workspaces foreach run build",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"devDependencies": {
"#mdx-js/react": "^1.6.22",
"#storybook/addon-actions": "^6.3.7",
"#storybook/addon-docs": "^6.3.7",
"#storybook/addon-essentials": "^6.3.7",
"#storybook/addon-links": "^6.3.7",
"#storybook/addon-postcss": "^2.0.0",
"#storybook/preset-scss": "^1.0.3",
"#storybook/vue3": "^6.3.7",
"#types/mdx-js__react": "^1",
"css-loader": "^6.2.0",
"node-sass": "^6.0.1",
"sass-loader": "^12.1.0",
"style-loader": "^3.2.1",
"vue-loader": "^16.5.0"
}
Here is my .storybook/main.js
const path = require('path');
module.exports = {
"stories": [
"../client/src/stories/**/*.stories.mdx",
"../client/src/stories/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/preset-scss"
],
webpackFinal: async (config, { configType }) => {
config.module.rules.push(
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
}
);
return config;
},
}
In my vue components, trying to use <style lang="scss"> throws the above error. I thought scss would be handled by the changes made in .storybook/main.js, but it's not working, and I'm wondering if it has something to do with the monorepo and two package.json, or if it is something else.
Based on the package.json you've provided, you may be encountering this bug:
https://github.com/webpack-contrib/sass-loader/issues/923
In short, using Vue 3 with sass-loader v11.0.0 or higher without Webpack v5 leads to this error. An interim solution may be to install a known-compatible version of sass-loader:
npm install --save-dev sass-loader#10.1.1
Or, if using yarn:
yarn add --save-dev sass-loader#10.1.1
Updating the storybook's webpack to version 5 as shown here solved the issue:
https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324#upgrade

Jest and Create-react-app: Cannot use import statement outside a module

I have a React Native application where I have some files with some methods that calls certain endpoints. When I try to run Jest is throwing me an error at a local file that is imported.
I have the next package.json:
{
"name": "appName",
"version": "1.0.0",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"#babel/core": "^7.14.2",
"#react-native-community/async-storage": "^1.12.1",
"#react-native-community/netinfo": "^6.0.0",
"isomorphic-fetch": "^3.0.0",
"jest": "^26.6.3",
"jest-fetch-mock": "^3.0.3"
},
"jest": {
"automock": false,
"setupFiles": [
"./jest.setup.js"
]
}
}
And the jest.setup.js file is the following:
import mockRNCNetInfo from '#react-native-community/netinfo/jest/netinfo-mock.js'
jest.mock('#react-native-community/netinfo', () => mockRNCNetInfo)
For the moment, this content is commented, otherwise will throw the same error like in the picture.
I tried to test the same stuff in another project where this #react-native-community/netinfo package wasn't saved in devDependencies but in dependencies and it worked but I am not sure if this is the problem. In this specific project I can't let this package as a dependency, it should be in devDependencies.
I found a lot of issues on this but none of them worked on this case, I don't know what to do anymore. Thank you for your time!
I got this error when I was creating tests with Create-react-app Typescript Jest Axios. Perhaps the following entry in package.json might help.
"jest": {
"transform": {
"^.+\\.[t|j]sx?$": "babel-jest"
},
{ "transformIgnorePatterns": [
"node_modules/(?!#shotgunjed)/"
]
},
I found this answer on internet and it worked for me with some small add-ons but I will post it here maybe will help someone in future:
install babel-jest, babel-preset-env, #babel/runtime and react (the last one might be possible to be necessary only if some other package requires it)
create .babelrc file in root directory and add:
{
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Run your code and should be good to go

Duplicate ReactJS import issue when using npm link to test component before publishing as npm package

I have a simple component like this.
import React, {useState} from 'react';
function MyComponentWithState(props) {
const [value, setValue] = useState(0);
return (
<p>My value is: {value}</p>
)
}
export default MyComponentWithState;
and I want to publish it on NPM as a separate package. so, to do that I prepared package.json and webpack.config.js like below.
package.json:
{
"name": "try-to-publish",
"version": "0.0.1",
"description": "Just a test",
"main": "build/index.js",
"scripts": {
"start": "webpack --watch",
"build": "webpack"
},
"author": {
"name": "Behnam Azimi"
},
"license": "ISC",
"peerDependencies": {
"react": "16.9.0",
"react-dom": "16.9.0"
},
"dependencies": {
"react": "16.9.0",
"react-dom": "16.9.0",
"prop-types": "15.7.2",
"react-scripts": "3.1.1",
"webpack": "4.39.3"
},
"devDependencies": {
"#babel/core": "7.6.0",
"#babel/plugin-proposal-class-properties": "7.5.5",
"#babel/preset-env": "7.6.0",
"#babel/preset-react": "7.0.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-plugin-transform-react-jsx": "6.24.1",
"css-loader": "3.2.0",
"node-sass": "4.12.0",
"sass-loader": "8.0.0",
"style-loader": "1.0.0",
"webpack-cli": "3.3.8",
"webpack-external-react": "^1.1.2"
}
}
webpack.config.json:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.resolve(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
]
},
resolve: {
alias: {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
}
},
externals: {
'react': "commonjs react",
'react-dom': "commonjs react-dom"
},
};
and here is my .babelrc:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": ["#babel/plugin-proposal-class-properties"]
}
These configs work like charm when I publish my component to NPM and install it in my another ReactJs project with `npm install , but my point is the local test!
I want to test this component/lib before publish. To do this I use npm link feature to link my component with my main ReactJS project.
As you saw above, my component is functional and I used hooks too. So when I inject the locally linked lib to my main ReactJs project face this error,
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
My issue is related to the 3td reason. My project uses ReactJs and import it once and also my component will import React! I mean twice React import in one project!.
I also have externals config about react and react-dom in my Webpack config.
What should I do to solve that? Where is my mistake?
Update:
I also tried what #sung-m-kim and #eddie-cooro say but it not worked! Mean, I change the package.json and removed react and react-dom from dependencies and add them to devDpendencies.
I finally solved this problem by these steps.
run npm link inside
<your-library-package>/node_modules/react
also
run npm link inside
<your-library-package>/node_modules/react-dom
then run npm link react and npm link react-dom inside your application root directory
and dont forget to keep react and react-dom as externals in the library
// webpack.config.js
const externals = {
"react": "react",
"react-dom": "react-dom",
}
module.exports = {
.
.
.
externals
}
I solved my issue. I used RollupJS instead of Webpack for bundling as bundle tool.
Here is my rollup.config.js:
import {uglify} from 'rollup-plugin-uglify'
import babel from 'rollup-plugin-babel'
export default {
input: "./src/index.js",
external: ['react', 'react-dom'],
output: {
name: 'test-lib',
format: "cjs",
},
plugins: [
babel({
exclude: "node_modules/**"
}),
uglify(),
],
};
and my package.json:
{
"name": "test-lib",
"version": "1.0.0",
"main": "dist/test-lib.min.js",
"scripts": {
"build": "rollup -c -o dist/test-lib.min.js"
},
"author": "Behnam Azimi",
"license": "ISC",
"peerDependencies": {
"react": "^16.9.0",
"react-dom": "^16.9.0"
},
"devDependencies": {
"#babel/core": "^7.6.0",
"#babel/preset-env": "^7.6.0",
"#babel/preset-react": "^7.0.0",
"rollup": "^1.21.4",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-uglify": "^6.0.3"
}
}
After these changes, npm link worked truly in my ReactJS (Hooks) project.
Notice that it's just a simple Rollup config to show my solution and you can add many kinds of stuff like hot reloading, styles loaders, and many other plugins to the config.
Set the react and react-native packages only inside of the peerDependencies part of package.json, not the dependencies. Also for local development (When your package is not included in any other react projects and you want to to run it locally), you can use the devDependencies field.
I resolve this problem in a typescript react project.
probably, when use the npm link use the react from main app project and the component project.
So, in your package.json remove react from dependencies and/or devDependencies
Check the answer: https://stackoverflow.com/a/62807950/5183591

Using environment variables in React application

Our JavaScript resource just quit, so I, knowing nothing about front-end development, need to get my UI stood up. I'm trying to use an environment variable in the javascript, and it seems like there are 100 different ways to do it.
All I know is this is a react/node app. I start it with npm run start. It needs an endpoint I've defined in my .bash_profile, XREFS_BACK_URL. I thought I could just use process.env.XREFS_BACK_URL, but apparently that has to be defined in some file? I don't know what file or where it should be located.
Sorry to be so clueless - this just landed in my lap and I have to get it up quickly!
Update:
I created a .env file in the root directory. It's one line:
REACT_APP_XREFS_BACK_URL=http://localhost:8080
In my code, I try to use it like so:
var endpoint = process.env.REACT_APP_XREFS_BACK_URL;
console.log("endpoint is " + endpoint);
But the console shows that endpoint is UNDEFINED.
My package.json is here:
{
"name": "bulletin-board",
"version": "0.0.1",
"private": true,
"devDependencies": {
"babel-jest": "^22.4.1",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"jest": "^22.4.2",
"react-scripts": "0.2.1",
"react-test-renderer": "^16.2.0",
"webpack": "^4.6.0"
},
"dependencies": {
"font-awesome": "^4.7.0",
"match-sorter": "^2.2.1",
"namor": "^1.0.1",
"npm": "^6.0.0",
"react": "^15.2.1",
"react-dom": "^15.2.1",
"react-draggable": "^2.2.0",
"react-table": "^6.8.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject",
"test": "jest"
},
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"moduleFileExtensions": [
"js",
"json",
"jsx"
],
"moduleNameMapper": {
"^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"
},
"preprocessorIgnorePatterns": [
"/node_modules/"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/EmptyModule.js"
]
},
"eslintConfig": {
"extends": "./node_modules/react-scripts/config/eslint.js"
}
}
Your app was made with create-react-app. Here are the docs for adding / referencing environment variables: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables
Create a file in the root folder called .env with the contents:
REACT_APP_XREFS_BACK_URL=put_whatever_here
Then access this variable in your JavaScript via:
process.env.REACT_APP_XREFS_BACK_URL
Dont sure, if it actual for you, CNDyson, but I think it might be helpful for newers like me:
npm install --save dotenv
create .env file in the root directory
declare there REACT_APP_**VARIABLE_NAME** = dont forget about REACT_APP
use it like this: process.env.REACT_APP_**VARIABLE_NAME**
Highly recommend to explore these links:
https://create-react-app.dev/docs/adding-custom-environment-variables/ -official documentaion
https://www.npmjs.com/package/dotenv - dotenv
The problem is that usually you want to access the environments variables present on the server that host your application.
With the described solution you will never be able to do docker run --env FOO="value of foo" my-org/my-app
then access FOO in the app like process.env["FOO"].
create-react-app bundle the environment variables that are defined when you run yarn build.
If you want, for example, access the environment variables defined in the docker container check out: react-envs
At first create a file named env.local beside package.json
and try to secure environment variables REACT_APP_YOUR ENV FILE NAME
now set the secured name to your firebase file and push it
as simple as that

Error: File to import not found or unreadable: ~bootstrap/scss/bootstrap

I followed the instructions at getbootstrap.com thinking that everything would just work. It isn't so far :\
Everything seems to be fine until I try to load the page, at which point my Express.js app throws the error
[[sass] error: File to import not found or unreadable: ~bootstrap/scss/bootstrap.
Parent style sheet: .../sass/app.scss at options.error (.../node-sass/lib/index.js:291:26)
I have tried npm install, restarting my server, looking on Google, StackOverflow (yes, I know there are quite a few similar questions, but none of them answer my question), the Bootstrap 4 GitHub issue pages and so far I haven't been able to come up with the answer.
Could it be that I installed the dependencies in the wrong place? (Dev instead of production or vis-à-vis)
Why am I getting this error??
My webpack.config.js file looks like this...
module.exports = {
entry: './src/index.js',
output: {
path: __dirname + '/public',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader', // inject CSS to page
}, {
loader: 'css-loader', // translate CSS into CommonJS modules
}, {
loader: 'postcss-loader', // run post CSS actions
options: {
plugins: function () { // post css plugins, can be exported to postcss.config.js
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader' // compile Sass to CSS
}]
}
]
}
};
My package.json file
...
"scripts": {
"start": "nodemon --exec babel-node server.js --ignore public/",
"dev": "webpack -wd",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"axios": "^0.17.1",
"bootstrap": "^4.0.0",
"ejs": "^2.5.7",
"express": "^4.16.2",
"jquery": "^3.3.1",
"mongoose": "^5.0.0",
"node-sass-middleware": "^0.11.0",
"popper.js": "^1.12.9",
"precss": "^3.1.0",
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"autoprefixer": "^7.2.5",
"babel-cli": "^6.26.0",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"css-loader": "^0.28.9",
"eslint": "^4.15.0",
"eslint-plugin-react": "^7.5.1",
"node-sass": "^4.7.2",
"nodemon": "^1.14.11",
"postcss-loader": "^2.0.10",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.1",
"webpack": "^3.10.0"
}
}
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
};
and inside app.scss I have
#import "custom";
#import "~bootstrap/scss/bootstrap";
When Sass is precompiled by its own CLI, it processes #imports by itself, and sometimes thus doesn’t understand ~ notation. So you can import "node_modules/bootstrap/scss/bootstrap"; in first place and replaced the ~
notation with node_modules/ instead.
I had a similar error
File to import not found or unreadable:
node_modules/bootstrap-sass/assets/stylesheets/bootstrap
Just add "bootstrap-sass": "^3.3.7", to devDependencies at yours package.json, ad run npm update, npm install in your project directory.
For me, I had to change the way I was importing
#import '../../../node_modules/bootstrap/scss/bootstrap';
Then it works
In Rails 7.0.1, after installing using rails new myapp --css=bootstrap, the same error occured. The problem was solved by:
Replacing the line with stylesheet_link_tag in application.erb by: stylesheet_link_tag "application.bootstrap", "data-turbo-track": "reload"
renaming app/assets/stylesheets/application.scss by app/assets/stylesheets/application.bootstrap.scss
Replacing the content by #import '../../../node_modules/bootstrap/scss/bootstrap';
I am not using webpack, but I got the same error when I try to import bootstrap in my scss file like this:
#import 'bootstrap';
It would work if I just import it like this in my case:
#import "../../../../../bootstrap/scss/bootstrap";
But since That is not clean enough to my liking, I found out I could alter my gulp scss task from:
.pipe(plugins.sass())
to:
.pipe(plugins.sass({
outputStyle: 'nested',
precision: 3,
errLogToConsole: true,
includePaths: ['node_modules/bootstrap/scss']
}))
(notice the includePaths section) and now I can just use
#import 'bootstrap';
In my scss file
I am using Solidus and on the very first while getting bootstrap works with the solidus faced the same issue.
The below thing works for me as we have to show the full path where the bootsrap is.
#import "../../../../../node_modules/bootstrap/scss/bootstrap";
I had a similar problem and the fix for me was very basic in the end.
I just had to change "../node_modules/bootstrap/scss/bootstrap"; to "node_modules/bootstrap/scss/bootstrap";.
This happens when you give import from node_modules in any scss file other than the base root style.scss. Try placing it in the root style.scss, it should do it.
If you are having any issue and the answers fail to resolve try this:
Open up your scss file that tries to import.
Rectify the address of the import it might be trying from differnt space.
I solved the problem by:
remove node_modules
npm install
ng serve
works ;)
I just run npm i bootstrap and it worked.
This is similar to my problem, npx mix fail to import bootsrtap with error;
SassError: Can't find stylesheet to import.
Turns out my application root folder name using "#" that caused npx consider as unusual path and fail to import
npx mix error
Solution:
Rename the folder (remove "#")
Good to go
Hope this helps

Categories