After running yarn eject in my react project,I get the 'process' is not defined error when calling registerServiceWorker() in index.js. files in scripts and config directories are not modified.
I get the same error for module variable.
This happens because React uses process.env to determine whether you're in a development or production environment. From getting-started.md:
Note: by default, React will be in development mode, which is slower, and not advised for production. To use React in production mode, set the environment variable NODE_ENV to production (using envify or webpack's DefinePlugin).
For example:
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
});
So to build it with Rollup, you need to replace process.env.NODE_ENV with either "development" or "production" – you can use rollup-plugin-replace for this:
rollup({
entry: 'main.js',
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify( 'production' )
})
]
}).then(...)
Since there is not a lot of details regarding your setup, my answer is going to assume you are using create-react-app which is the most common tool with the concept of an eject command.
You are using a version of CRA that got released before this change, renaming the registerServiceWorker file to serviceWorker and disabling SW by default, so a version <=1.1.5 based on release tags.
The Service Worker of CRA is there to cache your assets so that your application still works offline. If you don't need this feature, one straightforward thing to fix the error would be to disable the registerServiceWorker call, since that's what they did in the template too.
A more painful one would be to actually upgrade your project to CRA 2.x but probably worth it in the long run to keep your ejected project as close as possible to the origin. There is an upgrade guide you could take a look at here.
I myself created a new CRA project using the latest version and ejected it while enabling the service worker and didn't encounter any issue of the sort you are experiencing, so definitely something to consider too.
Related
I deployed a regular React app to Vercel and would like to have a API_BASE_URL environment setting with different values for development, preview and production environments.
Typically, I'd use dotenv npm package with my webpack config setting up the variables for local or production depending on the build by looking into env.local and env.production respectively.
The env.production would look like this:
API_BASE_URL=#{API_BASE_URL}
Then, I'd have my deployment pipeline replace all instances of #{___} with the respective values available in the pipeline.
However, the regular way in Vercel seems to be to make a Next.js app and the environment variables in the project will be automatically available in the process.env variable in the backend code.
Is there anyway for us to have environment variables in a non-Next.js in Vercel?
I'm thinking I have 2 ways forward:
There is actually an easy way 🍀
Create my own build and deployment pipeline to replace the #{___} placeholders and deploy using vercel deploy command.
Had a similar issue on my SPA (React + Webpack) app on deployed on Vercel. This is what worked for me.
https://github.com/mrsteele/dotenv-webpack#properties
webpack.config.js
const Dotenv = require('dotenv-webpack');
module.exports = {
// OTHER CONFIGS
plugins: [
new Dotenv({
systemvars: true
})
]
};
Doing it like this I was able to read env vars from:
Vercel build runtime (ex: VERCEL_ENV)
.env file in my src folder
Env variables defined in Vercel console
Initially, I was overlooking an important fact. Vercel deploys builds and deploys changes in the same step.
2 commits in preview branch which are merge them both to main in 1 single commit: that's a totally new thing (a new build is created for every single commit in every environment).
This goes against the build once, deploy to multiple environments principle but I suppose Vercel's team considered that in their quest to make the development process as simple as possible.
Anyway, I worked out 2 solutions:
In the build command, insert the environment variables e.g. in the package.json:
scripts: {
"build": "webpack --env production --env VERCEL_ENV=$VERCEL_ENV"
}
Create my own build and deployment pipeline and then deploy to vercel using vercel deploy command. It also works but I think I'm going to stick to the option for simplicity, at least in the meantime.
I want to deploy a React app (made with Create React App) + a Node server with Heroku,
I did it, but my app can't fetch data from the server,
In production, my process.env.NODE_ENV is equal to "development" which causes a lot of wrong stuff in my code,
Do you know what can put process.env.NODE_ENV always at "development"? At the build, this environment variable is supposed to switch to "production", no?
Your package.json add this.
"scripts": {
"start": "export NODE_ENV=development; {your start code}",
Your env variables can be set per environment, in this case in Heroku: https://devcenter.heroku.com/articles/config-vars#using-the-heroku-dashboard
If you want to make sure build always runs with the same NODE_ENV, you can follow #seunggabi 's answer. I'd also use cross-env to make it work cross-platform in such case. Per-process variable can be forced on heroku-postbuild task (after &&).
You can take control of your Environment with env-cmd. They make easy to switch between your local development, testing, staging, UAT or production.
You can refer to this article. This is was very helpful for me
I have been trying to come up with an elegant solution to share code between two projects that are closely related to each other.
I have a React web app which simply includes all of the client code and I have an Express app which serves the React web app, but it also acts as an API. Because I use Typescript for both projects, I want to reuse some types. To accomplish that, I created a shared project.
My current folder structures is as follows:
web-app
shared
server
Now I want to link the web-app and server projects with my shared project, but there are some restrictions:
This shared folder should not be uploaded to npm.
I have to be able to still deploy everything with Heroku (which rules out npm link I believe).
I would prefer not to eject my React project.
I am not sure whether my current structure of projects allows the functionality I need, so feel free to also suggest other folder structures.
You can use yarn workspaces for that kind of purpose,
There's a minimal working boilerplate I have created exactly for that kind of configuration:
https://github.com/rok-tel/ts-express-react
take a look at ./packages/shared folder which is consumed both by server (express) and client (react)
Consider use Nx - https://nx.dev/
This is an awesome framework to manage monorepos.
Use their React application boilerplate for the client side project
Use their express project boilerplate to create the API
Use their shared code package boilerplate to create shared code package
Docs for creating the shared code package:
https://nx.dev/l/r/tutorial/07-share-code
If you are using create-react-app to create the web-app then you can easily use NODE_PATH environment variable to do absolute imports without creating node modules.
Create a .env file at the root level (same level as package.json of web-app directory)
Set an environment variable, NODE_PATH to shared/ (NODE_PATH=shared/)
Now instead of doing something like
import { editUser } from ‘../../../shared/actions’;
you can use
import { editUser } from ‘shared/actions’;
Fixing ESLint
Install eslint-plugin-import to prevent eslint from throwing import errors. And update your .eslintrc file as
{
"settings": {
"import/resolver": {
"node": {
"moduleDirectory": ["node_modules", "shared/"]
}
}
}
}
Fixing Flow
Add the following content to your .flowconfig file
[options]
module.system.node.resolve_dirname=node_modules
module.system.node.resolve_dirname=shared
Say the webpack config is as follows
{
entry: path.join(__dirname, 'src', 'index.js'),
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
Now the build from webpack is
and the build from react-scripts build ( static contains css, js and media in seperate folders )
Question: Is there any specific advantage of webpack over react-scripts build? ( including but not limited to performance )
NOTE: package.json is edited to achieve this.
Webpack is a general purpose bundler, with applications beyond React. Before create-react-app, the web was full of examples of setting up a brand new React project which uses webpack as the bundler. It is extremely flexible and can handle things including and beyond what a React application would need. It works for Angular, Vue, NodeJS and even Web Assembly.
But it used to take a while to setup. You will need to understand its working and configure it so that you can transpile your React+ES6 code into plan-vanilla JS. You would need to decide the output structure you like and configure webpack for it. And then also add hot-module-reloading and code-splitting support yourself. During this, you will also need to add other plugins required by Webpack to support all the above :).
This naturally caused some fatigue with folks who were starting with React.
So facebook created cra which internally uses webpack, pre-configured to include all the nice tools to take care of these basics and help you focus on the React part of your code. It hides webpack from you as much as possible, otherwise the build process may break if the configuration is changed by the user.
With that aside, the structural conventions which cra uses should not be having any performance impact over a bare-bones webpack setup. It's just a convention.
Your question should then be, when would I use create-react-app and when would I use Webpack?
As a beginner you might want to stick to cra as you focus on your react app. Eventually there would come a time where what you want to do is not supported by the webpack configuration cra is managing under the hood. A very common example is if you want to write a component library to reuse in other apps. This cannot be done by cra (it's about the whole app :)). You can then switch over to webpack and start learning it.
react-scripts hides all of the webpack configs behind the scenes. The advantage of this is it makes it cleaner and since create-react-app is regularly updated, its easy to stay up to date with React, Webpack, and Babel. The community automatically fixes the issues for you.
In terms of performance, should be the same regardless with react-scripts or with webpack.
Advantages of running only webpack:
Full control of your environment
Can do custom things like server-side rendering easily (still possible with create-react-app
Knowledge of webpack as a skill
Disadvantages of webpack only
Full in charge updating and maintenance of webpack (some webpack versions are not backward compatible or future compatible)
Can be intimidating and can be a headache if you are trying to learn to react quickly.
If you want to customize create-react-app, here is some info
https://auth0.com/blog/how-to-configure-create-react-app/
Here is server-side rendering with create-react-app
https://hackernoon.com/server-side-rendering-with-create-react-app-1faf5a9d1eff
TLDR: Use create-react-app / react-scripts if you want to go to 0-100 as quick as possible for whatever reason
Use just webpack if you enjoy messing around under the hood
I try and not resort to StackOverflow too often, but this is driving me nuts. I have a create-react-app which I am trying to wrap into the electron framework. I discovered a tutorial online which basically has you create everything from scratch with a barebones webpack config setup, and it works, but only when starting up the webpack dev server first before starting the electron application. This is redundant when you want to package the application, as the package.json start script only runs one command, which is "electron .". So how do I go about including the static production files of my React app into Electron? I have tried it several time before without any success, and the closest I came was pointing (within the main.js entry file for electron) to my static react index.html file. Only problem was, because it was a production build, everything was minified. For the resources within this file to load correctly, I had to manually remove all the first "/" from any src url (you can see how quickly that would become quite cumbersome with larger apps).
So I guess my actual question is:
How do I "serve" the static files of my react application so electron loads it correctly?
(Do also take note that I ejected the application in order to make use of css modules)
PS: Link to the react-electron tutorial - https://medium.com/#Agro/developing-desktop-applications-with-electron-and-react-40d117d97564
By the logic of the tutorial you have to put the static files into the /public folder assets will be loaded relativ from the html document, but this will result in the same issue with paths where you had to manually remove all the first "/" from any src url. The URL's need to be correct when build.
That beeing said i think the tutorial encourages bad practice for electron development, and i think that is part of the issue you have.
You would never start electron from the node_modules path. You do this by electron ./path/to/electronscriptsfolder this will load a index.js/main.js in this folder containing the app definitions.
Webpack is the wrong approche for electron because, you don't need bundling and when packing electron, webpack tends to generate issues with native packages and paths (As you described yourself). You would use electron-compile or a gulp pipeline to do it by your electron specific logic.
There is no babel configuration given even though they are super important for electron. Basically you need two bable configs, one for electron running on a specific node version and one for the chromium running on a specific implementation.
Here an example for electron 1.8.1 which uses Chrome 59 and Node.js 8.2.1
Renderprocess
{
"presets": [
["env", {
"targets": {
"chrome": "59"
}
}]
]
}
Mainprocess
{
"presets": [
["env", {
"targets": {
"node": "8.2.1"
}
}]
]
}