Writing in the front

A programmer who is not “lazy” is not a good programmer. — — — — — — — – lu xun

Start with the wheel

Believe that each a programmers don’t want to spend too much time to build it is not necessary to build the wheels (skip) purely for the sake of learning, after continuous growth and experience accumulation, we have to make some meaningful can use for a long time “wheel” (because there is no ready-made, ha ha 🤣), namely everybody will beg the code reusability.

This article focuses on how I saved dozens of minutes each time I initialized a Vue project.

Let’s recall the steps to initialize the Vue project:

vue init webpack project-name

npm/cnpm install ….

Modify the WebPack configuration

Delete the VUe-CLI initialization page

Modify main.js to configure third-party plug-ins

Create a bunch of folders

And so on…

All in all, this is a really bad experience, unless some people just like to repeat the boring process. PS: Some people may also scratch a copy of the previous project and start a new project by deleting, editing, and tinkering, but this is not an elegant way. 🤔

What is scaffolding plus

When we learn or borrow foreign resources, we mainly take their essence and discard their dross. Therefore, on the basis of VUE-CLI3, we first solve the problems that are easy to be solved, and then further improve and increase our own needs, so as to meet our long-term needs.

In addition to sharing how to build a project framework, this article will also share the basics of using Vue’s advanced concepts Mixins, Directive, filters, vuEX management, and more.

Let’s start with the requirements

  • Manage static resource storage locations in a unified manner
  • Public style management, font library, third-party script unified management
  • Sass out of the box
  • Unified Router Management
  • Vuex manages stores in a modular manner
  • Interfaces manage URLConfig in a unified manner
  • Common Directive base configuration Directive
  • Global mixing of base configuration mixins
  • Custom component exports and imports
  • Command line package compression
  • The command line pushes the local repository in one step
  • Automatically obtain the LAN IP address and open the LAN Server
  • And so on…

Fulfill the requirements

Static resources, public style, router and other basic components of the project may be different from each other. Everyone has their own habits and styles of storage locations. Here I show my project components to make it clear to everyone. 😶

How to implement global introduction of SASS

Create common.scss under assets/ SCSS and then modify utils.js to commom.css. You don’t need to import it in main.js or other projects

/ / 57 line
function resolveResouce(name) {
    return path.resolve(__dirname, '.. /src/assets/scss/' + name);
}
  function generateSassResourceLoader() {
      var loaders = [
       cssLoader,
       // 'postcss-loader',
       'sass-loader',
       {
           loader: 'sass-resources-loader'.options: {
             resources: [resolveResouce('common.scss')]}}];if (options.extract) {
       return ExtractTextPlugin.extract({
         use: loaders,
         fallback: 'vue-style-loader'})}else {
       return ['vue-style-loader'].concat(loaders)
          }
  }
  // Notice here
  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateSassResourceLoader(),
    scss: generateSassResourceLoader(),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')}Copy the code

Complete the above configuration, and you can go crazy on any page of the project.

Unified interface management

If it is a project involving many people, it is necessary to manage the interface in a unified way. Of course, even one person is very necessary, because in this way, a small interface change at the back end will not affect the whole system.

Configuration reference form

// Use the proxy address of proxyTable under config
var BASE_URL = '/api';
var isPro = process.env.NODE_ENV === 'production'
if(isPro){
    BASE_URL= 'http://113.113.113.113:8011'  // Address in the production environment
}

const UrlConfig = {
  getUserInfo:BASE_URL +'user/getinfo'.// Get user information
}
export default {
  UrlConfig
};
Copy the code

One way to use it is to mount UrlConfig to the Vue prototype in main.js

import URL_CONFIG from ‘@/assets/js/urlConfig.js’;

Vue.prototype.$url = URL_CONFIG.UrlConfig

Then use it on the page

this.$url.getUserInfo

In this way, the interface can be managed in a unified way, and there is no need to change the base_URL every time you go online (except in production environment). At the same time, there is no need to generate multiple interface management forms in the process of multi-person collaborative development, which reduces the potential for code merge conflict.

Mixins management

