Hello everyone, I’m code_shu, from now on try to be original and valuable, try not to water. So let’s get started. I’m going to talk about what optimization I’ve done recently in building projects? Compared with the original model, what aspects of efficiency can be brought? After reading this article, you will learn the following:

  • Proficient in usingimportexportPerform front end engineering automation
  • Proficient in usingwebpacktherequire.contextAPI for front-end engineering automation
  • A better understanding of front end engineering automation

Let’s start with the basic operation of the common project, and then compare the optimization scheme, and then start our main topic.

General project structure

. ├ ─ ─ the SRC ├ ─ ─ assets -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- a static file ├ ─ ─ API -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- interface file ├ ─ ─ components -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- component files ├ ─ ─ The router -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the vue - the router project routing ├ ─ ─ store -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- vuex project status management ├ ─ ─ directives -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the global order file ├ ─ ─ minxins -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- with file ├ ─ ─ Utils -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- tools function file ├ ─ ─ views -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- page file ├ ─ ─ App. Vue -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the vue project root component └ ─ ─ main. Js -------------------------------------------- Project EntranceCopy the code

We are creating some files to demonstrate

. ├ ─ ─ the SRC ├ ─ ─ API │ ├ ─ ─ the user. The js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the user interface related │ └ ─ ─ cart. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- shopping Cart related interface ├ ─ ─ components │ ├ ─ ─ Cart. Vue -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - shopping cart component │ └ ─ ─ Banner. Vue -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- by chart component ├ ─ ─ Directives │ └ ─ ─ index. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the global directive ├ ─ ─ views │ └ ─ ─ home. Vue -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- page └ ─ ─ utils ├ ─ ─ the dom. The js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- dom related tools function └ ─ ─ array. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- array related tools functionCopy the code

Write two demo interfaces in API /user.js


// Get user information
const getUserInfo = () = >({})

// Check whether the user permission has expired
const getUserExpired = () = >({})

export {
    getUserInfo,   // Get user information
    getUserExpired // Check whether the user permission has expired
}
Copy the code

Write two demo interfaces in API /cart.js


// Get the cart category
const getCartProductCategory = () = >({})

// Get the number of items in the cart
const getCartProductCount = () = >({})

export {
    getCartProductCategory, // Get the cart category
    getCartProductCount     // Get the number of items in the cart
}
Copy the code

components/Cart.vue

<template>
  <div>
    <h1>Cart component</h1>
  </div>
</template>

<script>
export default {
  name: 'Cart',
  data () {
    return{}}}</script>
Copy the code

components/Banner.vue

<template>
  <div>
    <h1>Banner component</h1>
  </div>
</template>

<script>
export default {
  name: 'Banner',
  data () {
    return{}}}</script>
Copy the code

directives/index.js


import Vue from "vue" 
const draggable = {
      inserted(el, binding,vnode,oldVnode){
        / /...
      },
      bind(el, binding,vnode,oldVnode){
        / /...
      },
      update(el, binding,vnode,oldVnode){
      / /...
      },
      unbind(el, binding,vnode,oldVnode){
      / /...
      },
      componentUpdated(el, binding,vnode,oldVnode){
      / /...}}const fcous = {
      inserted(el, binding,vnode,oldVnode){
        / /...
      },
      bind(el, binding,vnode,oldVnode){
        / /...
      },
      update(el, binding,vnode,oldVnode){
      / /...
      },
      unbind(el, binding,vnode,oldVnode){
      / /...
      },
      componentUpdated(el, binding,vnode,oldVnode){
      / /...
      }
}
Vue.directive('draggable', draggable)
Vue.directive('fcous', fcous)
</script>
Copy the code

Then import ‘@/directives’ directly in main.js

views/home.vue

<template>
  <div class="wrapper">
    
  </div>
</template>

<script>
export default {
  data() {
    return{}},watch: {},
  computed: {},
  methods: {},
  created() {},
  mounted(){}}</script>
<style lang="scss" scoped></style>
Copy the code

Write two demo functions in utils/dom.js


// Get the style of the DOM element
const getStyle = () = >({})

// Get the attributes of the DOM element
const getAttr= () = >({})

