Vite3 + Vue3 + Ts solves the index generated by packaging The HTML page displays blank, cross domain resources, no resources found, 404 page not found and other errors

Posted by RClapham on Wed, 05 Jan 2022 00:01:52 +0100

Problem Description:

After the project is developed with Vue3 + Ts and built and packaged through Vite, directly open the index in the dist directory in the local file system with a browser When accessing HTML files, the browser page displays blank, there is an error after opening the console, and the corresponding file cannot be found in the corresponding path.

Reason 1:

Due to index In the HTML file, the path of the referenced related resource file is incorrect, which leads to the failure of loading the resource file. In most development processes, this refers to the prefix of static resource loading, which is "/" by default.

resolvent:

Open vite.com in the project root directory config. TS file. If there is no file, create one by yourself (in fact, it is similar to vue.config.js in Vue2.x). Set the "base" item of the static resource base path to: empty character: ". /", or: "", or according to process env. NODE_ Env environment condition setting: [also set the starting path of the loaded file to the current path (the same level as index.html)].

Note: if the item is in a subdirectory under the domain name, the value of the base item is the directory name of the corresponding subdirectory!!
For example, if the project is in the h5 directory under the domain name, then base: '/ h5 /',

import { defineConfig } from 'vite'
import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [
    vue(),
  ],

  // Static resource base path base: '. /' | ',
  base: process.env.NODE_ENV === 'production' ? './' : '/',

  alias: {
    // Configure directory alias
    '@': resolve(__dirname, 'src'),
    'views': resolve(__dirname, 'src/views'),
    'utils': resolve(__dirname, 'src/utils'),
  },

  css: {
    // css preprocessor
    preprocessorOptions: {
      less: {
        modifyVars: {
          // Global less variable storage path (configure the global variable of less)
          hack: `true; @import (reference) "${resolve('src/public/config.less')}";`,
        },
        javascriptEnabled: true,
      }
    }
  },

  // Development server configuration
  server: {
    host: true,
    open: true,
    port: 3000,
    proxy: {
      '/api': {
        target: '//www.xxxx.com',
        changeOrigin: true,
        ws: true,
        secure: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      }
    }
  },
})

Reason 2:

Vite is not designed for the traditional module system. The default output < script type = module > is ES Modules to load and access files (js modules, css files, etc.) in a modular manner of type="module". Therefore, accessing files locally in the form of file system is not allowed.

resolvent:

This is a hard injury. Most browsers do not support accessing js files directly in the browser in the mode of type="module", that is (< script type="module" crossorigin = "" SRC = ". / assets / xxx.. js" > < / script >). This modular mode needs to be accessed in the HTTP server environment, If you want to browse projects locally, you need to build an HTTP service environment.
The service environment can be built quickly with the help of some third-party tools. The common HTTP service tools are as follows:

Software:

Browser application (plug-in) class:

Command line tool class:

If you haven't installed any of the above, live server or HTTP server is recommended here, because they are very convenient to install and use, and you only need one life in the command line tool.

/**
* Choose one of the following service tools!!
*/

// Global install live server
npm install -g live-server

// Global installation HTTP server
npm install -g http-server

Extension:

When you are happy to solve the above problems and start to launch the production environment, you may encounter the following problems after the launch is completed:

  1. The page can be accessed and browsed normally, but once you click to jump to another page route or refresh the page, you will report 404 - Page Not Found!!

  2. The page can only be opened normally under the domain name, if it is behind the domain name (such as https://www.xxx.com/index.html )Add / index HTML, the page cannot be found and cannot be displayed!!

resolvent:

1. Change routing mode

Change the routing mode createWebHistory() in Vue router to createWebHashHistory()

import { createRouter, createWebHistory, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: 'Home',
        component: Home,
    },
    {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
    },
];

const router = createRouter({
    // history: createWebHistory(import.meta.env.VITE_BASE_PATH as string),
    
    history: createWebHashHistory(import.meta.env.VITE_BASE_PATH as string), // Change to this routing mode

    routes,
});

export default router;
2. Modify server configuration

Modify the configuration file of the corresponding production server:
1. Nginx server configuration

# In conf / Nginx.exe of Nginx server Add the following code to the conf configuration file
 
location / {
    try_files $uri $uri/ /index.html;
}
 
# Note: modified nginx After the conf configuration file, the nginx service must be restarted before the configuration can take effect!

2. IIS server configuration

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          //Set the parameter in the url to "/" or "/ index.html" 
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Topics: Vue.js