Accelerate the development of front-end automation project vue

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qq_40639990/article/details/89960380

Internal management platform used most of the time this project a rush. In fact, it used webpack + vue which to develop a set of words has greatly improved efficiency. But for our development level. There are still many places to improve our development efficiency project again, let us focus more on the business, improve efficiency, after all, time is life.

production environment automatically deleted console.log

Use the editor global search and found dozens of pages have this statement.
If all manually deleted, and time-consuming, but ineffective. So expect to remove by plug-ins.
Install the required libraries
yarn add babel-plugin-transform- remove-console --save-dev
modify .babelrc Configuration
"plugins": [ "transform- remove-console"]
in npm run build and they will be automatically deleted console. log

Reference-demand element-ui

If the direct introduction of the element-ui entire project will result in too large, pc end Fortunately, if the mobile end user experience will be poor, so first consider the introduction of on-demand element-ui.

solution

1. The official cited an on-demand method is to use babel-plugin-component, can refer to: official document
2.element-ui can also be introduced as needed as cherry pick lodash of
first remove the babel-plugin-component, lodash is a consistent, modular, high-performance JavaScript utility library.

import Button from 'element-ui/lib/button';
Vue.use(Button);

One thing to note here is the discovery can use button components, not just the style, so you need to import style files

import 'element-ui/lib/theme-chalk/index.css';

Of course, style files can also be loaded on demand

/*icon字体路径变量*/
$--font-path: "~element-ui/lib/theme-chalk/fonts";

/*按需引入用到的组件的scss文件和基础scss文件*/
@import "~element-ui/packages/theme-chalk/src/base.scss";
@import "~element-ui/packages/theme-chalk/src/button.scss";

3. The establishment of a single element-ui.js follows, will come in the components you need to write

import Vue from 'vue'
import { Card, Button, Row, Col, Tag, Switch, Form, FormItem, Message, Input, Icon, Dropdown, DropdownMenu, DropdownItem, Popover, Tabs, TabPane } from 'element-ui'

Vue.component(Card.name, Card)
Vue.component(Button.name, Button)
Vue.component(Row.name, Row)
Vue.component(Col.name, Col)
Vue.component(Tag.name, Tag)
Vue.component(Switch.name, Switch)
Vue.component(Form.name, Form)
Vue.component(FormItem.name, FormItem)
Vue.component(Input.name, Input)
Vue.component(Icon.name, Icon)
Vue.component(Dropdown.name, Dropdown)
Vue.component(DropdownMenu.name, DropdownMenu)
Vue.component(DropdownItem.name, DropdownItem)
Vue.component(Popover.name, Popover)
Vue.component(Tabs.name, Tabs)
Vue.component(TabPane.name, TabPane)
Vue.prototype.$message = Message

Using automated webpack

Webpack is the basis of our front-end engineering of the project, but in fact, its usefulness is much more than that, we can do something to help us through Webpack automate things. First, we need to look at require.context ()

require.context() ???

First, it is a webpack of api, by performing require.context () to get a particular context , where the context , refers toWe can be screened by this method we need a file and read.
Use require.context can dynamically import documents. In fact Webpack by resolving require () call, extracted the following information:

Directory: ./template
Regular expression: /^.*\.ejs$/

Want to know more can refer to: official document , but the document expressed very official.

When do I need require.context ()

Use require.context () but can also reduce our repetitive code
Scenario 1
routing file more reasonable to deal
with more and more projects, more and more required modules, require.context () this time can achieve automatic import module in front-end engineering, if you encounter the case of the introduction of many modules folder from a file, you can use this API , it will traverse the specified folder, and then automatically imported, there is no need to explicitly call each import import module.
For chestnut: writing vue multi-customer management background of the project, the route is divided by different functions into different modules, one needs to import index.js, more and more demand module, will appear each time a manual import bloated, here you can use require.context () loop through all files to a folder and then a one-time modules imported into the index.js.
Here Insert Picture Description

Here Insert Picture Description

