nextjs complains about read property of undefined during build - reactjs

I am creating comment component using Nextjs for server side rendering. everything works fine in dev mode but when I try to build the optimized production, next js complains about
Cannot read property 'byname' of undefined
this is my component:
import React from 'react'
import moment from 'moment-timezone'
export default function Comment({comment}) {
return (
<div>
<div>
<span>{comment.byName}</span>
<span> {moment(new Date(comment.createdOn)).format('ll')}</span>
</div>
{comment.comment}
</div>
);
}
and this is my scripts in package.json
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
this is the error I get
> next build
info - Loaded env from /Users/aliemami/coco-project/coco/.env
Creating an optimized production build
Compiled successfully.
Automatically optimizing pages .
Error occurred prerendering page "/community/Comment". Read more: https://err.sh/next.js/prerender-error
TypeError: Cannot read property 'byname' of undefined,
I kind of understanding what's going on, probably Nexjs is trying to create a static page from this but cannot because of the variable which is passed to the component, how can I tell nextjs that to create the component on each call? what's the most efficient solution? and how is it that Next can deal with this during development and not production?

OK, reading the documents more carefully, it seems that components cannot be under the pages folder, you have to move all the page components outside of the folder.

Related

Basic antd example rendering a blank page

I'm trying to create the most basic react app using antd but it renders a blank page. I used a venv, ran npx create-react-app . and replaced the default App.js file contents with the below example from the antd website. Can someone please advise?
App.js:
import React from 'react';
import { Button } from 'antd';
import 'antd/dist/reset.css';
import './App.css';
const App = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
Terminal output:
Compiled successfully!
You can now view antd-examples in the browser.
Local: http://localhost:3000
On Your Network: http://10.5.0.2:3000
Note that the development build is not optimized.
To create a production build, use npm run build.
webpack compiled successfully
I was expecting to see a button show up with the above code given there were no errors or warnings but just saw a blank screen instead. Note that when I use the starter code generated from running npx create-react-app . the page renders fine and I see the slowly rotating react symbol.
Edit:
There is some messages in the console log. You can see it here in pastebin.
The package.json file contents are here on pastebin.
The problem in this case is that the antd dependency is missing in the package.json. After installing it with yarn add antd the code works like expected.

Nextjs app won't export due to Image Optimization [duplicate]

This question already has answers here:
Error: Image Optimization using Next.js default loader is not compatible with `next export`
(5 answers)
Closed 5 months ago.
I see this question but the most upvoted answer was to use some Akamai-based config and I am not hosting this with Akamai.
I have a React/Nextjs with a package.json whose scripts look like:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"export": "next export"
},
When I run:
npm run export
I get:
> myapp-website#0.1.0 export
> next export
info - using build directory: /Users/myuser/workspace/myappsite/myapp-website/.next
info - Copying "static build" directory
info - No "exportPathMap" found in "/Users/myuser/workspace/myappsite/myapp-website/next.config.js". Generating map from "./pages"
Error: Image Optimization using Next.js' default loader is not compatible with `next export`.
Possible solutions:
- Use `next start` to run a server, which includes the Image Optimization API.
- Configure `images.unoptimized = true` in `next.config.js` to disable the Image Optimization API.
Read more: https://nextjs.org/docs/messages/export-image-api
at /Users/myuser/workspace/myappsite/myapp-website/node_modules/next/dist/export/index.js:149:23
at async Span.traceAsyncFn (/Users/myuser/workspace/myappsite/myapp-website/node_modules/next/dist/trace/trace.js:79:20)
When I check my next.config.js file I see:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
module.exports = nextConfig
What do I need to do so that npm run export runs successfully? And what's happening here?
I also don't understand why Nextjs wouldn't just work as-is, out of the starting gate.
What we have to keep in mind is how Next.js optimization works under the hood. The images are not optimized during build, they are optimized on-demand. Naturally, for that a server needs to be running.
It is mentioned in the docs:
Images can not be optimized at build time using next export, only on-demand. To use next/image with next export, you will need to use a different loader than the default. Read more in the discussion.
Running next export does not run a server. Instead you are trying to export a static HTML out of your next.js project (for example, to run on github pages etc.)
next export allows you to export your Next.js application to static HTML, which can be run standalone without the need of a Node.js server.
There will be unsupported features, and image optimization is one example.
You can change configuration by adding the below to next.config.js:
module.exports = {
images: {
unoptimized: true,
},
}
or
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
By using the imgix loader, you are offloading that task to imgix
servers, and they will serve you the image. By using unoptimized : true in config, you are disabling image optimization. This way you do not need a server.
In the next.config.js, turn off the image optimization feature, and then run npm build and npm export. Export doesn't support image optimization because there won't be any nextjs server to optimize image. After export you can use third party libraries to optimize your images or load your images from websites which optimizes your images.
Add this is config file -
images: {
unoptimized: true
}

NextJS Source Maps stopped working on Chrome 92

I did not change my package.json nor my next.config
"scripts": {
"dev": "NODE_OPTIONS='--inspect' next dev",
...
}
But I now get react_devtools_backend.js:4049 in my console on Chrome instead of the file and line of my console.log.
On NextJS DOC it says
Source Maps are enabled by default during development.
I am currently on nextJS v11.0.0
Any idea what changes was made which broke the source map ?
It works fine on Firefox though.
Answer given from #oleics
disabling react-dev-tools "fixes" this for me

Issue with Static HTML Export in NextJS [duplicate]

