Next Export script is not working with next/image component - javascript

I have a project. I want to build and export it but there is an error.
Here is my build script in package.json file.
"scripts": {
"build": "next build && next export"
}
Here is my component where I'm using next/image
import Image from 'next/image'
export default function Logo(){
return(
<Image
src={process.env.website_url ? (process.env.website_url + "/img/logo/logo1.png") : "/img/logo/logo1.png" }
width={width}
height={height}
alt="logo"
/>
)
}
And here is the error when I want to build the project:
Error: Image Optimization using Next.js' default loader is not compatible with `next export`.
So, what sould I do now. Should I use a different loader or what? Thanks.
EDIT: I have created a server.js file and revised package.json scripts.
Server.js file:
const express = require('express')
const server = express()
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev})
const handle = app.getRequestHandler()
const port = 3000
app.prepare().then(()=>{
server.get('*', (req, res)=>{
return handle(req,res)
})
server.listen(port, (err) => {
if(err) console.log(err)
console.log(`SERVER SUCCESS: ${port}`)
})
}).catch((e)=>{
console.log(e.stack)
process.exit(1)
})
Scripts in package.json file:
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "node server.js"
}
Server is working on the localhost, but not working on the host. There is a 503 Service Unavailable error.

next export is only for static pages. So next/image are images optimized and loaded with server started by next start (They are images on demand not on build). next start starts server which has Image optimization API. That's why its unable to export. Try using other image loading service. You can also try only building the next js (next build) without next export and use next start to start server which will handle the Image optimization.
You can Also configure your own loader for Image optimization. Refer these :
Loader reference
next-optimized-images
Next JS Doc message

Related

I can’t serve subroutes when I reload the page

It’s the first time I deployed a full-stack app I created on Render and all seems to be working fine except for the fact that my routes are not found when I reload the component. I’ve got a general idea why as I did a research online but I haven’t managed to solve the problem yet.
Here’s my server file
const express = require("express");
const dotenv = require("dotenv");
const connectDB = require("./config/db");
const path = require("path");
const cors = require("cors");
const corsOptions = {
origin: "*",
credentials: true,
optionSuccessStatus: 200,
};
const app = express();
app.use(cors(corsOptions));
// read variables and save them as environment variables
dotenv.config({path: "./.env"});
// Init Middleware
app.use(express.json({extended: false}));
// data from req object is added to it(middleware)
app.use(express.json());
// Define Routes
app.use("/api/data", require("./routes/data"));
app.use("/api", require("./routes/collection"));
app.use(`/api/item`, require("./routes/item"));
app.use(`/api`, require("./routes/under"));
app.use("/api/users", require("./routes/users"));
app.use("/api/auth", require("./routes/auth"));
app.use("/api/email", require("./routes/email"));
app.use("/api/basket", require("./routes/basket"));
app.use("/api/size", require("./routes/size"));
app.use("/api/wishlist", require("./routes/wishlist"));
app.use("/api/checkout", require("./routes/checkout"));
app.use("/api/payment_confirmation", require("./routes/confirmation"));
const PORT = process.env.PORT || 5000;
// Connect to Database
connectDB();
// Load React App in production
if (process.env.MODE === "production") {
app.use(express.static(path.join(__dirname, "build")));
app.get("*", (req, res) => res.sendFile(path.resolve(__dirname, "build", "index.html")));
} else {
app.get("/", (req, res) => {
res.send("Welcome to the home page");
});
}
app.listen(PORT, () => {
console.log(`App running on port ${PORT}`);
});
That's my package.json and my scripts
“scripts”: {
“start”: “node app.js”,
“server”: “nodemon app.js”,
“client”: “npm start --prefix …/client”,
“client:install”: “npm install --prefix client”,
“build”: “npm install --prefix client && npm run build --prefix client”,
"dev": "concurrently \"npm run server\" \"npm run client\""
}
That's my repo if you want to have a look at the file structure.
enter link description here
enter link description here
I get this error on the console
Error: ENOENT: no such file or directory, stat '/opt/render/project/client/build/index.html'
Although on the events log it says that build is successful so I'm not sure what the correct folder would be.
Thanks in advance
When I downloaded the app and ran it on my system reloading the page, it seems like the server cannot find the routes defined in your server file. This is because your server is configured to handle all routes in your React app's index.html file.
your client-side routes will match the routes defined in your React app, and the server will only serve the index.html file for the initial request.
In your server file, modify your app.get("*")method to serve the index.html file only for the initial request:
if (process.env.MODE === "production") {
app.use(express.static(path.join(__dirname, "build")));
app.get("*", (req, res) => {
// Serve index.html for the initial request
if (req.originalUrl === '/') {
res.sendFile(path.resolve(__dirname, "build", "index.html"));
} else {
// Serve static files for all other requests
res.sendFile(path.join(__dirname, "build", req.originalUrl));
}
});
}

