Build Vue3 TSX mobile terminal project based on Vue Cli4 (1)

Build Vue3 TSX mobile terminal project based on Vue Cli4 (1)

Build Vue3 TSX mobile terminal project based on Vue Cli4 (1)

Project Description

It has been nearly a year since the release of the preview version of Vue3. In previous experiments, compared with React Hooks, when targeted optimization is not considered, the underlying rendering mechanism of Vue3 is optimized better. So it's time to start some experiments with Vue3.

because I feel

Vue Cli4
It is very mature, so there is no need to build Webpack from scratch. It will be more efficient to repackage on its basis. So this article is based on
Vue Cli4
The construction of the Vue3 framework mainly includes:

  1. Differentiate multiple environment configurations
  2. Mobile debugging tool eruda
  3. eslint
  4. stylelint
  5. px2vw mobile end adaptive
  6. HardSource development and construction acceleration
  7. babel-plugin-import on-demand introduction
  8. CDN uploading static resources in the production environment
  9. express start
  10. Common Hooks package
  11. Vue3 TSX common syntax writing

In this project, I recommend using all

Component API
Develop to better use Hooks capabilities. At the same time, in order to improve Vue2
<template></template>
Code hints cannot be carried out in, the official recommendation is to use vue's template syntax for development, but template is not as flexible as TSX, so TSX can still be used for development in some cases where flexibility is required. In daily business code development, it is still recommended that you use template. The specific reasons will be explained in Chapter 4. With
Component API
After that, Vue's TSX writing method will not be as awkward as when Vue2 used JSX before. At the same time, TSX and Vue files can also be seamlessly connected, which can be selected according to the business form and your own habits.

In order to prevent the space from being too long, it will be divided into four parts for explanation. This article mainly explains: project creation, differentiation of multi-environment configurations, and integration of eruda mobile debugging tools.

Create project

1. we use Vue Cli4 to create a basic project:

Project creation

vue create yuor-template

Then we choose

Manually select features
Some basic configurations to customize our needs

Vue CLI v4.5.4 New version available 4.5.4 -> 4.5.12 Run npm i -g @vue/cli to update! ? Please pick a preset: Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3] babel, eslint) Manually select features Copy code

Select the required characteristics

Here we check

Vue version selection
,
Babel
,
TypeScript
,
Router
,
Vuex
,
CSS preprocessing
,
lint

? Check the features needed for your project: Choose Vue version Babel TypeScript Progressive Web App (PWA) Support Router Vuex CSS Pre-processors Linter/Formatter Unit Testing E2E Testing Copy code

Choose the version of Vue

Because our project is based on Vue3, the version selected here is Vue3

? Choose a version of Vue.js that you want to start the project with 2.x 3.x (Preview) Copy code

Other options

Because there are many choices here, I will not waste space one by one. The configuration is as follows:

Set separately

Do not use class components
,
Use babel for escaping
,
router uses history mode
,
Use dart-sass style preprocessor
,
Use ESLint + Standard config
,
Lint detection when saving
,
Put the configuration of each component in the configuration file of each component

? Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, TS, Router, Vuex, CSS Pre-processors, Linter ? Choose a version of Vue.js that you want to start the project with 3.x (Preview) ? Use class-style component syntax? No ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass) ? Pick a linter/formatter config: Standard ? Pick additional lint features: Lint on save ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files ? The Save the this AS A PRESET for Future Projects? (Y/N) copy the code

Project trial run

After the installation is complete, we can enter the newly-built project for a trial run

Successfully created project vue-plus-example. Get started with the following commands: $ cd vue-plus-example $ npm run serve Copy code

Differentiate multiple environment configurations

In the above step, we have created the basic project framework through Vue Cli4. Generally, when we actually develop, there will be

Local development environment
,
Development environment
,
Test environment test
,
Pre-release environment staging
,
Production environment
. In response to this difference, we all need a different set of configurations to distinguish configurations such as buckets uploaded by CDN, API addresses, and domain names that redirect to other sites. So next we will configure a set of multi-environment configurations.

Add environment configuration file

First we create a new in the root directory

config
Folder, then add in the config folder
index.js
,
local.json
,
development.json
,
test.json
,
staging.json
,
production.json
file.

