Learning about new company projects

Posted by zerGinfested on Wed, 29 Dec 2021 01:45:19 +0100

On the first day, use svn to pull down the project, and then use yarn to install dependencies. What's the use of yarn? Why do many people use yarn now,

Advantages of yarn

Parallel installation, npm is installed in sequence, so the speed of yarn will be faster,

Reuse the cache package. If a software package has been installed before, it will be obtained from the cache when yarn installs it again

Automatically add version lock, yarn Lock is similar to package lock json

Project structure

  ├─assets            # Static resources 
  │  └─img 
  ├─components        # Component library
  │  └─global         # Global components < do not need to be registered or imported after placement >
  ├─decorator         # Decorator
  ├─filter            # filter
  ├─http              # Network request
  ├─layouts           # layout file
  ├─plugins           # If the plug-in library needs to introduce third-party components, etc. < CDN > is recommended
  ├─router            # route
  ├─store             # vuex
  │  └─modules        # vuex module
  ├─style             # style
  │  ├─css            # css file
  │  └─sass           # sass tool library styles
  ├─utils             # Tool library catalog
  └─views             # pagefile

assets store static resources

It is worth mentioning that the icons here use Ali's vector icon library. You can see how to use them here iconfont code application

components component library

There are some public components. The components in the global folder will be directly registered in the global components. How can they be registered automatically? In fact, it is to traverse all vue suffix files under the global file, and then obtain the component instance through the file name, and then through vue The component method is registered in the vue global component

import Vue from 'vue'

const requireComponents = require.context('./', true, /\.vue/)

requireComponents.keys().forEach(fileName => {
  // Component instance
  const reqCom = requireComponents(fileName)
  // Extract the name in the component as the component name
  const reqComName = reqCom.default.name
  // Component mount
  Vue.component(reqComName, reqCom.default || reqCom)
})

After a general look at the common components, I feel uncomfortable that the semicolon is not used in the overall project. Because I have learned Java and C + + before, I am used to adding semicolons. I found that / deep / depth selector is useful. See here for the principle of depth selector, vue scoped css

Decorator

The highlight here is the decorator, because this is a js project. I didn't know that js project can also use decoration

It is thought that only ts projects have decorators. In fact, it is to install an additional loader to parse annotations and convert annotations into functions,

@The vue/cli plugin Babel plug-in has a Babel loader, and the Babel loader has a @ Babel / plugin proposal decorators plug-in. This plug-in can be used to parse decorators, which should be the built-in function of vue/cli

filter

There are some filters vue used in it

Network request

Generally, this is about how to intercept requests and responses

Request interception

http.interceptors.request.use(
  config => {
    openLoading(config)
    const sessionid = session.getSession(SESSIONID)
    if (sessionid) config.headers[SESSIONID] = sessionid
    config.headers['cache-control'] = 'no-cache'
    config.headers.Pragma = 'no-cache'
    if (localSession.getLocal(USER_INFO)?.userToken) {
      config.headers.token = localSession.getLocal(USER_INFO)?.userToken
    }
    return config
  },
  error => {
    throw new Error(JSON.stringify(error))
  }
)

When sending a request, a loading animation will be triggered first, and then a user-defined attribute sessionid will be added to the request header. Can't you see the use of this now? After that, the user-defined attribute token is added, which is generally a user identifier,

And disable forced caching. What is the reason for this?

Response interception

http.interceptors.response.use(
  async response => {
    closeLoading(response.config)

    let res = response.data
    if (process.env.VUE_APP_mockFlag === 'true') { // If it is mock mode, there is no outer packaging
      return res
    }
    if (response.config.responseType === 'blob') { // If the request is BLOB
      console.log('blob')
      try {
        const JsonData = await CheckStreamOrJSON(res)
        res = JsonData
      } catch {
        return response
      }
    }
    if (!res.success) { // Logical error custom error code
      if (res.message) {
        if (res.code === '401' && !localSession.getLocal(USER_INFO)?.userToken) {
          // When the getCurrentUserInfo interface is called for the first time, there is no token, and there is no need to prompt message
        } else {
          ErrorMessage(res.message)
        }
      }
      globalError('Interface call failed')
      switch (res.code) {
        case '401':
          if (!res.result) {
            reLogin()
          } else {
            // Adapt to the logic of three-party single sign on. If you do not log in, the url of the three-party login will be returned
            session.destroy('pathIDMap')
            session.destroy(SESSIONID)
            window.location.href = res.result
          }

          throw new Error('no login')
        case '402':
          session.destroy(SESSIONID)
          vm.$router.push({ name: 'login' })
          throw new Error('no sso login')
        default:
          break
      }
      throw new Error(JSON.stringify(res))
    }
    return res.result
  },
  error => {
    closeLoading(error)
    // http error
    globalError(new Date(), 'err' + error) // for debug
    const status = error?.response?.status ?? 'unKnow'
    ErrorMessage(status ? ERROR_MSG[status] ?? `link error (${status})!` : 'unknown error!')
    throw new Error(JSON.stringify(error))
  }
)

Response interception is to close loading, judge whether the response is successful according to res.success, and return different error messages according to different code s

// http description table
const ERROR_MSG = {
  400: 'Request error(400)',
  401: 'Unauthorized, please log in again(401)',
  403: 'access denied(403)',
  404: 'Request error(404)',
  408: 'request timeout(408)',
  429: 'The system is busy, please try again later(429)',
  502: 'network error(502)',
  503: 'Service Unavailable(503)',
  504: 'Network Timeout (504)'
}

Layout file

Just some layout components

Plug in Library

It's just some Vue plug-ins. Some feel that they are not plug-ins. Vue plug-ins provide an object with an install method, and then use Vue Use method to add the plug-in, Vue Use will call the install method of the object internally, and then pass the Vue object as a parameter. After getting the Vue object in install, you can perform some operations, Plug in usage

route

It's mainly for a look Global front guard What did you do

router.beforeEach((to, from, next) => {
  // document.title = `${to.meta.title}`
  const user = session.getSession(SESSIONID)
  // The following judgment is to deal with the boundary problem
  //
  if (!user && !to.meta.public) {
    next('/base/login')
  } else if (to.meta.permission) {
    // If you have administrator privileges, you can enter. Here is just a simple simulation of administrator privileges
    user === 'admin' ? next() : next('/403')
  } else {
    next()
  }
})

There is a question here. Which of sessionid and token is the user identifier?

Global state manager

Global style

The browser tag is initialized and used CSS generator plugin

page

Put it in the pages folder, which is chaotic

  + Using technology stack  vue Family bucket
  + close vue esm Error prompt (Please pay attention to your code standard!)
  + Code formatting eslint standard standard  [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
  + Network request usage axios 
  + Local storage usage session (Nailing environment)
  + Use of higher-order function library lodash
  + Time processor moment
  + Digital accurate calculation decimal.js
  + SDK  dingtalk-jsapi 2.8.33
  + UI Component library ant-design-vue: 1.4

Topics: Javascript Front-end