NodeJs Testrunner freezes / stops when setting up Express server

I'm using Node v18 with the experimental testrunner. I use express as a dev dependency for http integration tests which works fine but there is one test freezing or stopping the testrunner ( it doesn't continue )
I'm using TS but can also reproduce it with JS, the test file HttpTests.js contains
import assert from 'assert/strict';
import express from 'express';
import test from 'node:test';
test('Http', async () => {
const server = express();
server.listen(3000);
assert.ok(false);
});
Running this with the npm script "test": "node --test $(find . -name '*Tests.js')" breaks the test runner.
Any ideas what is wrong or missing?
Why am I not using the default execution model?
Since I'm using TS I had to find a way to use ts-node with the testrunner. You can find more information here
https://github.com/nodejs/node/issues/43675
So currently my TS project is using this npm script, which works fine
Reproduction
I created a minimal reproduction repository with and without TypeScript
https://github.com/matthiashermsen/reproduce-broken-test-ts
https://github.com/matthiashermsen/reproduce-broken-test-js
For reproduction purposes run mkdir reproduction && cd reproduction && npm init -y && npm install express. After that create a test directory with a file HttpTests.js containing the content as shown above. Change the package.json to
{
"name": "reproduction",
"type": "module",
"scripts": {
"test": "node --test $(find . -name '*Tests.js')"
}
}
and run the script, the testrunner should not finish.
The testrunner is still experimental
Yes I know. But there are many tests in the project that work perfectly fine. Some sample code
await t.test('subtest - saves data.', async () => {
const expectedResult = {};
const api = express();
const port = await getRandomPort();
const server = api
.use(express.json())
.post('/save', (request, response) => {
response.json(expectedResult);
})
.listen(port);
const httpDataProvider = new HttpDataProvider({ url: `http://localhost:${port}` });
const actualResult = await httpDataProvider.saveSomething();
assert.deepEqual(actualResult, expectedResult);
server.close();
});
The issue is the async activity that you start (server.listen()) but don't stop before the test errors out (by an exception thrown by assert.ok(false)).
Your second test case will probably also stall if actualResult doesn't deep-equal expectedResult because of the same issue (server.close() won't be called).
A workaround would be to always make sure the server gets closed in the end:
test('Http', async () => {
const app = express();
const server = app.listen(3000);
try {
assert.ok(false);
} finally {
server.close();
}
});
Most test frameworks provide "before/after" functionality that can be used to set up or tear down auxiliary objects before and after a test.

Start Node.js project with worker

I have a requirement to run a node js project with worker scripts
My folder structure as follows
Projects
app.js //starting script
controllers
services
routes
workers
worker.js // worker logic
workers.js //forky script to start worker.js file
In my package json file given like that
{
"name": "project",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js && ./workers/workers "
}
}
workers.js
const { cpus } = require('os');
const { fork } = require('child_process');
const numWorkers = cpus().length;
console.log('numWorkers', numWorkers);
for (let i = 0; i < numWorkers; i += 1) {
fork('./worker');
}
I am starting my project by 'npm start', here app.js file is running but my workers didn't start. I am not sure this is the way to start a worker project along with app. Your help is much appreciated.
Thank you
your file workers.js will never called. I will give you breif explanation. According to your package.json start script "node app.js && ./workers/workers" workers.js file will only be called after successfull execution of app.js file.But in app.js file we have a server listening on some xxxx port so the app.js file will never stop its execution unless you stop it using ctrl+c command. But only after the completing execution of app.js file your wokers.js file will be called according to your start script.The best way to call your workers.js file is call it in your app.js file ex:-
const app = require('express')();
require('./workers/workers.js');
app.listen(3000);
or the one more way (usually I dont recommend this for your use case) use npm-run-all
"start": "npm-run-all --parallel server workers",
"server":"node server.js",
"workers":"node ./workers/workers.js"