export {
    getStyle, // Get the style of the DOM element
    getAttr   // Get the attributes of the DOM element
}
Copy the code

API Usage optimization

General usage

Ps: we default your project configuration alias alias @ SRC

The use of API

views/home.vue

<template>
  <div class="wrapper">
    
  </div>
</template>

<script>
// The API is used on demand
import { getUserInfo, getUserExpired } from "@/api/user"
import { getCartProductCategory, getCartProductCount } from "@/api/cart"

export default {
  data() {
    return{}},watch: {},
  computed: {},
  methods: {},
  created() {},
  mounted(){}}</script>
<style lang="scss" scoped></style>
Copy the code

We know that as the project gets bigger and bigger, the functional API names created by each team member like user.js and cart.js are not necessarily semantic, May take a seemingly semantic and look not to understand the API file name Such as ResourceLibraryProjectManagement. Js bank project management the related API, perhaps some people say that I am not afraid of trouble, I have a bad CV solution, and they were afraid to copy and paste in the wrong.

We started to optimize the usage of API. First, we explained the optimization direction:

  1. The first plan was also approvedimportImport as required to achieve the following results
// Just a single import to import on demand
import { 
    getUserInfo, 
    getUserExpired,
    getCartProductCategory, 
    getCartProductCount 
} from "@/api"
Copy the code

This optimization purpose: we don’t need to care what your API module name is, because everyone has a different name style, the only thing we care about is what API is written, that’s all

We started to optimize the API file, and the modified API directory structure is as follows:

API ├ ├ ─ ─ ─ ─ modules -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the API module │ ├ ─ ─ user. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the user interface related │ └ ─ ─ cart. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- shopping cart associated interface └ ─ ─ index. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - API entry filesCopy the code

api/mudules/user.js


// Get user information
export const getUserInfo = () = >({})

// Check whether the user permission has expired
export const getUserExpired = () = >({})

// Refuse to rework
//export {
// getUserInfo, // get user information
// getUserExpired // Check whether the user permission has expired
/ /}
Copy the code

api/mudules/cart.js


// Get the cart category
export const getCartProductCategory = () = >({})

// Get the number of items in the cart
export const getCartProductCount = () = >({})

// Refuse to rework
//export {
// getCartProductCategory, // Get cart category
// getCartProductCount // Get cart quantity
/ /}
Copy the code

API /index.js API entry file

export * from "./modules/user.js"
export * from "./modules/cart.js"
Copy the code
  1. The friend said, the first plan for us1000+ routing projectsMaintenance is difficult, at least in the hundredsimportImport interfaces on demand,The amount of code upandMaintenance is also more difficult, the second renovation scheme continues:

After the transformation, the directory structure is still unchanged, the core idea is modular management and entry files

API ├ ├ ─ ─ ─ ─ modules -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the API module │ ├ ─ ─ user. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the user interface related │ └ ─ ─ cart. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- shopping cart associated interface └ ─ ─ index. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - API entry filesCopy the code

api/mudules/user.js

// Get user information
export const getUserInfo = () = >({})

// Check whether the user permission has expired
export const getUserExpired = () = >({})

Copy the code

api/mudules/cart.js


// Get the cart category
export const getCartProductCategory = () = >({})

// Get the number of items in the cart
export const getCartProductCount = () = >({})

Copy the code

The only difference between the second scheme and the first scheme is API entry file transformation

API /index.js API entry file for the second modification scheme

import Vue from 'vue'
// Use webpack's require.context to get the js file in the specified path.
// Pass the second argument to true
const files = require.context('./modules'.true./\.js$/)
// All API collection objects
const api = files.keys().reduce((modules, path) = > {
  const apis = Object.keys(files(path)).reduce((r, key) = > {
    r[key] = files(path)[key]
    return r
  }, {})
  return Object.assign({}, modules, apis)
}, {})
Vue.prototype.$api = api
Copy the code

What is require.context?

A Webpack API, which is used to automatically import modules by executing require.context. In front-end engineering, if many modules are imported from a folder, this API can be used, it will iterate through the specified files in the folder, and then automatically import, so that The import module does not need to be explicitly called every time