To put it simply, Mixins are codes that can be reused. In a project with a large number of functional modules, there are inevitably many repeated methods, and many methods can help us extract these reusable codes. But one of the nice features Vue offers is Mixins, which can use any methods we define in the page (methods, data, Mounted, etc.).

Define a formatTime.js mixin and use it on pages where we need to convert timestamps, for example:

const formatTime = {
     methods: {
     // Methods like timestamp conversion work for most projects, either in filter or computed, depending on the application scenario
      formatTime(date, fmt) {
          if (/(y+)/.test(fmt)) {
              fmt = fmt.replace(RegExp. $1, (date.getFullYear() + ' ').substr(4 - RegExp. $1.length));
          }
          let o = {
              'M+': date.getMonth() + 1.'d+': date.getDate(),
              'h+': date.getHours(),
              'm+': date.getMinutes(),
              's+': date.getSeconds()
          };
          for (let k in o) {
              if (new RegExp(` (${k}) `).test(fmt)) {
                  let str = o[k] + ' ';
                  fmt = fmt.replace(RegExp. $1, (RegExp. $1.length === 1)? str :this.padLeftZero(str)); }}return fmt;
      },
      padLeftZero(str) {
          return ('00'+ str).substr(str.length); }}},export default formatTime
Copy the code

Then use it on the page

Import formatTime from ‘path’

mixins:[‘formatTime’]

Even if the code with duplicate methods is removed from the local page, of course, the above examples only briefly illustrate the basic use of Mixins, such as converting timestamps and more elegant methods, but how to use them will have to be built in the context of the scene.

The other is a method that can be used on every or most of the pages in the project, so consider mounting it to the prototype for easier use. For example, a globally used Mixins has the following methods:

loadPage(path,params){
        this.$router.push({
          path:path,
          query:params
        })
}
Copy the code

So we’ll introduce it in main.js

import globalMixins from ‘@/components/common/mixins’

Vue.mixin(globalMixins )

Directive management

Global directives are the ways that Vue allows users to customize common low-level operations on the DOM, such as V-for and V-if directives. What it can do for us. For example, if we need to unify the background colors of various elements on the page, as well as the colors of primary, Danger, error and similar themes, we might write a set of style variables in sass/less and define class to control the uniform colors.

Let’s implement it with a custom directive:

let mydirective = {}
mydirective.install = function (Vue) {
  // Background color
  Vue.directive('bg', {
    bind(el, binding) {
        el.style.color = '#f6f6f6'; }}),/ / theme color
  Vue.directive('color', {
    bind(el, binding) {
        el.style.color = '#42E5D3';
    }
  }),
  Vue.directive('theme'.function(el){
    el.style.color = '#42E5D3'
    el.style.background = '#f6f6f6'
  }),
  // Use a random background color before loading the image
  Vue.directive('img', {
  inserted:function (el, binding) {
    var color = Math.floor(Math.random()*1000000);
    el.style.backgroundColor = "#" + color;
    var img = new Image();
    img.src = binding.value;
    img.onload = function(){
      el.style.backgroundImage = 'url('+ binding.value +') '}}})}export default mydirective;
Copy the code

Imported and mounted globally in main.js

import globalDirective from ‘@/components/common/directive’

Vue.use(globalDirective )

Then we can use v-for, V-if and other methods to use v-bg, V-color, v-theme in the page. Of course, some people might say that custom directive is a bit of overuse. Sass and unified class to manage the theme of the project and other basic configuration is also good. Or that word, combined with the scene to talk about business is not rogue, 😉 of course, there are more advanced use of custom instructions, you can refer to the Vue document to achieve more of their own business logic.

Command line package compression

This demand may only be my personal needs, because my goal has been to use the keyboard as far as possible not to use the mouse to operate the computer, the command line operation that is beyond description 😊, because I like Linux, although I am a front-end, less nonsense said to achieve.

First we need compressing to create a zip. Js file in the build folder

The most basic way to use compressing as a zip file is like this,

compressing.zip.compressDir('dist'.'dist.zip')
  .then((a)= > {
	process.exit()
  })
  .catch(err= > {
    console.error(err);
  });
