An overview of the
The previous front-end project structure adopts node layer + front-end interface to construct and deploy, and the solution is to realize the node layer service with eggJS interface and WebPack + VUe2, which has some mature implementation methods
With the release of Vue version 3.0 and the release of Vite tools, a solution was needed to realize the overall solution built with Vite + vue3 as the front-end of EggJS as a service
Since Vite is superior to WebPack in terms of service startup speed, build speed, package size, etc., this solution is definitely better than the previous solution
The project is developed in typescript and can be directly implemented
plan
The principle of
Start an EggJS service at the development stage, and start the Vite service when HTTP access is available. Accessing egg pages at the development stage is equivalent to using a proxy to access the Vite service for HTML content. After transformation, the resource reference path in the page is replaced with the path of the vite service request address to access the resource. Finally, the HTML is output by the Egg service view engine
The purpose of this is to edit the entry HTML of Vite uniformly during development. After the construction of the project, template resources and static resources are generated for the access of the eggJS online environment service, and the generated HTML is directly output by the online environment
Directories and dependency packages
The main directory structure and description are as follows:
An egg - vite - vue3 ├ ─ app # eggjs implementation │ ├ ─ controller │ │ └ ─ home. Ts │ ├ ─ public │ └ ─ service │ └ ─ Test. The ts ├ ─ config # eggjs │ ├─ ├─ exercises # ├─ build.sh ├─ │ ├─ exercises # ├─ build.sh ├─ │ ├─ exercises # ├─ build.sh ├─ │ ├─ exercises # ├─ build.sh ├─ │ ├─ exercises # │ ├─ ├─ all exercises, ├─ all exercises, all exercises, all exercises, all exercises Service │ └ ─ Test. Test. Ts ├ ─ README. Md ├ ─ appveyor. Yml ├ ─ index. The HTML page # front entrance ├ ─ package. The json ├ ─ postcss. Config. Js ├ ─ # Tailwind.config.js ├─ tsconfig.json # TsConfig ├─ tsconfig.prod.json # TsConfig ├─ vite ├ ─ yarn.lockCopy the code
The following package dependencies are referenced in the project:
{
"dependencies": {
"egg": "^ 2.6.1." "."egg-decorator-router": "^ 1.0.7"."egg-scripts": ^ "server"."egg-view-nunjucks": "^ 2.3.0." "."egg-vite-plugin": "^" 1.0.1
},
"devDependencies": {
"@types/egg": "^ 1.5.0." "."@types/mocha": "^ 8.2.1." "."@types/node": "^ 14.14.31"."@types/supertest": "^ 2.0.0." "."@vitejs/plugin-legacy": "^ 1.3.1." "."@vitejs/plugin-vue": "^ 1.1.5." "."@vue/compiler-sfc": "^ 3.0.7"."autod": "^ 3.0.1." "."autod-egg": "^ 1.1.0." "."autoprefixer": "^ 10.2.4"."egg-bin": "^ 4.11.0"."egg-ci": "^ 1.8.0 comes with"."egg-mock": "^ 4.0.1." "."eslint": "^ 7.21.0"."eslint-config-egg": "^ 9.0.0"."mkdirp": "^" 1.0.4."mocha": "5.2.0"."tslib": "^ 2.1.0." "."typescript": "^ 4.2.2." "."vite": "^ 2.0.4"."vue": "^ 3.0.7"}}Copy the code
Egg-view-nunjucks is a dependency and must be installed
Vue3 and vuE-related @vitejs/plugin-vue @vue/ Compiler-SFC will also be installed. @vitejs/ plugin-Legacy is designed to build pages compatible with browsers that do not support Module Script
The definition in vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import legacy from '@vitejs/plugin-legacy';
export default defineConfig({
build: {
manifest: true,},plugins: [vue(), legacy({ targets: ['defaults'.'not IE 11']})]});Copy the code
The eggJS plug-in and configuration
Egg-viet-plugin this package implements control over the Vite service and view output, and was developed separately to implement the eggJS plug-in for this solution
In config/plugin.ts, perform the following steps
import { EggPlugin } from 'egg';
const plugin: EggPlugin = {
// static: true,
nunjucks: {
enable: true.package: 'egg-view-nunjucks',},vitePlugin: {
/ / to enable an egg - vite - the plugin
enable: true.package: 'egg-vite-plugin',},decoratorRouter: {
enable: true.package: 'egg-decorator-router',}};export default plugin;
Copy the code
The startup of the Vite service is actually the middleware implementation of EggJS. The vite service needs to be enabled only in the development environment, as defined below in config/config.local.ts
import { EggAppConfig, PowerPartial } from 'egg';
export default() = > {const config: PowerPartial<EggAppConfig> = {};
config.vitePlugin = {
devServer: true};return config;
};
Copy the code
The devServer property in vitePlugin represents enabling vite service middleware
The output of the view is still using the Nunjucks template and also uses static resources, defined in config/config.default.ts
import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
import * as path from 'path';
export default (appInfo: EggAppInfo) => {
const config = {} as PowerPartial<EggAppConfig>;
config.keys = appInfo.name + '_1614221169780_4319';
config.middleware = [];
const bizConfig = {
sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`};// View output definition
config.view = {
defaultViewEngine: 'nunjucks'.root: path.join(appInfo.baseDir, 'dist'), //
mapping: {
'.html': 'nunjucks',}};Static resource definition
config.static = {
prefix: '/assets/'.//
dir: [
path.join(appInfo.baseDir, 'app/public'),
path.join(appInfo.baseDir, 'dist/assets')]}; config.security = {csrf: { enable: false}};return{... config, ... bizConfig, }; };Copy the code
In the development stage, the interface output is obtained through proxy. After the release, the interface output is realized through the plug-in of EggJS. Config. view and config.static are configured to set resource path correlation
The root path of the view in the setup is dist. The results of the Vite build are output to Dist. Eggjs uses the HTML page in Dist as the output template
config.view = {
defaultViewEngine: 'nunjucks'.root: path.join(appInfo.baseDir, 'dist'), //
mapping: {
'.html': 'nunjucks',}};Copy the code
The static resources are prefixed with /assets/. The default static resources output by Vite are assets. You also need to fetch resources from dist/assets
config.static = {
prefix: '/assets/'.//
dir: [
path.join(appInfo.baseDir, 'app/public'),
path.join(appInfo.baseDir, 'dist/assets')]};Copy the code
The development of
Define a Controller output eggJS view that uses the egg-decorator-Router implementation to automatically generate the router by declaring features like a normal back-end service
The controller uses the extended method await ctx.viet.render (‘index.html’) to output the view
import { Controller } from 'egg';
import { Route, HttpGet, HttpPost } from 'egg-decorator-router';
@Route(a)export default class HomeController extends Controller {
@HttpGet('/')
@HttpGet(The '*')
public async index() {
const { ctx } = this;
const renderData: any = {
serverText: 'title text'};await ctx.vite.render('index.html', renderData);
}
@HttpPost('/api')
public apiPost() {
const { ctx } = this; ctx.body = ctx.request.body; }}Copy the code
The vite. Render method determines whether ViteDevServer is enabled and obtains the service address. In the development environment, the service address of Vite is automatically obtained from the started service instance without additional configuration, replacing the reference path of resources in the template page, and directly outputs the template view online
You can also define any vite service address in viet.config. ts, which is automatically recognized
HTML = http://ip :[port]/index.html = http://ip :[port]/index.html = http://ip :[port]/index.html
release
Ts of compilation
Eggjs runs on JS files, and because it is developed on typescript, compilation is performed to generate JS files at release time
Implementation of TS file compilation
ets && tsc -p tsconfig.prod.json
Copy the code
Tsconfig. json complete definition:
{
"extends": "./tsconfig.json"."compilerOptions": {
"outDir": "./output"
},
"exclude": [
"app/public"."app/views"."node_modules*"."src"."vite.config.ts"]}Copy the code
Tsconfig.prod. json is defined for compilation. In addition to the configuration of references to./tsconfig.json, we also exclude the directory related to the front-end page, which is implemented by Vite
The TSC command by default puts the compilation result of ts files in the same directory as the ts file, using the outDir attribute to put the compilation result in a different location
Front-end construction
Use vite build-c vite.config.ts to build the front end and get the dist folder
Directory integration
To integrate the results of the eggJS compilation with the static resources built by Vite, scripts/build.sh are implemented directly with a script that generates the output directory
The output ├ ─ app │ ├ ─ controller │ │ └ ─ home. Js │ └ ─ service │ └ ─ Test. The js ├ ─ config │ ├ ─ config. The default. Js │ ├ ─ The config. Local. Js │ ├ ─ config. Prod. Js │ └ ─ plugin. Js ├ ─ dist │ ├ ─ assets │ │ ├ ─ the About - legacy. C3f1bf9e. Js │ │ ├ ─ .b856361a.js │ │ ├─ Homes.09CDf4F7.js │ │ ├─ Element - ICONS.a30F5b3b Element - ICONS.ab40A589. Woff │ │ ├─ ├─ Index.868 f201c. CSS │ │ ├─ Index.e5001C38 Polyfills - legacy. 3 e7a3c9b. Js │ │ ├ ─ vendor - legacy. 675 af630. Js │ │ └ ─ vendor. 4 c85d832. Js │ ├ ─ index. The HTML │ └ ─ The manifest. Json └ ─ package. JsonCopy the code
In package.json eggScriptsConfig sets the properties associated with eggJS execution
{
"eggScriptsConfig": {
"daemon": true."env": "prod"."title": "egg-vite-vue3"}}Copy the code
To start the project, run egg-scripts start. /output directly in the root directory
You can also execute NPM install — production on the output directory separately to install only the packages needed to run, and then build a Docker image to run
About vite + vue2
If you are still using vue2 please refer to github.com/fyl080801/e…
Install dependencies
npm i
Copy the code
Start the project
npm run dev
Copy the code
Build the front
npm run dist
Copy the code
Online running and stopping
npm run start
Copy the code
npm run stop
Copy the code
Some resource reference issues about the development environment
During development and debugging, if vite service resources are referenced through the path, resource loading will be abnormal because the eggJS service is accessed and there is no corresponding static resource under this service
Such as http://127.0.0.1:7001/node_modules/element-ui/lib/theme-chalk/fonts/element-icons.woff, in fact, in resources http://127.0.0.1:3000/node_modules/element-ui/lib/theme-chalk/fonts/element-icons.woff, That is, the vite service http://127.0.0.1:3000 provides resources
The solution is to set up egg-vite-plugin to implement proxy forwarding of paths
Add the following parameters to the config/config.local.ts file
config.vitePlugin = {
devServer: true.targets: [
/^(\/node_modules)/g.'/assets/(.*)'],}Copy the code
Targets is an array. Requests that define matching path rules are automatically forwarded to the Vite service. Regular expressions and strings are supported
This is only necessary in the development environment, not the online environment
A link to the
The name of the | instructions | Github | Gitee |
---|---|---|---|
egg-vite-vue3 | Complete solution implementation | Github.com/fyl080801/e… | Gitee.com/fyl080801/e… |
egg-vite-plugin | Eggjs integrates with the Vite service plug-in | Github.com/fyl080801/e… | Gitee.com/fyl080801/e… |
egg-decorator-router | The eggJS decorator routing plug-in | Github.com/fyl080801/e… | Gitee.com/fyl080801/e… |