Deploying Nuxt.js SSR app to production gives error

I have built a Universal app with Nuxt.js, and now I want to deploy it, however I am finding the process very confusing.
This is the scripts part of my package.json
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate"
}
So far I have been using npm run dev with no problem. When I run npm run build it all seems to work fine, then when I run npm run start the app also runs succesfully, but it doesn't seem to be executing my recent built code, instead, it rather seems to be running the same dev code that was ran when doing npm run dev.
I have also tried to execute nuxt start, which made sense to run after executing npm run build, however the app crashes if I do so.
How do I run my SSR app in production after building it?
Is npm run build supposed to build any of my Node.js backend stuff?
This is my server/index.js
// Debug in development
process.env.DEBUG = 'nuxt:*'
require('dotenv').config()
const env = require('../config')
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
const redis = require('./api/adapters/Redis')
const host = env.public.host
const port = env.public.port
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
next();
});
app.set('port', port)
// Import and Set Nuxt.js options
let config = require('../nuxt.config.js')
config.dev = !(env.public.environment === 'production')
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config)
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Connect to redis
redis.connect() // <-- This creates a connection with redis server, and doesn't seem to connect when running `nuxt start`, hence the error.
require('fs').writeFile('ZZZ.txt', 'YES', 'utf8', () => {}) // <-- as an experiment ZZZ.txt file gets written when `npm run dev` but not when `nuxt start` is ran.
// Handle errors
process.once('uncaughtException', err => {
redis.disconnect()
process.exit(1)
});
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()

What is the difference to run React server-side rendering locally and on real NodeJS server (IBM Bluemix)

I created a simple react app with serverside rendering using this workshop git as a base with my minor changes.
So when I run locally NODE_ENV=server node server.js it works fine. But my attempts to deploy this app on a trial of Bluemix the Nodejs server failed. Here's a log :
Here is my server.js code:
require('babel-register')
const express = require('express')
const React = require('react')
const ReactDOMServer = require('react-dom/server')
const ReactRouter = require('react-router')
const StaticRouter = ReactRouter.StaticRouter
const _ = require('lodash')
const fs = require('fs')
const PORT = 5050
const baseTemplate = fs.readFileSync('./index.html')
const template = _.template(baseTemplate)
const App = require('./js/App').default
const server = express()
server.use('/_public', express.static('./_public'))
server.use((req, res) => {
const context = {}
const body = ReactDOMServer.renderToString(
React.createElement(StaticRouter, {location: req.url,
context: context},
React.createElement(App))
)
res.write(template({body: body}))
res.end()
})
console.log('listening on port', PORT)
server.listen(PORT)
P.S. It's obvious that it doesn't understand ES6 syntax in js/App.js, but on my local server it works.
By default NODE_ENV=production but according to Bluemix docs I created a file in .profile.d directory
node_env.sh code:
export NODE_ENV=server;
But I'm not sure if this file changes node_env.
I'm hoping someone more knowledgeable than me can offer a better solution, but here is what I did to make your app work. There is probably a better answer.
Assuming that you do NOT want to run in production mode...
1) server.js: Listen to the port as set in the PORT env var.
server.listen(process.env.PORT || PORT)
2) package.json: Add start command in scripts
"start": "babel-node server.js --presets es2015,stage-2"
3) Get babel-cli
npm install --save-dev babel-cli
npm install --save-dev babel-preset-es2015 babel-preset-stage-2
4) Create a manifest.yml to set CF properties
applications:
- name: rvennam-node-react
memory: 1G
disk_quota: 2G
env:
NPM_CONFIG_PRODUCTION: false
NODE_ENV: dev
5) remove eslint dependencies from devDependencies in package.json (there was a mismatch)
Again, this is assuming you want to run on Bluemix under dev mode. If you wanted production on Bluemix, I would think you would want to use webpack to build locally, and then push and serve your dist directory.

Categories