Copy the code

But can we compress the file every time and make the file name more identifiable when executing the command, otherwise it will be dist. Zip every time, wouldn’t it be embarrassing if we need to back up the file?

To implement the command line prompt and input filename, use node stdout and stdin as follows:

process.stdout.write('Please enter the compressed file name:')
process.stdin.resume()
process.stdin.on('data', (chunk) => {
	chunk = chunk.toString().trim();  // Enter the name of the file
    // Enter what you want to do
});
Copy the code

One more requirement, sometimes I don’t want to enter a file name, but I also want to compress the file name into a uniform format and try not to duplicate the name.

Finally, to achieve this more personalized requirements, the code on 😁

#! /usr/bin/env node
process.stdin.setEncoding('utf8');
const compressing = require('compressing');
const prefixName = 'wvue-cli_';  // Default compressed package prefix
function formatDateToString(date){
	var year = date.getFullYear();
	var month = date.getMonth()+1;
	var day = date.getDate();
	var hour = date.getHours();
	month < 10 ? '0' + month: month;
	day < 10 ? '0' + day: day;
	hour < 10 ? '0' + hour: hour;
	return month+day+hour;  // Absolute non-repetition can be directly accurate to milliseconds
}
function toZip(name){
	compressing.zip.compressDir('dist'.`${name}.zip`)
  .then((a)= > {
    console.log( `${name}.zip`+'Saved to project directory! ');
		process.exit()
  })
  .catch(err= > {
    console.error(err);
  });
}
const time = formatDateToString(new Date());
process.stdout.write('Please enter the compressed file name:')
process.stdin.resume()
process.stdin.on('data', (chunk) => {
	chunk = chunk.toString().trim();  // Enter the name of the file
  var	name = chunk || prefixName + time;
	toZip(name)
});
process.stdin.on('end', () => {
  process.stdout.write('the end');
});
// The compressed file name is in the form of wvue-cli_062101.zip
Copy the code

Then add it to our package.json as follows

“pack”: “node build/zip.js”

npm run pack zipname

The command line submits the code in one step

After completing a requirement or fixing some bugs, we need to submit the code once, which may require git add git commit git push,but we are lazy. (Please do not tell me about graphical tools or plug-ins in the editor, I need command line 🙄)

Here we need shellJS. This plug-in is installed in the dev environment of our project by default in VUe-CLI, so we don’t need to install it by ourselves. The implementation is as follows

#! /usr/bin/env node
var name = process.argv[2] | |'auto-commit';
var shell = require("shelljs");
var exec = shell.exec;
var echo = shell.echo;

if (exec('git add .').code ! = =0) {
  echo('Error: Git add failed');
  exit(1);
}
if (exec(`git commit -am "${name}"`).code ! = =0) {
  echo('Error: Git commit failed');
  exit(1);
}
if (exec('git push').code ! = =0) {
  echo('Error: Git push failed');
  exit(1);
}
// Green font
echo('-e'."\033[0;32m git success \033[0m"+`${name}`);

Copy the code

Then, like a zip file, add methods to package.json to execute the command.

“push”: “node build/push.js”,

NPM run push “fixed some bugs”

At this point, a more comprehensive scaffolding plus is finished, we have achieved some of the development process is very common and practical requirements, from the code can also be one step faster than others, at least do not waste time in the initialization project this tedious and emotional waste of things, because we are lazy 😏.

The last

Articles in the realization of the function of some process cannot complete display due to space limitations, there are some methods such as custom global components did not reflect that it is, I’m sorry, but if there is any communication or reference can go to a lot in my code, or directly by NPM install scaffolding, I bronze player if any Suggestions please comment ~ 😊

Making the address

Github.com/vannvan/wvu…

NPM installation and use method

npm i wwvue-cli -g

wwvue init project-name

Finally, thank you to all the developers who walked by for taking the time to watch me pull off all this crap ~🤡

(PS: there are many Easter eggs in the tool that are not mentioned in the article, which can provide many solutions for novices. Welcome to dig down the code for reference!)