Such modules generate a directory contains various modules, each functional module is then introduced index.js the disposable modules folder.

modules folder processing service module

modulesFolder to store all of our business logic modules, as to how to divide the business logic modules, I believe we naturally have their own set of standards. We () followed by the preparation of the above-mentioned require.context automation core of index.js.

/**
* @param directory 要搜索的文件夹目录不能是变量,否则在编译阶段无法定位目录
* @param useSubdirectories  是否搜索子目录
* @param regExp 匹配文件的正则表达式,匹配哪种文件
* @return function 返回一个具有 resolve, keys, id 三个属性的方法
          resolve() 它返回请求被解析后得到的模块 id,接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
          keys() 它返回一个数组,由所有符合上下文模块处理的请求组成,返回匹配成功模块的名字组成的数组 
          id 是上下文模块里面所包含的模块 id. 它可能在你使用 module.hot.accept 的时候被用到
          这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)
*/
// require.context('demo', useSubdirectories = false, regExp = /\.js$/)
// (创建了)一个包含了 demo 文件夹(不包含子目录)下面的、所有文件名以 `js` 结尾的、能被 require 请求到的文件的上下文。

const files = require.context('.', true, /\.js$/)
//console.log(files.keys()) // 返回一个数组['./components.js','./login.js']
let configRouters = []
files.keys().forEach(key => {
  if (key === './index.js') return
  // console.log(files(key).default)
  configRouters = configRouters.concat(files(key).default)  // 读取出文件中的default模块
})
export default configRouters      // 抛出一个Vue-router期待的结构的数组

Automated finished part, that part of how to write a business component?

export default [
  {
    path: '/richtext',
    noDropdown: true, // 是否有下级菜单
    name: 'Richtext',
    hidden: false, // 是否隐藏
    icon: '', // 图标
    redirect: "/richtext", // 如果要默认路由携带名称的话,就需要redirect
    component: () => import('@/views/frame/Frame'),
    children: [
      {
        path: '',
        component: () =>import('@/views/richtext/ReachText')
      }
    ]
  }
]

Route initialization This is our last step, it is used to initialize our route project

import Vue from 'vue'
import VueRouter from 'vue-router'
import RouterConfig from './modules'
import ToppingRouter from './topping'
import CommonRouters from './common'
Vue.use(VueRouter)
export default new VueRouter({
  // mode: 'history', // 需要服务端支持
  // base: '/',
  scrollBehavior: () => ({ y: 0 }),
  // the real routers
  routes: [...ToppingRouter, ...RouterConfig, ...CommonRouters]
})

之前我们创建完一个模块要手动的把这个模块import到路由文件声明的地方去使用。但是有了上面的index.js,在使用的时候你只需要去创建并抛出一个符合VueRouter规范的数组,剩下的就不用管了。import RouterConfig from './modules’已经帮你处理完了。
情景2
全局注册组件
当项目中需要全局注册很多个组件那么就要在main.js里面手动很多个Vue.component()。
这种情况下也可以使用require.context()来帮忙,把所有的公共组件放在global目录下面。
Here Insert Picture Description

import Vue from 'vue'

// 自动加载 global 目录下的 .js 结尾的文件
const componentsContext = require.context('./global', true, /\.js$/)
console.log(componentsContext.keys())
componentsContext.keys().forEach(component => {
  const componentConfig = componentsContext(component)
  console.log(componentConfig) // 返回Module
  /**
  * 兼容 import export 和 require module.export 两种规范
  */
  const ctrl = componentConfig.default || componentConfig
  console.log(ctrl)
  console.log('ctrl.name', ctrl.name)
  Vue.component(ctrl.name, ctrl)
})

通过node自动生成vue组件

