I'm prototyping a NextJS implementation with the following server code:
import express from 'express';
import next from 'next';
import path from 'path';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
dotenv.config();
app.prepare().then(() => {
const server = express();
// Custom build resources aliases
// ---------------------------------------------------------------------
server.use('/favicon.ico', express.static(path.join(__dirname, 'static', 'images', 'icons', 'favicon.ico')));
// ---------------------------------------------------------------------
// Custom/dynamic routes
// ---------------------------------------------------------------------
server.get('/p/:id', (req, res) => {
const actualPage = '/post';
const queryParams = { title: req.params.id };
app.render(req, res, actualPage, queryParams);
});
// ---------------------------------------------------------------------
// Default route
// ---------------------------------------------------------------------
server.get('*', (req, res) => handle(req, res));
// ---------------------------------------------------------------------
// Express: Listener
server.listen(process.env.WEB_PORT, () => {
console.log(`Server listening on port: ${process.env.WEB_PORT}...`);
});
}).catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
As apparent, my static assets sit in a /static/ folder. Of these, I have a favicon file at /static/images/icons/favicon.ico. I am able to visit this file using https://schandillia.com/static/images/icons/favicon.ico. However, when I try hitting https://schandillia.com/favicon, it throws a 404. Am I not using express.static() correctly?
Related
app.js
import express from "express";
import { getTokenData } from "./src/services/dbServices";
const app = express();
app.get("/api/token/:token_id", (req, res) => {
const tokenId = req.params.token_id;
const worldMetadata = getTokenData(tokenId).metadata;
res.send(worldMetadata);
});
app.use(express.static("public"));
app.get("/api/animation/:token_id", (req, res) => {});
app.listen(5000, () => {
console.log("App running on port 5000");
});
Im trying to render static files from my server to display a p5.j script. right now the public directory is being rendered from the "/" route of my server thanks to the express.static. I'd like to render the public directory only when the url matches /api/animation/:token_id. I've been trying for hours to make this work
Here is my express code:
const express = require('express');
const serveStatic = require('serve-static');
const path = require('path');
// create the express app
const app = express();
var cors = require('cors');
app.use(cors());
app.use("/",serveStatic ( path.join (__dirname, '/dist') ) );
app.use('/static', express.static(path.join(__dirname, '/dist23')));
app.listen(port, () => {
console.log("listening on "+port)
});
The above code only works for the folder /dist. But when I go to /static, it shows a blank page and this error in the console:
If I put the js files from /dist23 into /dist, then /static works and shows me the application. Its almost like it is looking for files inside /dist and not /dist23. How do I fix it?
Both apps were built using vue-2.6.11. Both directories have files built/bundled for production.
You need to set the content type while serving your static files.
app.get('/index.html', (req, res) => {
res.set('content-type', 'text/plain').sendFile('index.html', { root: path.join(__dirname, 'public/dist/') })
});
app.get('/', (req, res) => {
res.set('content-type', 'text/plain').sendFile('index.html', { root: path.join(__dirname, 'public/dist/') })
});
I building project NuxtJs + ExpressJs(SSR type) with options as below
In file server/index.js i import API route
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
const fs = require('fs')
const api = require("./routes/routes.js")(app, fs);
// Import API route
app.use('/api', api);
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
await nuxt.ready()
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// 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()
In routes/routes.js
// import other routes
const productRoutes = require("./product/products.js");
const appRouter = (app, fs) => {
// default route
app.get("/", (req, res) => {
res.send("welcome to the development api-server");
});
// // other routes
productRoutes(app, fs);
};
module.exports = appRouter;
And in product/products.js
const productRoutes = (app, fs) => {
app.get("/products", (req, res) => {});
app.post("/products", (req, res) => {});
app.put("/products/:id", (req, res) => {});
app.delete("/products/:id", (req, res) => {});
};
module.exports = productRoutes;
However, i have error TypeError: app.use() requires a middleware function. Maybe i cannot pass parameter (app, fs) when using app.use('/api', api) and need to handle Middleware.
I'm newbie with ExpressJs and Middleware. I don't know what i'm missing. I hope someone please give me a solution. Thanks very much.
I have setup a express.js + next.js app, which is running fine in development environment. When I am trying to run its webpack bundle, Its throwing error
Error: Cannot find module '/Users/user/workspace/project/next.config.js'
I am trying to run its bundle as aws-lamda is not allowing me to upload zip size more than 50MB.
// server.js
const express = require('express');
const argv = require('yargs').argv;
const nextApp = require('./nextApp.js');
const handle = nextApp.getRequestHandler();
const pageRoutes = require('./routes/pages/index.js');
const port = argv.port || 3000;
const server = express();
// route to next.js web pages
server.use('/', pageRoutes);
server.get('*', (req, res) => {
return handle(req, res)
});
nextApp.prepare()
.then(() => {
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
});
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
});
module.exports = server;
So far I have found that we can/should extends next.config.js for adding additional bundle entries instead of creating a separate webpack.config.js. Following config will create a serverbundle.js file in build/server directory.
const merge = require('webpack-merge');
module.exports = {
distDir: 'build',
webpack (config, {isServer}) {
if (isServer) {
return merge(config, {
entry () {
return config.entry().then((entry) => {
return Object.assign({}, entry, { serverbundle: './server' })
})
},
output: {
filename: '[name].js'
}
});
}
return config;
}
}
I'm trying to use the Express Router with Next.js using their custom-express-server example as my boilerplate. The only difference is that I'm trying to define the routes externally on routes/router.js as follows:
Code in server.js:
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const routes = require('./routes/router')
app.prepare()
.then(() => {
const server = express()
server.use('/', routes)
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
module.exports = app;
Code in routes/router.js:
const express = require('express'),
app = require('../server.js'),
router = express.Router();
router.get('/a', (req, res) => {
return app.render(req, res, '/b', req.query)
})
router.get('/b', (req, res) => {
return app.render(req, res, '/a', req.query)
})
router.get('/posts/:id', (req, res) => {
return app.render(req, res, '/posts', { id: req.params.id })
})
module.exports = router;
At this point, even when I'm importing "app" from server.js, app is not available within router.js.
Is my logic incorrect?
If it's not, then why is app not available within router.js?
Just solved it. This issue is known as a circular dependency, and it should be avoided at all costs... unless the pattern you're using (like the boilerplate I used, I guess...) requires it.
To solve it, just export from file "A" the dependency that file "B" uses before you require file "B" on file "A".
...And that's it pretty much.
You might also try using next-routes, which I use on all of my Next project:
// server.js
const { createServer } = require('http');
const next = require('next');
const routes = require('./routes');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = routes.getRequestHandler(app);
app.prepare().then(() => {
createServer(handler).listen(port, err => {
if (err) {
throw err;
}
console.log(`> Ready on http://localhost:${port}`);
});
});
Then you can configure your routes in the routes.js file without accessing the app:
// routes.js
const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());
routes
.add('landing', '/')
.add('blog', '/blog', 'blog')
.add('blog-post', '/blog/:postId', 'blog')