Next. Js is a great lightweight React isomorphic framework that allows you to quickly develop server-side renderings of React applications. On the next. Js website, it is recommended to deploy the application using Now, but for domestic users or users with special needs, deploying to a custom server is probably what most people want. By taking advantage of the recent revision of the company’s official website, I would like to share my experience from development to deployment.
I still remember that the first time I used Next-js was last year (2017). At that time, I used Next-js version 2.x and React version 15. A year later, React has developed to version 16 and Next-js has developed to version 6.0. In the process of using the new version is also encountered many pits.
The technology used
To start with what technologies were used this time, here is a list of the main technologies or tool libraries used in the project.
- Koa 2
A next-generation Web framework developed by the original Express team to provide Web services.
- nginx
Is a high performance HTTP and reverse proxy server, as well as an IMAP/POP3/SMTP server (from Baidu Baike), developed by the Russians. Used to provide static file services, HTTPS certificates, proxy services.
- 16.3 the react
A javascript UI library
- Next, js 6.0.1
A lightweight React isomorphic application framework
- ant design
React is a set of background product component library developed by Ant Financial
- react-motion
React based animation solution
- react-waypoint
Determine whether the react component is in the current viewable area
- pm2
Process manager for a Node application with load balancing
- isomorphic-fetch
Isomorphic WHATWG Fetch API
The development phase
Having said so much, let’s enter the development phase, and the first step is to build the project architecture. Here we share our own project structure:
📁 .vscode
Vscode configuration file
📁 component
The react components
📁 common
In the public part, I put the navigation bar information, global variables, global styles, and so on
📁 pages
All page entry files of the project are also next. Js page entry files
📁 static
Static files
📁 styles
Individual page style sheets
🗄 index. Js
Node startup file
🗄 .babelrc
Babel configuration file
🗄 .gitignore
Git configuration files
🗄 ecosystem. Config. Js
Pm2 configuration file
🗄 next. Config. Js
Next. Js configuration file
🗄 postcss. Config. Js
Postcss configuration file
🗄 nginx. Conf
Nginx configuration file
🗄 package. Json
NPM configuration file
After configuring the project structure, assuming you have saved all the dependencies we need in package.json, let’s try typing YARN to install the dependencies. Assuming all goes well with the installation, let’s continue our development journey.
First, I created a new index.js file under the Pages file, where I randomly extracted some code from my real project and used it as a normal.
export default class HomePage extends React.Component {
static async getInitialProps({ req, pathname }) {
const data = await fetch(`${ctx}/api/projects/common/list`).then(res= > res.json())
.then(dt= > dt)
.catch(err= > {
return {
success: false.message: err.message
}
})
return { pathname,data };
}
render() {
const { pathname, data } = this.props;
return (
<div>
<Head>
<title>Home page - Ekejie (Wuhan) Ecological Technology Co., LTD</title>
</Head>
<div>Welcome to next.js!</div>{/* omit code here */}</div>); }}Copy the code
If you don’t have the next startup script configured in your package.json, go to Setup to do so. Let’s run NPM run dev on the console. If all goes well, open your browser and you’ll see Welcome to next.
Developing the experience in next.js is almost the same as react, but the WebPack configuration may require some work. Common plugins such as Sass, CSS, and next.js are already available, but you can also use community open source plugins to complete your development journey. For details, please visit the website of next.js.
The deployment of
After going through the development phase, testing, and so on, it’s finally time for deployment. In next. Js, you only need to run NPM run build. It is officially recommended not to change the folder name of the package (formerly called.next), but I recommend to change it to build or dist. After the packaging is complete, we need to write the nodeJS startup entry file. Here is the example code:
const Koa = require('koa')
const next = require('next')
const Router = require('koa-router')
const port = parseInt(process.env.PORT, 10) | |3000
constdev = process.env.NODE_ENV ! = ='production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then((a)= > {
const server = new Koa()
const router = new Router()
/ / home page
router.get('/'.async ctx => {
await app.render(ctx.req, ctx.res, '/', ctx.query)
ctx.respond = false
})
/ / about
router.get('/about'.async ctx => {
await app.render(ctx.req, ctx.res, '/about', ctx.query)
ctx.respond = false
})
/ / product
router.get('/products/:id'.async ctx => {
const {id} = ctx.params
await app.render(ctx.req, ctx.res, `/products/${id}`, ctx.query)
ctx.respond = false
})
/ / case
router.get('/case'.async ctx => {
await app.render(ctx.req, ctx.res, '/case', ctx.query)
ctx.respond = false
})
// Contact us
router.get('/contact'.async ctx => {
await app.render(ctx.req, ctx.res, '/contact', ctx.query)
ctx.respond = false
})
/ / details
router.get('/view/:type/:id'.async ctx => {
const {id, type} = ctx.params
await app.render(ctx.req, ctx.res, `/view`, {id, type})
ctx.respond = false
})
// If nginx is not configured to do static file service, the following code must be enabled
/* router.get('*', async ctx => { await handle(ctx.req, ctx.res) ctx.respond = false })*/
// Prevent console error 404
server.use(async (ctx, next) => {
ctx.res.statusCode = 200
await next()
})
server.use(router.routes())
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`)})})Copy the code
General static files, gzip compression do not need to be handed over to NodeJS to do, I have always considered professional things to professional people. If you do not use Nginx to do static file services, please enable it. Otherwise, js, CSS, image files, etc. packaged with next.js will be 404.
In the packaging stage of next. Js production, the js file request path contains the version number, while the real packaged folder does not have the actual corresponding directory, that is, the packaged folder is a virtual directory, which needs special attention when using nginx. Next. Js provides configuration items to change the build ID. Here’s my actual code:
// next.config.js
module.exports = {
generateBuildId: async() = > {// For example get the latest git commit hash here
return 'v1'}}Copy the code
The resulting virtual path is roughly _next/v1/page/xxx.js, which is slightly different if you use the CDN prefix, but the version number is still there.
Another pitfall is that next. Js is packaged with three folders: bundles, dist, and static. For those who don’t know the source code, there is no way to know which folder the actual requested files are in. So I looked at the source code of next. Js and found that I was actually looking for page in the bundle file, source location: L214
So you need to use aliases when configuring nginx. Here is my actual nginx configuration code:
# site root directory file
location ~ ^/(robots.txt|humans.txt|favicon.ico|sw.js|baidu_verify_7Kj6tQjI3v.html) {
root /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# static file
location^ ~ /static/ {
alias /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next Pages script
location ~ ^/(/_next/v1/) {
alias /home/website/eco_website_pc/build/bundles/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next static file
location ~ ^/(/_next/static/) {
root /home/website/eco_website_pc/build;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
Copy the code
After the static file is configured, HTTPS certificate needs to be configured. Because this project is on the official website of our company, I got a certificate for free, and I used the Asian integrity certificate provided by FreessL here. After applying for the SSL certificate, I need to configure the TXT record from the domain name provider. I am using Ali Cloud here. After completing the verification, FreessL will download the certificate, and after getting the certificate, I need to configure the Nginx SSL certificate.
server {
listen 80;
listen 443 ssl;
server_name wh-eco.com;
charset utf-8;
ssl_certificate /home/website/ssl/www/full_chain.pem;
ssl_certificate_key /home/website/ssl/www/private.key;
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
if ($scheme = http ) {
return 301 https://$host$request_uri;
}
access_log /var/log/nginx/www.wh-eco.com.access.log;
error_log /var/log/nginx/www.wh-eco.com.error.log;
location / {
proxy_pass http://127.0.0.1:xxxx; Secret # 0.0
proxy_set_header Host $host;
#proxy_redirect off;
proxy_set_header REMOTE-HOST $remote_addr;
Websites may use the Websocket special upgrade request protocol in the future
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
# site root directory file
location ~ ^/(robots.txt|humans.txt|favicon.ico|sw.js|baidu_verify_7Kj6tQjI3v.html) {
root /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# static file
location^ ~ /static/ {
alias /home/website/eco_website_pc/static/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next Pages script
location ~ ^/(/_next/v1/) {
alias /home/website/eco_website_pc/build/bundles/;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
# next static file
location ~ ^/(/_next/static/) {
root /home/website/eco_website_pc/build;
if ($request_filename ~* sw.js){
expires -1s;
}
expires 10m;
}
error_page 500 502 503 504 = /error.html;
error_page 404 = /notfound.html;
location = /error.html {
root /home;
}
location = /notfound.html{
root/home; }}Copy the code
As for gzip, you can configure it according to your requirements. Here is my sample configuration:
gzip on;
gzip_comp_level 6;
gzip_vary on;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
image/jpeg
image/gif
image/png
text/css
text/plain
text/x-component;
Copy the code
All you need to do after configuring Nginx is launch the entire application in PM2 mode
pm2 start ecosystem.config.js
Copy the code
After running the above command, if all goes well, you can enter the domain name to access your application (assuming you have resolved the domain name).
conclusion
As deep as the sea at the front
Making | blog