Here is a rough explanation of the role of each file:

  • index.js: The method class for obtaining the configuration file, which mainly encapsulates a series of operations for reading the configuration according to the current environment variables
  • local.json: The configuration of the local development environment. The advantage of extracting this file separately is that when we want to debug the interfaces of different environments when developing locally, we only need to copy the content from other environment configuration files and overwrite it. Avoid directly modifying the configuration files of other environments, which may cause problems after the release.
  • development.json: configuration of the development environment
  • test.json: configuration of the test environment
  • staging.json: configuration of the pre-release environment
  • production.json: configuration of the production environment

Write configuration file

The configuration file format here is just a set of structure defined by myself at present. You can define your own structure according to your own needs. The following code I use

development.json
Take the structure of as an example, the rest of the environment can be changed according to the actual configuration of the project.

//development.json { //Configure "buildtime" when building : { //Local service IP and port configuration "origin_server" : { "ip" : "127.0.0.1" , "port" : "5000" }, //cdn configuration. This value needs to be filled in according to the CDN configuration in your project. //It will be used in the subsequent static resource upload CDN. If you do not do static resource upload CDN, then this configuration can omit "cdn" : { "region" : "oss-cn-shenzhen" , "accessKeyId" : "xxxxxxxxxxxx" , "accessKeySecret" : "xxxxxxxxxx" , "bucket" : "frontend" , //A bucket is dedicated to store front-end static files "path " : "vue-plus/development/" , //Here I used the project name (vue-plus) + environment variable format as the path "cdnPath" : "https://frontend.oss-cn-shenzhen.aliyuncs.com/vue-plus/development/" //CDN path after upload, used for publicPath } }, //Runtime configuration "runtime" : { //Current environment identifier "env" : "development" , //Public api address "api" : "https://dev-api.wynneit.cn" , //Account related api address "account" : "https://dev-account-api.wynneit.cn" , //host here is defined as the configuration item "host" that jumps to other sites in the project : { //domain name of mobile site "mobile" : "https://dev-mobile.wynneit.cn" }, // Wechat related configuration "wechat" : { // Wechat APPID "appId" : "wxf8xxxxxxxxxxxa53a" } } } Copy code

Write configuration read method

Because the end of the project is to use

Docker
with
Jenkins
Deployed, so I used a custom environment parameter here
front_env
,From
Jenkins
Passed in during configuration.

//index.js const fs = require ( "fs" ); const path = require ( "path" ); const lodash = require ( "lodash" ); const cfgDir = path.join(__dirname); const env = process. env.front_env; function generateCfg () { //Default configuration path const defaultConfigPath = path.join(cfgDir, "development.json" ); //Local configuration path const localConfigPath = path.join(cfgDir, "local.json" ); let localConfig = {}; let envConfig = {}; if (fs.existsSync(localConfigPath)) { localConfig = require (localConfigPath); } //Get if (env) { const envCfgPath = path.join(cfgDir, ` ${env} .json` ); if (fs.existsSync(envCfgPath)) { envConfig = require (envCfgPath); } else { console .warn( `\nConfiguration file specified by env var ${env} = ${envCfgPath} does not exist.\n` ); } } //Get the default configuration const defaultConfig = require (defaultConfigPath); //Splicing the final configuration const mixedConfig = lodash.merge((), defaultConfig, localConfig, envConfig); return mixedConfig; } module .exports = generateCfg; Copy code

Mount config configuration

Here I mount the environment configuration to the window object, so that we can easily see some of the current environment configuration in Chrome DevTool daily to facilitate troubleshooting.

  1. in

    /public/index.html
    Add to
    config slot

    <!DOCTYPE html > < html lang = "zh-CN" > < head > < meta charset = "utf-8"/> < meta http-equiv = "X-UA-Compatible" content = "IE=edge"/> < meta name = "viewport" content = "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" /> < link rel = "icon" href ="<%= BASE_URL %>favicon.ico"/> < title > <%= htmlWebpackPlugin.options.title %> </title > <!-- Add custom configuration--> <%= htmlWebpackPlugin.options.config %> </ head > < body > < noscript > < strong > We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong > </noscript > < div id = "app" > </div > <!-- built files will be auto injected --> </ body > </HTML > copy the code
  2. New

    vue.config.js
    , Configure
    config slot
    Values and settings
    devServer

    //Get environment configuration const cfg = require ( "./config/index" )(); module .exports = { devServer : { host : config.buildtime.origin_server.ip, port : config.buildtime.origin_server.port, }, chainWebpack : ( config ) => { //HTML template injection configuration config.plugin( "html" ).tap( ( args ) => { //Environment configuration script const configScript = `<!--configArea--><script >window.CUSTOMCONFIG = ${ JSON .stringify(cfg.runtime)} </script><!--endOfConfigArea-->` ; args[ 0 ].config = configScript; return args; }); }, }; Copy code
  3. After the configuration is complete, at this time we run the project, and then enter in the Chrome DevTool

    window.CUSTOMCONFIG
    You can see the configuration of our current environment.

