Sharing components in yarn workspaces (next and tailwindcss) - reactjs

I've got a frontend (next.js) which has tailwindcss installed (config, postcss, ...) and everything works.
I've made another package (ui) which has the following package.json
{
"name": "ui",
"version": "1.0.0",
"private": true,
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"autoprefixer": "^10.3.2",
"postcss": "^8.3.6",
"tailwindcss": "^2.2.7"
}
}
The problem is when is serve the ui locally everything works fine (the UI sees the styles of the component), but when deployed to vercel, the component has no styles in it.
The component (ui):
import React from 'react';
const Example = ({children}) => <button className='bg-blue-500 py-1 px-2'>{children}</button>
export default Example
And my next config (frontend)
const withTM = require('next-transpile-modules')(['bar'])
module.exports = withTM()
Is there a way of sharing the same tailwind.config.js ? Or anything to make it work.
Steps that I have made:
created the workspace
added frontend package (next, and then i installed tailwind with all the steps from their docs)
added the ui package (installed the peerDependencies, see above)
created the component
added the ui package as a dependency in the frontend, yarn install, and then imported the component
yarn dev, and the styles are applied locally.
deployed to vercel, the button has only the children , no styles
UPDATE:
The problem is caused by the purging process at build time.
Is there any way to specify in the tailwind config to purge also the ui package?
UPDATE2:
I've tried to add the package (i've renamed it to "#example/ui") to the purge in next.config.js
module.exports = {
purge: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./node_modules/#example/ui/src/*.{js,ts,jsx,tsx}'
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
The code in the UI package is inside of the src, has only the index.tsx file. I mention, locally still works fine.

Solved it !
In the purge array , I needed to add the node modules from the root of the project, not of the frontend

Related

unable to use my component library based on Material UI with a nextjs application (both typescript)

On one side I have a component library using react, mui and emotion as peerDep.
package.json
"peerDependencies": {
"#emotion/react": "^11.10.5",
"#emotion/styled": "^11.10.5",
"#mui/icons-material": "^5.10.15",
"#mui/material": "^5.10.15",
"react": "18.2.0",
"react-dom": "18.2.0"
}
rollup config (note the regexp for #emotion and #mui)
external: [
'react',
'react-dom',
/#emotion\/.*/,
/#mui\/.*/,
],
output: [
{
file: 'dist/index.cjs.min.js',
format: 'cjs',
sourcemap: true,
plugins: [terser()],
},
{
file: 'dist/index.esm.min.js',
format: 'esm',
sourcemap: true,
plugins: [terser()],
},
],
plugins: [
resolve({ browser: true }),
...
typescript({ tsconfig: './tsconfig.json' }),
],
},
Lib is published with npm.
On the other side, I have an application (nextjs and storybook, webpack5)
Nothing special on the config on this side.
When I run storybook, it works fine.
But when I run dev, I get this error:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
at Bidon (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/#msio/common-frontend/dist/index.cjs.min.js:629:18)
at div
at /home/smallet/Dev/sandbox/spike-nextjs/node_modules/#emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js:51:25
at Stack (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/#mui/material/node/Stack/Stack.js:111:49)
at Home (webpack-internal:///./pages/index.tsx:32:81)
at Layout (webpack-internal:///./components/Layout/Layout.tsx:14:19)
at InnerThemeProvider (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/#mui/system/ThemeProvider/ThemeProvider.js:19:39)
at ThemeProvider (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/#mui/private-theming/node/ThemeProvider/ThemeProvider.js:39:5)
at ThemeProvider (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/#mui/system/ThemeProvider/ThemeProvider.js:38:5)
at App (webpack-internal:///./pages/_app.tsx:27:16)
at StyleRegistry (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/styled-jsx/dist/index/index.js:449:36)
at PathnameContextProviderAdapter (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/next/dist/shared/lib/router/adapters.js:60:11)
at AppContainer (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/next/dist/server/render.js:289:29)
at AppContainerWithIsomorphicFiberStructure (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/next/dist/server/render.js:325:57)
at div
at Body (/home/smallet/Dev/sandbox/spike-nextjs/node_modules/next/dist/server/render.js:612:21)
I tried to change the tsconfig file but didn't change anything
I tried to put only #mui and not #emotion as a peer dependency, but it didn't work.
First for the bundle size it is better to have those libs as peer dependency,
but moreover, I have a ThemeProvider initialized with a custom theme and I want it to be shared between lib and app.
I spent a lot of time looking for something wrong in the Theme, but in fact, the error was here because it is the first component imported from my lib.
I added a dummy component with just a div => the app works fine.
But as soon as I add an import on #mui lib, like :
import Paper from '#mui/material/Paper';
I get the crash.
It works with storybook.
I also created a simple react app and it works, so it doesn't seem to be on the side on the library.
I suppose it comes from some config on Nextjs side.

React compiler end up with Unexpected token <

I am beginner in React and I am struggling with compiler error. Let me introduce my situation. I have two independent React applications:
App A - Big ERP
App B - "Plugin" to the App A
I supposed I will develop App B as an independent application. Then, I will install it to the App A (using npm install git#github.repo/...) once I finish development of the App B. I expected I will call components from App B within the App A source code. Everything went fine until I run the compilation. I am receiving:
SyntaxError: /frontend/node_modules/connector_frontend/src/views/Connector/FormView/index.js: Unexpected token
In my /frontend/node_modules/connector_frontend/src/views/Connector/FormView/index.js there is following code:
const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
<p>Hello world</p>
)
}
export default ConnectorFormView;
Error is ocuring at the position of <p>.
I call this functional component from App A (frontend/src/views/Connector/ConnectorNewEditView/index.js) like this
import ConnectorFormView from "connector_frontend/src/views/Connector/FormView";
const ConnectorNewEditView = () => {
return (<ConnectorFormView AppValues={appValues} secureFetch={secureFetch} />)
}
export default ConnectorNewEditView;
I tried to return just a plain text from the ConnectorFormView component like this:
const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
'Hello world'
)
}
export default ConnectorFormView;
and it was compiled successfully, but once I return a JSX from the ConnectorFormView component the compiler get crashed.
Can anyone explain the source of this error please?
I successfully figured out the source of this problem and also I found a solution. I expected I can reuse however React component implemented in JSX. I expected, the only requirement is to install it, resp. download it in JSX form to my project using NPM. It's FALSE.
According to my research, I can reuse React components compiled from JSX to ES only. It is achievable using Babel. Another very important requiremen, it should not by installed as React application as I installed it. It must be installed as a NPM package with clearly defined set of exported components.
I found this paper https://levelup.gitconnected.com/publish-react-components-as-an-npm-package-7a671a2fb7f and I followed it step by step and finally I achieved desired result.
I can very briefly mention steps which I performed:
Implemented my custom component (mentioned above)
const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
<p>Hello world</p>
)
}
export default ConnectorFormView;
Added the component to /src/index.js file in order to export it for host App
import ConnectorFormView from './components/ConnectorFormView';
export { ConnectorFormView };
Installed Babel and all needed presets
npm install --save-dev #babel/core #babel/cli #babel/preset-env
npm install -save #babel/polyfill
configured Babel - created file /babel.config.json with following content
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
],
"#babel/preset-react"
]
}
Added new script to the package.json to compile React components to ES:
"build": "rm -rf dist && NODE_ENV=production babel src --out-dir dist --copy-files";
Executed npm run build to compile React components to ES. Compiled components are located in new dist folder.
Adjusted package.json that looks like this now
{
"name": "my_react_components",
"version": "0.1.0",
"private": true,
"description": "Some description",
"author": "Lukas",
"main": "dist/index.js",
"module": "dist/index.js",
"files": [ "dist", "README.md" ],
"dependencies": {
.
.
},
"scripts": {
"build": "rm -rf dist && NODE_ENV=production babel src--out-dir dist --copy-files",
.
.
.
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"#babel/cli": "^7.17.10",
"#babel/core": "^7.18.5",
"#babel/preset-env": "^7.18.2"
}
}
Pushed dist folder to the git.
Installed repository to the host project using NPM
npm install https://github.com/my_custom/react_component.git
Import and use the component from installed git repo
import ConnectorFormView from 'my_react_components';
function App() {
return (
<ConnectorFormView />
);
}
export default App;
Actually that's all. I very recommend to see the attached paper at the beginning of this answer because I maybe skipped very important info for you.

How to resolve "Cannot use import statement outside a module" in jest

I have a React application (not using Create React App) built using TypeScript, Jest, Webpack, and Babel. When trying to run yarn jest, I get the following error:
I have tried removing all packages and re-adding them. It does not resolve this. I have looked at similar questions and documentation and I am still misunderstanding something. I went so far as to follow another guide for setting up this environment from scratch and still received this issue with my code.
Dependencies include...
"dependencies": {
"#babel/plugin-transform-runtime": "^7.6.2",
"#babel/polyfill": "^7.6.0",
"babel-jest": "^24.9.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-test-renderer": "^16.11.0",
"source-map-loader": "^0.2.4"
},
"devDependencies": {
"#babel/core": "^7.6.0",
"#babel/preset-env": "^7.6.0",
"#babel/preset-react": "^7.0.0",
"#types/enzyme": "^3.9.2",
"#types/enzyme-adapter-react-16": "^1.0.5",
"#types/jest": "^24.0.13",
The component's import lines...
import * as React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/pages";
import {
Footer,
Header,
Navigation,
} from "./components/shared";
The test file....
import * as React from "react";
import * as renderer from "react-test-renderer";
import App from "../App";
it("Renders the Footer correctly", () => {
const tree = renderer
.create(<App />)
.toJSON();
expect(tree).toMatchSnapshot();
});
I expected to be able to use named imports in my components without my tests blowing up. It appears to fix the issue if I only use default imports through my solution, but I would prefer to not go that route.
Also using Babel, Typescript and Jest. Had the same failure, driving me crazy for hours.
Ended up creating a new babel.config.js file specifically for the tests. Had a large .babelrc that wasn't getting picked up by jest no matter what i did to it. Main app still uses the .babelrc as this overrides babel.config.js files.
Install jest, ts-jest and babel-jest:
npm i jest ts-jest babel-jest
babel.config.js (only used by jest)
module.exports = {presets: ['#babel/preset-env']}
jest.config.js
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
}
};
package.json
"scripts": {
"test": "jest"
Use Babel to transpile those JS Modules and you'll be able to write your tests with es6.
Install Babel/preset-env
npm i -D #babel/preset-env
Create a babel configuration file with the preset
//babel.config.js
module.exports = {presets: ['#babel/preset-env']}
I solved this by migrating the .babelrc file to babel.config.js! Shocker.
For future references,
I solved the problem by using below jest config, after reading Logan Shoemaker's answer.
module.exports = {
verbose: true,
setupFilesAfterEnv: ["<rootDir>src/setupTests.ts"],
moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
moduleDirectories: ["node_modules", "src"],
moduleNameMapper: {
"\\.(css|less|scss)$": "identity-obj-proxy"
},
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/file.js",
}
};
try this thing if you are using babel 6
Adding #babel/plugin-transform-modules-commonjs in the plugin section of babel.config.js
or
For my case import issue was due to the react file drop by adding that to transformIgnorePatterns
"transformIgnorePatterns": ["/node_modules/(?!react-file-drop)"]
I fixed it by simply appending the pattern after the run statement in package.json runner
{
"scripts": {
...
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!my-library-dir)/'"
...
Then, just run npm test
Solution: my named imports were coming from index.js files and I believe ts-jest needed them as index.ts files (I'm using Typescript). If anyone else runs into this error, couldn't hurt to check if you derped your file extensions.
I wasted a lot of time on this, unfortunately, but I learned a lot about webpack configurations and Babel.
Add your test script in package.json with Node experimental feature: --experimental-vm-modules
In this way you won't require babel or other dependencies.
Examples:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest"
If you get this error: zsh: command not found: jest, try with node passing jest.js like this:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node --trace-warnings' node node_modules/jest/bin/jest.js --detectOpenHandles"
I'm surprised that none of the answers does not give an elegant solution:
jest.config.js
module.exports = {
...,
globals: {
"ts-jest": {
isolatedModules: true,
},
},
};
This compiles each file separately therefore avoiding the no exports issue.
Create .babelrc on the main directory and add this code and install these packages
#babel/core, #babel/preset-env and #babel/preset-react
{
"presets": [
[
"#babel/preset-env",
{
"modules": "commonjs"
}
],
"#babel/preset-react"
]
}
Matching file extensions:
I importing a file named Todo.jsx in the root as ./src/Todo/. Whenever I changed it to Todo.js the problem went away.
Disclaimer: I'm not sure what the requirement is for having your file extension as jsx vs js for your components. It did not effect me at all, but I could imagine it could mess with intellisense or snippets.
For me renaming file to babel.config.js worked.
Here is my config file an NX project using next with Typescript along with Twin-macro
// .babelrc.js >> babel.config.js
module.exports = {
presets: [
[
"#nrwl/react/babel",
{
"runtime": "automatic",
"targets": {
"browsers": [">0.25%", "not dead"]
},
"preset-react": {
runtime: "automatic",
importSource: "#emotion/react",
},
}
],
'#babel/preset-env',
'#emotion/babel-preset-css-prop',
'#babel/preset-typescript'
],
plugins: ['#emotion', 'macros', '#babel/plugin-transform-runtime', 'react-docgen'],
}
Also, please note even updating package.json works,
https://kulshekhar.github.io/ts-jest/docs/getting-started/presets/#basic-usage
// package.json
"jest": {
// Replace `ts-jest` with the preset you want to use
// from the above list
"preset": "ts-jest"
}
I encountered the same problem with Typescript, Jest, and VueJS/VueCli 3. The normal build has no problem. only happens for Jest. I struggled for hours by searching. But no answer actually works. In my case, I have a dependency on my own typescript package which I specific "target": "es6" in the tsconfig.json. That's the root cause. So the solution is simply to change the dependent's (Not the same project) back to es5 tsconfig.json:
{
"compilerOptions": {
"target": "es5",
...
},
...
}
Personnaly I followed #ajwl setup but discovered that jsdom-worker inside setupFiles: section of jest.config.js was triggering that same error. Once removed, my tests were passing.
P.S. my babel.config.js is a bit different, since I have a Vuejs (v2) SPA (bundled with Vitejs):
module.exports = {
plugins: ['#babel/plugin-transform-modules-commonjs'],
presets: [['#babel/preset-env', { targets: { node: 'current' } }]]
}
The problem is likely that jest doesn't support esmodules natively. Which can cause problems if youre typescript target is es6 or greater.
If you are testing the built typescript output, you could simply add a module=commonjs flag while transpiling. That way, your code can run with es6 or greater and still work with Jest.
"scripts": {
"test": tsc --module commonjs && jest {your-output-folder}/
}
What's great about this is that I didn't have to add any additional babel dependencies or special jest runners :)
I solved it by changing my tsconfig.json to a compatible native output
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
It is not ideal in every scenario but you might be okay with this.
All I had to do, was simply updating the package #babel/preset-env in the dev dependencies to the latest version
// package.json
"#babel/preset-env": "^7.18.6"
None of the answers helped me, what did help me was making sure my NODE_ENV was set to test, since babel config is per NODE_ENV using the wrong NODE_ENV by accident that is not configured in babel config will mean you wont be using babel and the typescript files will not be transformed.
It took me couple of hours to figure this one out so i hope it will save someone else the time it took me.
Don't know why and how but how I solved the problem was really interesting.
Just add __mocks__ folder in your src folder and create an empty file inside __mocks__ named axios.js
I discovered that this error might be triggered when you try to load a dependency that is made for the browser and, thus, cannot work with jest (node).
I had a lot of trouble solving this issue for #zip.js/zip.js lib. But I could do it like that:
Here is my jest.config.js. Adapt it to your need. The trick here is the moduleNameMapper that will make all imports to zip.js point to the file __mocks__/#zip.js/zip.js I created in my root folder.
export default {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'#zip.js/zip.js': '<rootDir>/__mocks__/#zip.js/zip.js',
},
}
And here is what I have in <rootDir>/__mocks__/#zip.js/zip.js file:
module.exports = {}
Too late for this answer :)
After trying all the possible solutions, this worked for me:
The solution, that works for me:
create a file named jest/mocks/#react-native-firebase/crashlytics.js
export default () => ({ log: jest.fn(), recordError: jest.fn(), });
create a file named jest/jestSetupFile.js
import mockFirebaseCrashlytics from './mocks/#react-native-firebase/crashlytics';
jest.mock('#react-native-firebase/crashlytics', () => mockFirebaseCrashlytics);
in package.json add
"jest": { "setupFiles": ["./jest/jestSetupFile.js"] },
I needed to do a couple things to get this to work for me
Rename my .babelrc to babel.config.js and make a little change:
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"corejs": "3.26",
"useBuiltIns": "usage"
}
],
"#babel/preset-react"
],
...
}
// babel.config.js - This still works fine with webpack
module.exports = {
"presets": [
[
"#babel/preset-env",
{
"corejs": "3.26",
"useBuiltIns": "usage"
}
],
"#babel/preset-react"
],
...
}
Add the following to my jest config file:
{
...
"transformIgnorePatterns": [
"node_modules/(?!(react-leaflet-custom-control)/)"
],
...
}
Where react-leaflet-custom-control was the package causing issues for me.
If you're using TypeScript, and you have a tsconfig.json file, try removing "module": "esnext" if you're using it
Running npm ci fixed this problem for me.

