preface

Front-end and server frameworks come in a variety of forms, and with the recent use of Midway. Js on the server side, a lot of thought has been given to how the front-end and server frameworks fit together. There is little documentation on midway. Js, but it is based on egg.js, and egg has many plugins for template rendering. I wanted to do something about it, so I gave it a try.

Many previous projects used NUXT front-end frameworks, mainly considering the nuXT server straight out. However, the application scenarios of the project are constantly changing. Nuxt is a relatively heavy front-end framework. If we only develop a management background, the design concept of the server side is completely redundant for us, so I tried to make a preliminary framework with VUE-CLI to separate the front and back ends. And vuE-CLI can be used to build a flexible front-end framework.

The related documents

Docker tutorial for Midway. Js

Begin to build

1. Create an MVL directory (midway-vue-learn) locally

$ mkdir midway-vue-learn

2. After the MVL directory is created, access the MVL file and use vue-CLI to create a client directory, which is the front-end service directory

Build the vue – cli

$ vue create client

The next steps are some configuration options for scaffolding. After this step, the vue-CLI directory structure is complete

3. Create a server directory

$ midway-init

4. In the client directory, create a vue.config.js file, which is an optional compilation configuration file of vue-CLI

const path = require('path');
module.exports = {
    / / options...
    publicPath: process.env.NODE_ENV === 'production' ? '/public' : '/'.// The resource access addresses of the development and production environments are different
    outputDir: path.join(__dirname, '.. /server/src/app/public')}Copy the code

5. Server service configuration template engine (toegg-view-nunjucksAs an example)

  • plugin.tsThe introduction of the plugin
nunjucks: {
    enable: true.// Whether to enable the plug-in
    package: 'egg-view-nunjucks',}Copy the code
  • config.default.tsConfigure the plug-in
config.view = {
    defaultViewEngine: 'nunjucks'.// Specify the default template engine
    mapping: {
      '.html': 'nunjucks'.// Files with the.html suffix are rendered using Nunjucks
    },
    root: [
      path.join(appInfo.baseDir, 'app/public'), // Specify the root directory for the template file
      // path.join(appInfo.baseDir, 'path/to/another'),
    ].join(', ')};Copy the code

6. Configure the route to render index.html and create a controller

import { Context, inject, controller, get, provide } from 'midway';

@provide()
@controller('/')
export class HomeController {

  @inject()
  ctx: Context;

  @get('/')
  async index() {
    await this.ctx.render('index.html'); }}Copy the code

Here we have implemented the front-end service which packages the code into the static directory of the MDIway service and renders the index.html through the Controller. Of course, many parts of the project are configured to determine the production and development environment. This is mainly for demonstration, and then we start deploying.

Start the deployment

Using a docker

1. Install the docker

The installation process will take some time

2. EditDockerfileThe file is the same as the client and server directories

Set the mirror store addressfromdocker-registry.kuwo-inc.com/alpine-node:latest # Copy files or directories from the context directory to the specified path in the container. Run NPM install --registry= HTTPS://npm.kuwo-inc.com && npm build

workdir /app/my_midway_app

run npm install --registry=https://npm.kuwo-inc.com && npm build# Service launch port expose3000# define anonymous data volume volume ["/app"] # start service CMD ["npm"."start"]
Copy the code

3. Generate an image

Create an image named midway-vue:test in the directory where the Dockerfile resides

$ docker build -t midway-vue:test .

4. Start the image

$ docker run -it -p 3001:3000 midway-vue:test

At this point, our Docker service is already up and running,Access address: localhost:3001Find page access display

It took a while to figure out what the problem was. The midway framework was packaged with a default configuration that did not synchronize static directories to the dist directory, which needed to be configured in package.json

"midway-bin-build": {
    "include": [
      "app/public" // Synchronize static directories]},Copy the code

Finally, we will re-create the image, start the image, and then we are done

Deployment related Issues

Since our project was ultimately presented as a vUE single page application, we usedvue-router“You are likely to adopthistoryPattern, becausehashThe schema is ugly, so that all of our page visits except the home page areThat’s because we only matched/Routes, routes like this/ * * *The service is undefined, so 404.

To solve this problem, here’s what I did before wemidwayThe service adds a middleware that will/apiAddress at the beginning (interface route),/publicAfter the initial address (static directory) is excluded, all other addresses are used to render the page.

The SRC /app/ Middleware directory creates a view.ts

module.exports = () = > {
  return async function auth(ctx, next) {
    const url = ctx.request.url;
    if (/^\/api|^\/public/.test(url)) {
        await next()
    } else {
        await ctx.render('index.html'); }}; };Copy the code

That’s it!