next-blog

Project introduction

Use the React server framework next. Js blog, like to give a Star support. Github.com/Weibozzz/ne… Online address: www.liuweibo.cn This project uses next.js experience sharing: www.liuweibo.cn/p/206

Software architecture

React.js Next-js antd mysql node koa2 FETCH

Website Usage Technology

  • React(16.x) Next-js ANTD – Design fetch Less
  • Backend: Node framework KOA and mysql (currently the front and back end of the separation, here is only responsible for writing interface, and the usual Ajax access interface, here is not open source)
  • Purpose: study in spare time, record technical articles and apply what you learn
  • Web site functionality
    • Markdown publishes articles
    • Modify the article (add, delete, modify and check)
    • User comments
    • Upload pictures to Qiniu Cloud storage

Install the tutorial

  1. Quick start is server-side rendering, but it also calls the interface, so you need to call the back-end interface

Set isShow to true for env.js in config folder. This only calls the interface on my own line. If the value is false, you cannot tune the interface and need to write the interface yourself.

  1. run
cnpm i
npm run dev
Copy the code
  1. The deployment of
cnpm i
npm run build
npm start
Copy the code

Directions for use

  • It is normal to not upload pictures, publish articles or modify the presentation, because it is for presentation only.
  • Routing and background management are also normal, you can modify the code to show the effect of routing.

Website screenshot

  1. Details page
  2. List of pp.
  3. Edit pages and publish articles, upload pictures to Qiniuyun

Website Technology Introduction

With the help of the personal website developed by next. Js, the online address www.liuweibo.cn, summarize the experience and use experience after the completion of development. Github.com/Weibozzz/ne gtihub source code… . Give a Star if you like.

Why server side Rendering (SSR)?

  • The website is to promote, so need better SEO, search engines can grab the whole page
  • Access speed, faster loading of static pages

Website Usage Technology

  • React(16.x) Next-js ANTD – Design fetch Less
  • Backend: Node framework KOA and mysql (currently the front and back end of the separation, here is only responsible for writing interface, and the usual Ajax access interface, here is not open source)
  • Purpose: study in spare time, record technical articles and apply what you learn
  • Web site functionality
    • Published articles
    • Modify the article (add, delete, modify and check)
    • User comments

Source analysis

I’m just going to get to the point here

Entrance to the fileserver.js

Here use the official provided express, while enabling gzip compression

const express = require('express')
const next = require('next')

const compression = require('compression')
constdev = process.env.NODE_ENV ! = ='production'
const app = next({ dev })
const handle = app.getRequestHandler()
let port= dev?4322:80