Material-UI ThemeProvider Invalid hook call when building an ES6 module using rollupJs

the problem here is quite simple, really.
I'm currently working on an app that I want to split parts into components.
I decided to create a boilerplate to create modules using rollupJS in order to export these modules into my core app using NPM.
I stumbled upon a problem while using MaterialUI in my dependencies, and while using withStyles and ThemeProvider from the module.
I've currently tried :
building the module as cjs (commonJS) instead of es6 module, not working,
passing material-ui as smthg else than peerDependencies, little to none effects,
ran different scenario using rollup (changing orders, using externalPeerDependencies plugin and so on) but I don't understand rollup that much, so that's a dead end to me, and I'd like guidance on that,
Erasing the ThemeProvider and/or withStyles keys are solving the problem, so at least I know there's a problem here. (and the error message on my main app is pointing towards a function directly in my module/node_modules, on a function using useContext() from material-ui)
Using MuiThemeProvider instead of ThemeProvider does not solve the problem
Using an earlier version of Material UI and/or ReactJS is a no-go in this case
The message itself is the infamous Invalid hook call from react
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
See blabla for tips about how to debug and fix this problem.
As you can see here in the code :
"devDependencies": {
...
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.5.1",
"sass-loader": "^7.1.0",
"#material-ui/core": "^4.0.0",
"style-loader": "^0.23.1"
},
"dependencies": {
"babel-core": "^7.0.0-bridge.0",
"prop-types": "^15.7.2"
},
"peerDependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-proptypes": "^1.0.0",
"#material-ui/core": "^4.0.0"
}
I've put my dependencies as peers to avoid conflicts between React versions (and material ui too, but it seems to have little to none effects). I've truncate the devDependencies to avoid the full list here.
my rollup config :
export default {
input: 'src/index.js',
output: [{
file: pkg.main,
format: 'es'
}],
// All the used libs needs to be here
external: [
'react',
'react-dom',
'react-proptypes',
'#material-ui/core',
'#material-ui/styles',
'prop-types'
],
plugins: [
resolve({ preferBuiltins: false }),
postcss({
plugins: [
postcssModules({
getJSON (id, exportTokens) {
cssExportMap[id] = exportTokens;
}
})
],
getExportNamed: false,
getExport (id) {
return cssExportMap[id];
},
extract: 'dist/styles.css',
}),
json({
'include': 'node_modules/**'
}),
babel({
presets: ["#babel/preset-env", "#babel/preset-react"],
plugins: ["#babel/plugin-proposal-class-properties", "#babel/plugin-proposal-export-default-from"],
exclude: [
'node_modules/**'
],
}),
commonjs({
include: 'node_modules/**',
namedExports: {
'node_modules/react-is/index.js': ['ForwardRef', 'isValidElementType']
}
})
]
}
and my code which if I suppress ThemeProvider I have no error on it :
import { render } from 'react-dom'
import React, { Component } from 'react'
import { MuiThemeProvider } from '#material-ui/core/styles'
const props = {}
class Boilerplate extends Component {
render() {
return (<div className='title'>Hello world</div>)
}
}
render(<MuiThemeProvider><Boilerplate /></MuiThemeProvider>, document.getElementById('app'));
Any help that can solve this problem is really, really much appreciated !
For anyone wondering what was the problem,
Yarn and NPM, even while listing react calls in the console, where not listing the react version used by the module linked. So I thought there was only one react version. Using PeerDependencies did not solve the problem either.
using https://github.com/facebook/react/issues/13991#issuecomment-496383268 I was able to use an Alias in my main app and it's solving the duplicate react call in the module.