This question already has answers here:
Error: Image Optimization using Next.js default loader is not compatible with `next export`
(5 answers)
Closed 6 months ago.
I am new in nextJS and trying to deploy project in html.
Develop your app as you normally do with Next.js. Then run:
next build && next export
For that you may want to update the scripts in your package.json like this:
"scripts": {
"build": "next build && next export"
}
And run it with:
npm run build
Then you'll have a static version of your app in the out directory.
above is from https://nextjs.org/docs/advanced-features/static-html-export#how-to-use-it
On npm run build its creating out folder but it have only js files, index.html file is missing.
How to export nextJS project in html.
Thanks
Update
on export i am getting this error
Error: Image Optimization using Next.js' default loader is not compatible with `next export`.
Possible solutions:
- Use `next start` to run a server, which includes the Image Optimization API.
- Use any provider which supports Image Optimization (like Vercel).
- Configure a third-party loader in `next.config.js`.
- Use the `loader` prop for `next/image`.
Read more: https://nextjs.org/docs/messages/export-image-api
replacing Image with img and npm run build. Image optimization not supported next export
<img width={70} height={70} src="https://sun1.beTCOYGm.jpg" alt="мое фото" />
Add the following to module.exports in next.config.js:
experimental: {
images: {
unoptimized: true,
},
},
This turns off image optimization.
Read more here: https://nextjs.org/docs/messages/export-image-api
And here: https://nextjs.org/docs/api-reference/next/image#unoptimized

How to connect to a sqlite db from a React app?

I'm trying to build a page using Create React App, plus the sqlite3 module. In their default configurations, the two things don't seem to be compatible out of the box. I'm new to React and JS in general, so I'm hoping there's something obvious I'm missing here.
Using npx v6.9.0 and Node v12.4.0, I can reproduce this by typing npx create-react-app test, cd test, npm start.
So far so good. I type: npm install sqlite3, and receive an npm warning that I should install typescript. OK, I type npm install typescript. All good. I start up the app, and it compiles so far. Great!
I open up App.js, and per sqlite3's readme doc, under the import lines, I type var sqlite3 = require('sqlite3').verbose();
This is probably where I'm doing something wrong. My app now fails to compile, telling me:
./node_modules/sqlite3/node_modules/node-pre-gyp/lib/info.js
Module not found: Can't resolve 'aws-sdk' in '/Users/brendanlandis/Desktop/test/node_modules/sqlite3/node_modules/node-pre-gyp/lib'
I try npm install aws-sdk, which gets me a little farther. My app still won't compile, but now the error is:
TypeError: stream is undefined
./node_modules/set-blocking/index.js/</module.exports/<
node_modules/set-blocking/index.js:3
1 | module.exports = function (blocking) {
2 | [process.stdout, process.stderr].forEach(function (stream) {
> 3 | if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function') {
4 | stream._handle.setBlocking(blocking);
5 | }
6 | });
In googling around, I haven't yet figured out what I'm doing wrong. Any help would be appreciated. Thanks!
As the other answer mentioned, this is probably not recommended. You should really stick your database on the backend somewhere.
However it is possible to do this using sql.js. I had no luck with the sqlite3 module.
Here is the example I used: https://github.com/sql-js/react-sqljs-demo
Start by installing Craco. This is needed for bundling the wasm file.
npm install #craco/craco --save
replace your react scripts with Craco scripts in package.json:
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
"start": "craco start",
"build": "craco build",
"test": "craco test"
}
Make a craco.config.js file in the root of your project and place this code inside:
module.exports = {
webpack: {
configure:{
// See https://github.com/webpack/webpack/issues/6725
module:{
rules: [{
test: /\.wasm$/,
type: 'javascript/auto',
}]
}
}
}
};
Then install sql.js
npm install sql.js --save
You probably need to do some more backend setup after this, but for now import the package:
import initSqlJs from 'sql.js';
// Required to let webpack 4 know it needs to copy the wasm file to our assets
import sqlWasm from "!!file-loader?name=sql-wasm-[contenthash].wasm!sql.js/dist/sql-wasm.wasm";
I had to disable eslint to get the second import to work. Really not ideal, but eslint throws errors if you try using file-loader. These are the lines to remove in package.json:
"eslintConfig": {
"extends": "react-app"
},
Now call the library!
const response = fetch("example.com/sqlitedatabase");
const buf = await response.arrayBuffer();
const SQL = await initSqlJs({ locateFile: () => sqlWasm });
const db = new SQL.Database(new Uint8Array(buf));
You can then query the database; The following code runs a query and then puts it into a more useable form than the default response.
const query = db.exec(`
SELECT
*
FROM
table;
`);
const columns = query[0].columns;
const values = query[0].values;
let rows = [];
values.forEach(element => {
let row = {};
for (let i = 0; i < columns.length; i++) {
row[columns[i]] = element[i];
}
rows.push(row);
});
That should work, but as I mentioned above, you might need to mess with the backend a little. Often times single page applications have trouble with CORS when dealing with bundled files. To fix this on AWS Amplify, I added the following code in a file called customHttp.yml to the root of my project:
customHeaders:
- pattern: '**/*'
headers:
- key: Access-Control-Allow-Origin
value: '*'
- pattern: '*.wasm'
headers:
- key: Access-Control-Allow-Origin
value: '*'
(Edit: Added a more generic pattern to the file, didn't work without it.)
Note that it may take some time for the custom headers to update, even though it looks like they update immediately.
Also related to single page applications, wasm files need to be added to the list of files exempted from redirects:
Source address: </^((?!.(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|json|map|wasm)$).)*$/>
Target address: /index.html
Type: 200 (Rewrite)
ReactJS is mostly a front end framework, you should create a backend server.
Some NPM packages are not compatible with front-end JS application.
Your react application will call the server and the server manipulate the DB transactions. You can for example use express js. Useful docs below :
ExpressJS - SQLite doc
API Request from react app

Resources