app.prepare()
  .then((a)= > {
    const server = express()

    if(! dev) { server.use(compression())//gzip
    }
    // Create a new page
    server.get('/p/:id', (req, res) => {
      const actualPage = '/detail'
      const queryParams = { id: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })

    server.get(The '*', (req, res) => {
      return handle(req, res)
    })

    server.listen(port, (err) => {
      if (err) throw err
      console.log('> Ready on http://localhost ' port)
    })
  })
  .catch((ex) = > {
    process.exit(1)})Copy the code

Page root component _app.js

For passing redux data,store is used just like normal react usage, header and footer can be placed here, and _err.js is used for handling 404 pages


import App, {Container} from 'next/app'
import React from 'react'
import {withRouter} from 'next/router' // Add router to next
import withReduxStore from '.. /lib/with-redux-store' // Access next's redux
import {Provider} from 'react-redux'


class MyApp extends App {
  render() {

    const {Component, pageProps, reduxStore, router: {pathname}} = this.props;
    return (
      <Container>
        <Provider store={reduxStore}>
         <Component {. myPageProps} / >
        </Provider>

      </Container>
    )
  }
}

export default withReduxStore(withRouter(MyApp))

Copy the code

The server render page of the site Blog page

  • linkTo jump to pages, use as to change the original http://***.com?id=1 to a nice /id/1
  • headYou can nest meta tags for SEO
  • Configure components that do not require SEO
import dynamic from 'next/dynamic';

// No need for SEO
const DynasicTopTipsNoSsr = dynamic(import('.. /.. /components/TopTips'), {ssr:false
})

import React, {Component} from 'react'
import {connect} from 'react-redux'
import Router from 'next/router'
import 'whatwg-fetch' // Used to fetch data
import Link from 'next/link'; // Next jump link
import Head from 'next/head'  // Next jump head can be used for SEO

class Blog extends Component {

  render() {
    return (
      <div className="Blog">
        <Head>
          <title>{BLOG_TXT}&raquo; {COMMON_TITLE}</title>
        </Head>
        <MyLayout>
          <Link   as={` /Blog/ ${current} `}href={` /Blog?id=${current}`} >
            <a onClick={this.onClickPageChange.bind(this)}>{current}</a>
          </Link>
        </MyLayout>
      </div>)}}The getInitialProps method is used to request data to be rendered on the server
Blog.getInitialProps = async function (context) {
  const {id = 1} = context.query
  let queryStringObj = {
    type: ALL,
    num: id,
    pageNum
  }
  let queryTotalString = {type: ALL};
  const pageBlog = await fetch(getBlogUrl(queryStringObj))
  const pageBlogData = await pageBlog.json()


  return {pageBlogData}
}
// Redux is passed here as needed
const mapStateToProps = state= > {
  const {res, searchData, searchTotalData} = state
  return {res, searchData, searchTotalData};
}
export default connect(mapStateToProps)(Blog)

Copy the code

Static resource

Create a static folder in the root directory. This is mandatory, otherwise static resources will not load

Configure antD and themes and load them as needed

The topic configuration

antd-custom.less

@primary-color: #722ED0;

@layout-header-height: 40px;
@border-radius-base: 0px;

Copy the code

styles.less

@import "~antd/dist/antd.less";
@import "./antd-custom.less";

Copy the code

Finally unified configuration in the common head

<Head>
    <meta charSet="utf-8"/>
    <meta httpEquiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
    <meta name="viewport"
          content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
    <meta name="renderer" content="webkit"/>
    <meta httpEquiv="description" content="Lau Wai Po - Up every Day"/>
    <meta name="author" content="Liuweibo,liuweibo"/>
    <link rel='stylesheet' href='/_next/static/style.css'/>
    <link rel='stylesheet' type='text/css' href='/static/nprogress.css' />
    <link rel='shortcut icon' type='image/x-icon' href='/static/favicon.ico' />
  </Head>

Copy the code

Load the configuration on demand

. Babelrc file

{
  "presets": ["next/babel"]."plugins": [
    "transform-decorators-legacy"["import",
      {
        "libraryName": "antd"."style": "less"}}]]Copy the code

Next. Config. js file configuration

const withLess = require('@zeit/next-less')

module.exports =   withLess(
  {
    lessLoaderOptions: {
      javascriptEnabled: true.cssModules: true,}})Copy the code

CSS page

JSX of style adds global as global, otherwise only applies here

render() {

    return (
      <Container>
        <Provider store={reduxStore}>
          <Component {. myPageProps} / >
        </Provider>

        <style jsx global>{` .fl{ float: left; } .fr{ float: right; } `}</style>
      </Container>
    )
Copy the code

A progress bar is loaded at the top of the page

import Router from 'next/router'
import NProgress from 'nprogress'

Router.onRouteChangeStart = (url) = > {
  NProgress.start()
}
Router.onRouteChangeComplete = (a)= > NProgress.done()
Router.onRouteChangeError = (a)= > NProgress.done()
Copy the code

Markdown publishes articles and code highlighting

Use only marked(‘ put markdown string ‘);

import marked from 'marked'
import hljs from 'highlight.js';

hljs.configure({
  tabReplace: ' '.classPrefix: 'hljs-'.languages: ['CSS'.'HTML, XML'.'JavaScript'.'PHP'.'Python'.'Stylus'.'TypeScript'.'Markdown']
})
marked.setOptions({
  highlight: (code) = > hljs.highlightAuto(code).value,
  gfm: true.tables: true.breaks: false.pedantic: false.sanitize: true.smartLists: true.smartypants: false
});
Copy the code

Tired of studying, let’s have a picture to relax

Participate in the contribution

  1. The Fork the project,
  2. New Feat_ XXX branch
  3. Submit code
  4. New Pull Request

legacy

  1. Do data caching when traffic is high
  2. CDN node view the date of the picture
  3. Configure image description and changes
  4. Upload pictures of high quality not support upload, upload code improved
  5. Uploading is just 1M bug
  6. Support to collect articles and modify comments after login
  7. The top loading scrollbar did not load for the first time
  8. Added koA submodule
  9. Comments support Markdown, and too many comments are suggested to sf platform

To be learned and modified

  1. Warning.js :33 Warning: A component iscontentEditable
  2. eslint

About the author

  • github:github.com/Weibozzz
  • Personal blog :www.liuweibo.cn
  • segmentfault:segmentfault.com/u/weibozzz

Copyright statement

  • Copyright of all original articles belongs to Weibozzz.

Author: Liu Weibo

Link: www.liuweibo.cn/p/206

Source: Liu Weibo’s blog

The copyright of this article belongs to Liu Weibo. Please indicate the source. Thank you for your cooperation