Write config declaration file

Although we have successfully mounted the config configuration to

window.CUSTOMCONFIG
Got it, but because our project uses TypeScript, in order not to report an error when using it, and to have the correct code prompt when using it, we also need to target
window.CUSTOMCONFIG
Write a declaration file.

  1. In the project directory

    src/typings/global
    Create under
    window.d.ts
    file.

    Here i use

    typings
    As a unified storage folder for declaration files,
    global
    As a storage folder for some global related declaration files.

  2. write

    window.d.ts
    file

    interface CustomConfig { //Runtime environment variable env : "local" | "development" | "test" | "staging" | "production" ; //Public interface address api: string ; //Account interface address account: string ; //Jump to the domain name of other platforms host: Record< string , string >; //WeChat related configuration wechat: { appId : string , } } interface Window { CUSTOMCONFIG : CustomConfig; } Copy code
  3. in

    main.ts
    Try to introduce it, this is what we can already have under the window
    CUSTOMCONFIG
    Code hints. (If there is no prompt when using vscode, just restart it).

Eruda mobile debugging tool

Because this project is positioned on the mobile terminal, I generally choose to embed it in a non-production environment during mobile development. For example

vConsole
or
Eruda
And other tools, so that we can view logs and quickly locate problems when debugging on the real machine. because
Eruda
Is more powerful, so here I choose to embed
Eruda
.

Add Html slot

Still in

public/index.html
Add custom configuration items in
<%= htmlWebpackPlugin.options.eruda %>

<!DOCTYPE html > < html lang = "zh-CN" > < head > < meta charset = "utf-8"/> < meta http-equiv = "X-UA-Compatible" content = "IE=edge"/> < meta name = "viewport" content = "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" /> < link rel = "icon" href = "<%= BASE_URL %>favicon.ico"/> < title > <%= htmlWebpackPlugin.options.title %> </title > <!-- Custom configuration--> <%= htmlWebpackPlugin.options.config %> <!-- Eruda configuration--> <%= htmlWebpackPlugin.options.eruda %> </head > < body > < noscript > < strong > We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong > </noscript > < div id = "app" > </div > <!-- built files will be auto injected --> </body > </html > Copy code

Add eruda slot content

in

vue.config.js
file
chainWebpack
Add in
eruda
The configuration of the CDN is used directly here, because this package is only used as a development and debugging tool, so there is no need to go
npm install
To the project. This can also be avoided
eruda
Being packaged into the project only increases the package size of the project.

//Get environment configuration const cfg = require ( "./config/index" )(); module .exports = { devServer : { host : cfg.buildtime.origin_server.ip, port : cfg.buildtime.origin_server.port, }, chainWebpack : ( config ) => { //HTML template injection configuration config.plugin( "html" ).tap( ( args ) => { //Embedded environment configuration script const configScript = `<!--configArea-->< script>window.CUSTOMCONFIG = ${ JSON .stringify(config.runtime)} </script><!--endOfConfigArea-->` ; args[ 0 ].config = configScript; //In non-local development environment and non-production environment, inject eruda if (![ "local" , "production" ].includes(cfg.runtime.env)) { const erudaCDN = "//cdn.bootcdn.net/ajax/libs/eruda/2.4.1/eruda.min.js" ; const erudaDomCDN = "//cdn.jsdelivr.net/npm/eruda-dom@2.0.0" ; const erudaScript = `<!--erudaArea--> <script src=" ${erudaCDN} "></script> <script src=" ${erudaDomCDN} "></script> <script> eruda.init({ tool: ['console','network','elements','resources','snippets','sources'], }); eruda.add(erudaDom); </script> <!--endOfRrudaArea-->` ; args[ 0 ].eruda = erudaScript; } return args; }); }, }; Copy code

Eruda test

Because we generally do not need Eruda when we have Chrome DevTool in the local development environment, so I excluded it.

local
surroundings. Here we modify it
config/local.json
middle
runtime.env
for
test
Let's test whether eruda is installed normally. After the modification is completed, run the project again, and we can see that the Eruda icon has appeared in the lower right corner.