Personal blog system

Hello, my name is Black Tooth.

I don’t know if it’s my handsome brother or my beautiful sister

Thanks to the nuggets this platform, the big guys of knowledge sharing, let me learn a lot of things!

preface

Code quality problems lightly spray (last year just learn the front end), have any suggestions welcome to contact me, contact information see the bottom, thank you!

If there is any bug on the page, you can also feedback to me, thank you! React/nuxT/Next/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR/reactSSR

Blogs have all the features you need, you can write articles, you can comment, you can leave a message, you can even play games (though it’s not perfect yet), and so on for you to discover.

This is a small full stack project, mainly to check and record their own learning results

Vue, VUE-CLI, Element-UI, back-end NodeJs, MySql and other technologies are used

See here, please don’t white whoring, click a star(O(∩_∩)O)

The front desk page

  • Page design refers to the open source project “White Tea”

PC and mobile support, responsive pages, more page play section for you to explore

1. The home page

2. List of articles

3. The rain

4. Demo

5. About me

6. Message board

Page details here

The background page

  1. The home page
  2. Published articles
  3. About me
  4. Comment on the list
  5. Set up the

Others, such as the article list, I will not fill in later, “mainly want you to study the code thoroughly, write your own, because it is really easy (manual dog head).”

Page details here

The back-end related

  1. Sequelize is used for database operations
  2. The backend framework uses KOA

The use of “sequelize” and “KOA” in this project will be written in a corresponding article whenever possible

Database table structure

This blog originally intended to achieve the classification function of the article, after the feeling does not need, did not use this table

  1. User table ID User Name User Account Password Birthday Profile picture Creation time
  2. Article table ID User ID Article Title Article Picture Article Music Article Category ID(foreign key) Article Summary Publication Time Number of Views Number of Likes Number of Comments (to check the article message board) Category ID
  3. Article Message Table ID Article ID User ID Message Content Time when a message is left
  4. Category Table ID Category name
  5. Mwi ID Indicates the USER ID of a message
  6. Does the user like article table ID User ID Article ID (produced by many-to-many relationship)

Table relationships

  1. Multiple articles in a category (one-to-many)
  2. An article can have multiple comments (one to many)
  3. One user can comment on multiple articles (one to many)
  4. A user can leave a message multiple times (one-to-many)
  5. An article can be liked by multiple users, and a user can like multiple articles (many-to-many)

Code directory introduction and operation introduction

The back-end code uses a three-tier architecture pattern

Models is the presentation layer

Services are the business logic layer

Routes is the data access layer

  1. Backstage is the backstage management system
  2. The “client” is the front-end

NPM Install installs dependencies in both the root and client folders and backstage after pulling the code

You will first create public and ENCRYPT folders in the following directories

Public folder to create the upload folder, upload files need to package the front-end code is also packaged into this directory

In encrypt, you need to create dbencrypt. js and ossencrypt. js