Specific please see website: webpack.docschina.org/guides/depe…

Then import “@/ API “directly from main.js. The usage is much simpler. Without import, the disadvantage is that there is no on-demand, because API collection objects are mounted directly on the prototype of Vue

Example:

views/home.vue

<template>
  <div class="wrapper"></div>
</template>
<script>
export default {
  data() {
    return{}},mounted() {
      console.log(this.$api)
      console.log(this.$api.getUserInfo)
      console.log(this.$api.getUserExpired)
      console.log(this.$api.getCartProductCategory)
      console.log(this.$api.getCartProductCount)
  }
}
</script>
<style lang="scss" scoped></style>
Copy the code

With the API optimized for the project, let’s move on to optimizing the use of our components

Component usage optimization

See optimizing the final result

views/home.vue

<template>
  <div class="wrapper"></div>
</template>
<script>

// I think so
import {
    Cart,
    Banner
} from "@/components"

// I don't want that
//import Cart from "@/components/Cart.vue"
//import Banner from "@/components/Banner.vue"

export default {
  data() {
    return{}}, components: {Cart, Banner}}</script>
<style lang="scss" scoped></style>
Copy the code

To start our transformation, the component directory structure is as follows:

API ├ ├ ─ ─ ─ ─ modules -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- component module │ ├ ─ ─ Banner -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- by chart component │ │ └ ─ ─ index. The vue │ └ ─ ─ Cart -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- shopping cart component │ └ ─ ─ index. The vue └ ─ ─ index, js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - component entry filesCopy the code

The directory structure is designed this way to enhance independent maintenance by considering that your component may depend on many other components that serve your component

Let’s write our component entry file

components/index.js

export { default as Banner } from "./modules/Banner"
export { default as Cart } from "./modules/Cart"
Copy the code

That completes the component optimization, and now we can optimize our global directives

Global instruction optimization

Global instruction optimization, the core idea is still modular + entry idea, that is, an entry file management of many module files, by the entry file external distribution, so more attention to their module can be written

Command file directory structure:

├ ─ ─ directives ├ ─ ─ modules -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- component module │ ├ ─ ─ focus. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get focus instruction │ └ ─ ─ draggable. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- dragging instruction └ ─ ─ index. Js -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - order entry filesCopy the code

directives/modules/focus.js

export default {
      inserted(el, binding,vnode,oldVnode){
        / /...
      },
      bind(el, binding,vnode,oldVnode){
        / /...
      },
      update(el, binding,vnode,oldVnode){
        / /...
      },
      unbind(el, binding,vnode,oldVnode){
        / /...
      },
      componentUpdated(el, binding,vnode,oldVnode){
        / /...}}Copy the code

directives/modules/draggable.js

export default {
      inserted(el, binding,vnode,oldVnode){
        / /...
      },
      bind(el, binding,vnode,oldVnode){
        / /...
      },
      update(el, binding,vnode,oldVnode){
        / /...
      },
      unbind(el, binding,vnode,oldVnode){
        / /...
      },
      componentUpdated(el, binding,vnode,oldVnode){
        / /...}}Copy the code

directives/index.js

import Vue from 'vue'
const files = require.context('./module'.false./\.js$/)
files.keys().forEach(key= > {
  const fileName = key.replace(/(\.\/|\.js)/g.' ')
  Vue.directive(fileName, files(key).default)
})
Copy the code

Finally import the file in main.js import “@/directives”

views/home.vue

<template>
  <div class="wrapper">
      <input type="text" v-focus />
  </div>
</template>
<script>

export default {
  data() {
    return{}}}</script>
<style lang="scss" scoped></style>
Copy the code

I believe that with the above optimization ideas, you can also optimize your project, because the text may not be very clear description, so I put the relevant optimization in this project, if you think it is helpful, please do not spare your star, other utils and other similar optimization, do not list together.

conclusion

These are some of the things I’ve been doing recently in the area of project construction and front-end engineering automation in order to lower the barriers to adoption and improve team efficiency.

Feel free to point out any inaccuracies or errors, and leave comments if you have better ideas.