React project using parcel bundler instead of Webpack

We can start with React project using command create-react-app. But when we use this command we don't get idea about how it's bundle and pack all types of files using Webpack.
So I tried to build react app without create-react-app command using Webpack 4 and Babel 7 and I succeed.
Now I want to do same app using parcel bundler. as I read on different blogs I got an idea that parcel is easy then web pack and it's truly zero configuration set up.
My project structure is
- src
|- components
|- styles
|- index.html
|- index.js
- package.json
This is simple project to start with parcel bundle so I've not add Redux or routing yet.
What I want to achieve is
1). As aspected React app should be run in browser using parcel bundler.
2). I want to use absolute paths when importing JS files.
3). I want to enable hot reloading.
After few minutes of research on net I find the solution and it's truly zero configuration with parcel bundler.
we just need to add 2 commands in package.json file 's script section.
project structure is
- src
|- components
|- styles
|- index.html
|- index.js
|- App.js
- package.json
- .babelrc // this file will use to setup absolute path when import files
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from './App';
import "./style/index.scss";
ReactDOM.render(<App />, root);
index.html is same file as create-react-app provide we just need div with id.
App.js
import React, { Component } from "react";
import Count from "#components/Count"; // here I used absolute path. check .bablerc file
export default class App extends Component {
render() {
return (
<>
<div>this is App component</div>
<Count />
</>
);
}
}
components/Count.js
import React, { Component } from "react";
export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<>
count is: {this.state.count}
<br />
<button onClick={(prevState) => {this.setState({
count: prevState.count + 1
});
}}
>
Add count
</button>
</>
);
}
}
style/index.scss
body {
background-color: red;
color: #fff;
text-align: center;
font-size: 40px;
}
note that we don't need to manually install node-sass package to use
scss. parcel will handle for you.
package.json
{
"name": "react_parcel",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "parcel ./src/index.html",
"build": "parcel build ./src/index.html/"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"parcel-bundler": "^1.12.3",
},
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}
.bablerc
{
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"alias": {
"#components": "./src/components"
}
}
],
["react-hot-loader/babel"]
]
}
here we add alias for components folder so when we need to import any file from components folder we don't need to write relative path.
npm run dev
your server will start on localhost:1234
I solved 2 issues but still need to figure out how to use hot reloading so if you guys have any idea related hot reloading please answer it.
for production build: npm run build

Resources