每次新建组件的时候,都要创建一个目录,然后新增一个.vue文件,然后写template、script、style这些东西,然后新建一个index.js、导出vue组件。都是一些重复的操作,写相同的代码,既消耗体力,也浪费时间,就等于浪费美好的生命。
这个时候我们可以借助node,然后告诉node帮我生成的组件名称就行了。然后让node来帮我们写代码。
我实现这个功能主要要借助Node的fs和process。
1.安装一下chalk,这个插件能让我们的控制台输出语句有各种颜色区分。
chalk
主要注意一下它可以使用的一些颜色color。
在根目录中创建一个 scripts 文件夹,
新增一个generateComponent.js文件,放置使用node生成组件的代码
新增一个template.js文件,放置我们可自定义组件模板的代码。

在项目中优雅地使用svg

Reference in the future will be hot: SVG Sprite technology introduced
svg scalable vector graphics (Scalable Vector Graphics), as the name suggests is any change in size will not be deformed, are based on Extensible Markup Language (XML), he strictly comply with XML syntax and text format description language to describe the content of an image, and the image is therefore a resolution-independent vector graphics format, should more scenarios phone terminal, because of the large difference in resolution phone.
svg following advantages
1. arbitrary scaling
user can arbitrarily scale the displayed image, without damaging the sharpness of the image, and other details.
2. smaller file
Overall, SVG files to be much smaller than those files GIF and JPEG formats, so download quickly.
3. Super display
SVG image is always sharp edges on the screen, it's suitable for any screen resolution and clarity of print resolution, better help people with low vision
to use svg Steps
1. First build a name for the cc -svg-icon global assembly

<template>
  <svg  class="cc-svg-icon" :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>
<script>
export default {
  name: 'cc-svg-icon',
  props: {
    iconClass: {
      type: String
    },
    className: {
      type: String
    }
  },
  computed: {
    iconName () {
      return `#icon-${this.iconClass}`
    },
    svgClass () {
      if (this.className) {
        return `svg-icon ${this.className}`
      }
      return `svg-icon`
    }
  }
}
</script>
<style lang="scss" scoped>
.cc-svg-icon {
  width: 16px;
  height: 16px;
  vertical-align: middle;
  fill: currentColor;
  overflow: hidden;
}
</style>

2. Write automation index.js

const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', true, /\.svg$/)
requireAll(req)

3. Modify webpack.config.js
using svg-sprite-loader used to project svg processed:

const path = require('path')

function resolve(dir) {
  return path.join(__dirname, './', dir)
}

module.exports = {
  chainWebpack: config => {
    // svg loader
    const svgRule = config.module.rule('svg') // 找到svg-loader
    svgRule.uses.clear() // 清除已有的loader, 如果不这样做会添加在此loader之后
    svgRule.exclude.add(/node_modules/) // 正则匹配排除node_modules目录
    svgRule // 添加svg新的loader处理
      .test(/\.svg$/)
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })

    // 修改images loader 添加svg处理
    const imagesRule = config.module.rule('images')
    imagesRule.exclude.add(resolve('src/icons'))
    config.module
      .rule('images')
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
  }
}

Finally, in main.js introduced in Import '@ / iconsThe ' to
regard svg, Ali can go to the open source icon library iconFont
download.

gizp compression

Installation of compression-webpack-plugin plugin

cnpm install compression-webpack-plugin --save-dev
// or
yarn add compression-webpack-plugin --dev
// vue.config.js
const CompressionPlugin = require('compression-webpack-plugin')
module.exports = {
  chainWebpack: config => {
    // 这里是对环境的配置,不同环境对应不同的BASE_URL,以便axios的请求地址不同
    config.plugin('define').tap(args => {
      args[0]['process.env'].BASE_URL = JSON.stringify(process.env.BASE_URL)
      return args
    })
    if (process.env.NODE_ENV === 'production') {
      // #region 启用GZip压缩
      config
        .plugin('compression')
        .use(CompressionPlugin, {
          asset: '[path].gz[query]',
          algorithm: 'gzip',
          test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
          threshold: 10240,
          minRatio: 0.8,
          cache: true
        })
        .tap(args => { })

      // #endregion
    }
  }
}

Guess you like

Origin blog.csdn.net/qq_40639990/article/details/89960380