nextjs - next build with NODE_ENV=development - reactjs

I'd like to build my nextjs project as development mode.
and I tried like it
package.json
{
...
"scripts": {
"dev": "next",
"build:dev": "set NODE_ENV=development & next build",
"build:prod": "set NODE_ENV=production & next build",
"start:dev": "set NODE_ENV=development & next start",
"start:prod": "set NODE_ENV=production & next start"
}
...
}
next.config.js
module.exports = withSass({
env: {
baseUrl: process.env.NODE_ENV === "development" ? "devServerURL": "prodServerURL"
}
});
but I couldn't achieve what I want.
so, I tried with some change.
package.json
"scripts": {
"dev": "next",
"build": "next build",
"start:dev": "set NODE_ENV=development & next start",
"start:prod": "set NODE_ENV=production & next start"
}
but it also doesn't work.
How can I build the next with development mode?
Thanks in advance.
EDIT
My OS is Windows 10.

UPDATE 2022-11-23:
See how-to-set-environment-variables-from-within-package-json.
In short:
"start:dev": "NODE_ENV=development next start"
You might need cross-env (on Windows ? I don't know):
"start:dev": "cross-env NODE_ENV=development next start"
More specific documentation is now available (and maybe requirements also have changed, or maybe not):
environment-variable-load-order:
... Note: The allowed values for NODE_ENV are production, development and test.
non-standard-node-env:
... only permitting three (3) values:
production: When your application is built with next build
development: When your application is ran with next dev
test: When your application is being tested (e.g. jest)
ORIGINAL ANSWER:
See issue #9123, (Oct 18, 2019) :
NODE_ENV is a reserved environment variable that cannot be changed.
The only valid values are production, development, and test.
If you need your app behavior to change in different production
environments, please use a different variable like APP_ENV.
And issues #17032 (Sep 12, 2020):
process.env.NODE_ENV only has 2 possible values development and
production. If this is not set to that value you'll run into all kinds
of library edge cases (especially in node_modules) where you get
severely de-optimized results. E.g. if you run a performance test
you'll get significantly worse results if process.env.NODE_ENV is not
set to production

We solve it from our pipeline. Basically, when we build the image:
copy ".env.%ENVIROMENT%" to "./.env"
Then, if it finds a .env file, it always uses that.
You need to configure the value of %ENVIROMENT% in each pipeline you use for production or development (or make it recognize which pipeline it is).
If you have different steps during the image build, you could even use different environments for building and running.
Dockerfile example (this is not the best Dockerfile):
FROM node:16.17.3-buster-slim as build
WORKDIR /app
COPY package.json yarn.lock ./
COPY . ./
COPY .env.%ENVFILE_NEXT% ./.env
RUN yarn
RUN yarn build
FROM node:16.17.3-buster-slim as dst
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/next-i18next.config.js ./next-i18next.config.js
#
COPY .env.%ENVFILE_NEXT% ./.env
EXPOSE 3000
CMD ["yarn", "start"]

Related

I use npm run build-css to update my tailwind css. Is there a way to make this done automatically?

Every time I add a new class in the className of a react component, i need to go to the terminal and type npm run build-css in order for the classes to take effect.
What npm run build-css does is "build-css": "npx tailwindcss build -o src/styles/main.css",.
Is there a way to not have to run the above command on every UI change I do? I have used tailwind css in nextjs by following the official guide and it updates on its own whenever I do a change in the UI.
My scripts:
"scripts": {
"prod": "cross-env NODE_ENV=production webpack --mode production --config webpack.build.config.js && electron --noDevServer . ",
"start": "cross-env NODE_ENV=development webpack serve --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development && craco start",
"build": "cross-env NODE_ENV=production webpack --config webpack.build.config.js --mode production && craco build",
"watch-css": "npx tailwindcss build -i src/styles/index.css -o src/styles/main.css --watch",
"build-css": "npx tailwindcss build -o src/styles/main.css",
"package-m1": "electron-forge package --arch=arm64 --platform=darwin",
"package-intel": "electron-forge package --arch=x64 --platform=darwin",
"package": "npm run package-m1 && npm run package-intel",
"postpackage": "electron-packager ./ --out=./builds"
},
You should be able to combine this command into your normal run command, I'm not sure if you're using a framework or not but if you go into you package.json and look at your normal run/start command you can edit that to include the tailwind build. Depending on if you are using a unix or windows environment it will be slightly different. For react it would look like this(I don't remember syntax for nextjs)
"start": "npx tailwindcss build -o src/styles/main.css && node scripts/start.js"
The above would be for windows and the below for unix
"start": "npx tailwindcss build -o src/styles/main.css & node scripts/start.js"

Dockerizing react for production not working

I have created a Dockerfile and Docker-compose.yml for containerzing my create-react-app to production. My problem of understanding is how should I create the production build if the scripts that are needed to run the command are dev-dependencies?
Also I can`t find anything on deployment docs.
> [builder 7/7] RUN yarn build:
#13 0.507 yarn run v1.22.19
#13 0.556 $ react-scripts build
#13 0.579 /bin/sh: react-scripts: not found
#13 0.590 error Command failed with exit code 127.
#13 0.590 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
------
executor failed running [/bin/sh -c yarn build]: exit code: 127
ERROR: Service 'app' failed to build : Build failed
`docker-compose` process finished with exit code 1
package.json
{
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-i18next": "^11.17.2",
"react-router-dom": "^6.3.0",
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build", <--- THIS WILL BE USED FOR PRODUCTION
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"devDependencies": {
"react-scripts": "5.0.1", <--- THIS WILL NOT BE INSTALLED WITH --production FLAG
"tailwindcss": "^3.0.24",
"typescript": "^4.6.3"
}
}
Dockerfile
FROM node:18-alpine AS builder
ENV NODE_ENV production
# Add a work directory
WORKDIR /app
# Cache and Install dependencies
COPY package.json .
COPY yarn.lock .
RUN yarn install --production <---- THIS DOES NOT INSTALL DEV DEPENENCIES
# Copy app files
COPY . .
# Build the app
RUN yarn build <---- THIS CAUSES THE CRASHING
# ---------------------------------------------------
# Bundle static assets with nginx
FROM nginx:1.23.1-alpine AS production
ENV NODE_ENV production
# Copy built assets from builder
COPY --from=builder /app/build /usr/share/nginx/html
# Add your nginx.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]
docker-compose.yml
version: "3.8"
services:
app:
container_name: my_app
build:
context: .
target: production
dockerfile: Dockerfile
In the final image stage, you're only COPY --from=builder the /app/build directory but not any of the node_modules tree. It doesn't matter in the initial stage if you have development or production dependencies, since they're not going to be in the final image.
Since you do need the devDependencies at this point, I'd remove the yarn install --production option. If it makes a difference to your build environment you can set NODE_ENV=production after you install the dependencies.
RUN yarn install # not --production
COPY . .
# ENV NODE_ENV=production
RUN yarn build

Connecting to React docker container on port 80

I'm trying to deploy a React app as part of a docker compose. It works fine if I deploy on port 3000, but when I use port 80, I cannot connect. If I run npm start manually, either config works fine, but I cannot access the port 80 version when running as a docker image.
I've tried adding EXPOSE 80 to the dockerfile, but it did not seem to have any effect. Can someone point out the error in my config?
Dockerfile:
FROM node:17-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install
RUN npm install react-scripts#5.0.0 -g
COPY . .
CMD ["npm", "start"]
docker-compose.yaml
version: "3.8"
services:
solvle:
build: ./
container_name: solvle_c
ports:
- '8081:8081'
solvle_front:
build: ./solvle-front
container_name: solvle_front_c
ports:
- '80:80'
stdin_open: true
tty: true
package.json fragment
"scripts": {
"start": "set PORT=80 && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
For linux you should set port in this way:
"start": "export PORT=80 && react-scripts start"
Another solution is create a file with name .env (documentation) in the main directory and set PORT variable to desired port number:
PORT=80
One more solution.
You could use cross-env to set the port:
npm install cross-env -D
and then modify start script package.json:
"start": "cross-env PORT=80 react-scripts start",
p.s.
But for deploy react app with docker I woud recomend you to use nginx.
p.p.s.
The EXPOSE instruction in dockerfile does not actually publish the port. It functions as a type of documentation. expose documentation

How to create and run a development build of an application using create-react-app configuration

npm run build creates production build of the project. How do I create development build? I'm using gradle-node-plugin to build the artifact. The project has standard create-react-app configuration.
This is not really doable with just create-react-app, there is an open issue Here and it doesn't look like it will be added anytime soon.
However, you can use a package called dotenv for that, following are the steps you should take:
Install dotenv (make sure to add save dev) npm install dotenv-cli --save-dev
In package.json scripts section add new script: "build:dev": "dotenv -e .env.development react-scripts build",
And you can build for development with npm run build:dev
PS: if you want to avoid mistakenly deploying dev builds to production (as mentioned here) you can add build:prod to package.json and disable the regular build command, see code:
"build:dev": "dotenv -e .env.development react-scripts build",
"build:prod": "dotenv -e .env.production react-scripts build",
"build": "echo \"Please use build:dev or build:prod \" && exit 1",
Also note that process.env.NODE_ENV will still be production but it'll load your .env.development file
Thanks, #Moses. This is an extension to the answer posted by Moses Schwartz. You can also make the build pick the environment files dynamically by exporting the value of the environment(development, test, production) in the bash shell. And then you don't have to have different build commands for different environments.
You can use this in your package.json
"start": "dotenv -e .env react-scripts start",
"build": "dotenv -e .env.${REACT_APP_ENVIRONMENT} react-scripts build",
So when your run npm start, it will pick the environment values from .env
and when you run npm run build, it will pick the environment values from .env.{REACT_APP_ENVIRONMENT}
To define the REACT_APP_ENVIRONMENT, you can do:
export REACT_APP_ENVIRONMENT="development" or
export REACT_APP_ENVIRONMENT="test" or
export REACT_APP_ENVIRONMENT="production"
Hope this helps. This will help in staging the react application for multiple environments.
Thanks to #Tx_monster comment
github.com/Nargonath/cra-build-watch
A script for create-react-app that writes development builds to the disk
npm install -D cra-build-watch
package.json:
{
"scripts": {
"watch": "cra-build-watch"
}
}
npm run watch

How to use .env in react js

How to use .env in react . I can get access to .env.development and .env.production with
"start":"react-scripts start",
"build": "react-scripts build",
How to get access to another like .env.staging ?
I gave like this
"build_staging": "set REACT_APP_ENV=staging & react-scripts build",
but not working.
Any suggestions please.
To keep things consistent across linux(my production server) and windows(my development server) I use cross-env
npm install --save cross-env
and my scripts look like this
"scripts": {
"dev": "cross-env NODE_ENV=development node server",
"build": "cross-env NODE_ENV=production next build ",
"start": "cross-env NODE_ENV=production node server"
},
so to set a custom env like REACT_APP_ENV you'll need to
"build_staging": "cross-env REACT_APP_ENV=staging react-scripts build",
and you can access it in your javascript code using
process.env.REACT_APP_ENV
also to start a staging server you might want to add
"start_staging": "cross-env REACT_APP_ENV=staging react-scripts start"
more about this here
[CONTEXT]
- I've created React project with Create React.
- Running on Windows 10
- Using VSCode IDE
- I have the file .env.development on above /src folder.
- My code has console.log(process.NODE_ENV) and console.log(process.REACT_APP_YOUR_KEY)
[PROBLEM]
When I'm running the program with npm start, the browser prints 'development' for NODE_ENV, but for my React .env variable, it prints undefined.
I try to run npm start with changing the default script of package.json to this start script: set REACT_APP_YOUR_KEY && react-scripts start. Then there isn't any undefined, all works well. 🤨
[SOLUTION]
The cause was that the file .env.development is not detected correctly. My hypothesis is the environment development file, Windows or VSCode don't detect well.
Windows File Explorer files
VS Code explorer. Look up the icon of the files 🤔
You have to change the file name from .env.development to .env.
[SOLUTION]: I've created env.js as shown below.
env.js placement
after that i have added in index.html the script below
my env.js content
NB: i can acces my env.js var without import them (it seems the best way for me)

Resources