You can switch between models/tables/db.js at any timeLocalDbInfo is used for local development, note to switch in db.js
—————————— Install the database by yourself ————————————
dbEncrypt.js  module.exports = {  localDbInfo: {  dbName: 'XXX'// Database name userName: 'XXX'// Database user name password: 'XXX'// Database password host: {  host: 'localhost'. dialect: 'mysql'  }  }, AliDbInfo: {// Database information on the server, as above dbName: 'XXX'. userName: 'XXX'. password: 'XXX'. host: {  host: 'XXX'. dialect: 'mysql'  }  } } Copy the code
If you don't have a server, you don't need this for local developmentI wrote two interfaces for uploading files, /upload and /ossUpload. If there is no server, switch to /uploadossEncrypt.js
    module.exports = {
        region: 'XXX', // OSS region
 accessKeyId: 'XXXXXX', OSS accessKeyId  accessKeySecret: 'XXXXXX', OSS accessKeySecret  bucket: 'XXXX', // OSS bucket name } Copy the code

Then you can play happily

“Make sure that the database information is correct and then enter the root directory in NPM run sync to synchronize the database, indicating that the synchronization is complete.” “Then enter NPM start to start the service, so that the local service will run.” “Then run the front-end service as usual. Go to Client or Backstage and say NPM run dev to go into development mode.”

The deployment of

First you have to have a server of your own. I use Aliyun

One of the server tools I use, xShell and xFtp, is recommended

Then click on the right “free licensing page” to fill in the relevant information to download

  1. Please choose one of them. After the installation is complete, node-v can print and publish the book, which means the installation is complete. After the installation is complete, set to Taobao image: “NPM config set registry https://registry.npm.taobao.org”

    Optional [” NVM “(Node management tool),” git “]

  2. “Nginx” installation can be seen here, or baidu tutorials a lot

  3. “Mysql” baidu, you will know ~~

  4. “Navicat” (database operation tool), you can use “NavICat registration machine” crack

  5. Open NavICat to connect to the server database, the connection is successful

  6. “Pm2” (PM2 is the node process management tool, you can use it to simplify many node application management tedious tasks, such as performance monitoring, automatic restart, load balancing, and so on, and very simple to use)

    Installation command: NPM install pm2@latest -g

    The pM2 -V printed version is successfully installed

  7. Open the server and the corresponding port on ali cloud (3306,5008,80)

  8. Nginx configuration

    Why 5008? Because my KOA is listening on port 5008

    Here is my nginx configuration

    user  root root;
    worker_processes auto;
    error_log  /www/logs/nginx_error.log  crit;
    pid        /www/server/nginx/logs/nginx.pid;
    worker_rlimit_nofile 51200;
    events  {  use epoll;  worker_connections 51200;  multi_accept on;  }  http  {  include mime.types;  #include luawaf.conf;   If each file is inactive (no requests) within 1 day, it will be removed from the disk. If the disk cache is full, the cache will be automatically cleared according to the LRU algorithm.  proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;   include proxy.conf;   default_type application/octet-stream;   server_names_hash_bucket_size 512;  client_header_buffer_size 32k;  large_client_header_buffers 4 32k;  client_max_body_size 100m;   sendfile on;  tcp_nopush on;   keepalive_timeout 60;   tcp_nodelay on;   fastcgi_connect_timeout 300;  fastcgi_send_timeout 300;  fastcgi_read_timeout 300;  fastcgi_buffer_size 64k;  fastcgi_buffers 4 64k;  fastcgi_busy_buffers_size 128k;  fastcgi_temp_file_write_size 256k;  fastcgi_intercept_errors on;   Enable and disable gzip mode  gzip on;  #gizp compression starting point, files greater than 1K to compress  gzip_min_length 1k;  Set the size of the buffer required for compression, in 4k, if the file size is 7K, apply 2* 4K buffer  gzip_buffers 4 16k;  #nginx for static file processing module, when enabled, will look for files ending with.gz, directly return, do not use CPU compression, if not found, do not compress  gzip_static on;  # Recognize the HTTP protocol version, early browsers may not support gzip self-extracting, users will see garbled characters Gzip_http_version 1.1; # gzip compression level, 1-9, the larger the compression, the better, also more CPU time  gzip_comp_level 1;  The type of file to compress.  gzip_types text/plain application/json application/javascript application/x-javascript text/javascript text/css application/xml image/jpeg image/gif image/png video/mpeg audio/x-pn-realaudio audio/x-midi audio/basic audio/mpeg audio/ogg audio/* video/mp4;  # enable reply header "Vary: accept-encoding"  gzip_vary on;  # Enabled for nginx as a reverse proxy,off(to turn off compression of all proxy results),expired(to enable compression if the header contains the "Expires" header),no-cache(to enable compression if the header contains "cache-control :no-cach") E "),no-store(compression enabled with header containing "cache-control :no-store"),private(compression enabled with header containing" cache-control :private"), no_last_mo______ (open Use compression,header does not contain "last-Modified "),no_etag(compression enabled, if header does not contain "Etag" header information),auth(compression enabled, if header header contains "Authorization" header information)  gzip_proxied expired no-cache no-store private auth;  # (IE5.5 and IE6 SP1 use the mSIE6 parameter to disable gzip compression) to specify which browsers do not need gzip compression (which will match user-agents), depending on the PCRE library  gzip_disable "MSIE [1-6]\.";   limit_conn_zone $binary_remote_addr zone=perip:10m;  limit_conn_zone $server_name zone=perserver:10m;   server_tokens off;  access_log off;   # Whether to enable on-the-fly compression of files. If enabled, files will be compressed and returned in response.  brotli on;  # When enabled, it checks for precompressed files with br extensions. If the value is always, the compressed file is always used, regardless of whether the browser supports it.  brotli_static always;  Set the compression quality level. The value ranges from 0 to 11.  brotli_comp_level 6;  Set the number and size of buffers. The default size is the size of a memory page, which is 4K or 8K.  brotli_buffers 16 8k;  Set the minimum response size to compress.  brotli_min_length 20;  # specify which content encoding types are compressed. Text/HTML content is always compressed  brotli_types text/plain application/json application/javascript application/x-javascript text/javascript text/css application/xml image/jpeg image/gif image/png video/mpeg audio/x-pn-realaudio audio/x-midi audio/basic audio/mpeg audio/ogg audio/* video/mp4; server {  listen 80;  Your domain name  server_name xxxxxx.xxx;  location ^~ / {  proxy_cache imgcache;  proxy_cache_key $scheme$proxy_host$uri$is_args$args;  proxy_cache_valid 200 304 302 24h; Proxy_pass http://www. Domain :5008; proxy_set_header X-Real-IP $remote_addr;  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  proxy_set_header Host $http_host;  proxy_set_header X-Nginx-Proxy true;  proxy_redirect off; rewrite ^.+(? <! js|css|png|map)$ /index.htmlbreak;  autoindex on;  index index.htm index.html;  set $fallback_uri /index.html;  if ($http_accept! ~ text/html) { set $fallback_uri /null;  }  try_files $uri $uri/ $fallback_uri = 404;  }  location ^~ /pc { Proxy_pass http://www. Domain name :5008/back; index index.htm index.html;  } } include /www/server/panel/vhost/nginx/*.conf; }  Copy the code

Everything is ready to deploy the project to the server

“Run the NPM run build command to package foreground and background respectively” The structure of the package is like this


Next place the project (with the exception of client and Backstage and node_Modules) in the dist folder on the server (then use that directory to download the “NPM I” dependencies)


I am not familiar with nginx, so I have to make some changes to the public file placement, familiar can be self-configurable (incidentally teach me.


I’m just going to put everything in the PC folder on the same level

Then go into DIST and run the program with PM2. Run the pm2 start index.js command

Everybody’s happy. We’re done here. Next use the domain name can access

Like my blog

logging

When something goes wrong on the server, it’s not as convenient as local development and debugging, so we need “logging” to locate the problem

I use the library is log4JS open or over the wall, I only record the interface call record, SQL call record can add NPM I KOA-log4

const log4js = require('koa-log4')
const path = require('path')

log4js.configure({
    appenders: {
 api: {  type: 'dateFile'. filename: path.resolve(__dirname, 'logs'.'api'.'logging.log'), MaxLogSize: 1024 * 1024, // Maximum number of bytes in the configuration fileKeepFileExt: 3, // Keep for up to 3 days layout: {  type: 'pattern'. pattern: 'c [%d{YYYY-MM-DD hh: MM :ss}] [%p] : %m%n'  }  },  default: {  type: 'stdout'  }  },  categories: {  api: {  appenders: ['api']. level: 'all'  },  default: {  appenders: ['default']. level: 'all'  }  } })  process.on("exit", () = > { log4js.shutdown() })  const apiLogger = log4js.getLogger("api")  exports.apiLogger = apiLogger Copy the code

Then create a middleware

// apiLoggerMiddleware.js
const { apiLogger } = require('.. /logger') 

// Middleware to handle errorsmodule.exports = async (ctx, next) => {
 try {  await next();  }  finally {  apiLogger.debug(`${ctx.method} ${ctx.path} ${JSON.stringify(ctx.body)}`)  }  };  //init.js app.use(require('./apiLoggerMiddleware') // API request logCopy the code

Home page loading speed optimization

Due to the word limit, please go to Github to check it out

For complete configuration, see vue.config.js in client

Before optimization: 1M bandwidth load “more than 10 seconds” on the first screen

After optimization: under normal conditions, the first screen loads “1,2 seconds”

The last

Unconsciously write too much

There is no template for the project

Share a full stack of their own simple project to everyone, what suggestions/bugs/optimization can be mentioned, thank you!! .

If you see here, please help point [star] (https://github.com/qiheizhiya/myBlog)!!!!!

Like technology can also add me, progress together.

Contact email: [email protected]

This article is formatted using MDNICE