Articles under the discussion of classification technology

Recently submitted PR Comments by leaders LGTM A capital one It's in the brain. The abbreviations were checked and sorted out as follows:

  • PR: Pull Request. Pull requests, which have submitted code to open source projects, should all know
  • CR: Code Review. Code review
  • LGTM: Looks good to me. Yes, we can merge
  • TL;DR: Too long;Didn't read. The old woman's foot wrap.
  • TBR: To be reviewed. Give the labor review code!
  • WIP: Work in progress. Writing at the beginning of the title as an identification function is not completed
  • RFC: Request for comments. We usually hear that some policies want to be carried out. If the government wants to carry out these policies, the government will issue a draft for comments. The general meaning of open source projects is to ask for comments, which are used as task memoranda
  • ACK: Acknowledge. Confirm some contents, functions and tasks

A strange bug was found in WSL today. Shouldn't sh be called directly under WSL

use Create React App Create a react application, yarn start Now, output Starting the development server... And then throw one Error: spawn cmd.exe ENOENT I wonder how this WSL is called to windows again cmd.exe It's weird. Hey

go create-react-app Turn it over Source code , executed an operation to open the browser and found that open Class library judgment windows Not just checking process.platform Yes, by the way wsl and docker The environment is also used as the judgment condition. The following splicing command is the final source of all evil

 root of all evils

Two ways to fix this bug

  1. take /mnt/c/Windows/System32 Add back the WSL environment variables so that you can pull up the default browser
  2. react-scripts/scripts/start.js Note it out openBrowser(url.localUrlForBrowser);

This is really an Indian bug, 🤮 The directory cannot be deleted

 rm: can't remove XXX: No such file or directory

After searching through the docker's documents and issues, this seems to be related to the ftype of the XFS partition. According to other people's solutions, it can't be solved 🤮 Yes

In the end, it's better to reduce two versions. Of course, it's OK to reload the system Dafa

JQuery just to understand the core of the exchange of his friends today. (it seems that I have been pigeoning for a long time.)

By the way, which CDN service provider can find a jQuery file to open. I use version 1.2.3 as an example. The latest version is similar, with only two or three changes https://cdnjs.cloudflare.com/ajax/libs/jquery/1.2.3/jquery.js

Source code analysis

17-20 lines Pass in the selector and return the init method of its own new. I guess you haven't used it $() The second parameter is omitted here

 var jQuery = window.jQuery = function(selector) {
    return new jQuery.prototype.init(selector);
}

Lines 26-27 This is why it always starts with $and is mounted under the window object, which is a global variable

 // Map the jQuery namespace to the '$' one
window.$ = jQuery;

Lines 36-547 Get rid of what we don't need, keep the core, stay init Method, the internal judge of jQuery instance and selector is made. Here we ignore and simplify

 JQuery. FN = jQuery. Prototype = {init: function (selector) {var nodes = document. Queryselectorall (selector); 
 for (VaR I in nodes) {this [i] = nodes [i]; 
} return this; 
} 
 / / omit 100000 words 
}}

549 lines In the previous paragraph, the jQuery prototype chain is passed to the init method prototype under the jQuery prototype. Looking back at the new code, it is very clear

 jQuery.prototype.init.prototype = jQuery.prototype;

Complete implementation

If you continue to add functions to the jQuery prototype, it will be very close to the original version of jQuery. Here I will simply implement it text() method

 var jQuery= function (selector) {
        return new jQuery.fn.init(selector);
    }

    jQuery.fn = jQuery.prototype = {
        init: function (selector) {
            var nodes = document.querySelectorAll(selector);
            for (var i in nodes) {
                this[i] = nodes[i];
            }
            return this;
        },
         element: function (callback) {
            for (var i = 0; i < this.length; i++) {
                callback(this[i]);
            }
        },
        text: function (content) {
            if (content == '' || content) {
                this.element(function (node) {
                    node.innerHTML = content;
                })
                 return content;
            } else {
                return this[0].innerHTML;
            }
        },
    }

    jQuery.prototype.init.prototype = jQuery.prototype;

    window.$ = jQuery;

end

In fact, the core is not complicated at all. I like the implementation of plug-ins. I think most of their functions are implemented by plug-ins. The ingenious design of the tool itself and the convenience.

In the traditional page production, jQuery is very comfortable to use, but the emergence of MVVM has changed our way of thinking. We only need to pay attention to business logic, do not need to manually operate DOM, and do not need to pay attention to the synchronization of data status. It is much easier for project management.

If there are simple requirements on a single page, jQuery still has a place to use, MVVM can only be added to the trouble.

Share some of the latest gadgets

When you log in with your mobile phone number, you can see that there are two buttons (get the verification code and log in) and two boxes (input the mobile phone number and input the verification code) by analyzing the page

So we have the following device (we don't look at the specific functions, we just look at the structure)

 < template > 
 < div class = "login wrapper" > 
 < div class = "title bar" > login < / div > 
 < div class = "wrapper phone wrapper" > 
 < span class = "title" > mobile number < / span > < input class = "input phone" type = text "placeholder =" mobile number "> 
 < / div > 
 < div class =" wrapper code wrapper "> 
 < span Class = "title" > captcha < / span > < input class = "input code" type = "number" placeholder "> 
 < div class =" send "> get verification code < / div > < / div > < div class =" wrapper BTN wrapper "> 
 < div class =" input BTN "> login < / div > < / div > < / div > < / template > login

At this time, you can start to write the logic. It is also a simple analysis. To login, you need to click to get the verification code, and you can count back the number of seconds. In other words, you can dynamically modify the text. You can check and limit the number of mobile phone numbers and the number of verification codes.

It's almost like the following

 < template > 
 < div class = "login wrapper" > 
 < div class = "title bar" > login < / div > 
 < div class = "wrapper phone wrapper" > 
 < span class = "title" > mobile number < / span > < input class = "input phone" type = text "placeholder =" mobile number "
: value =" phone "
 ref =" phone "v-on: change =" changephone " V-on: input = "changephone" > 
 < / div > 
 < div class = "wrapper code wrapper" > 
 < span class = "title" > verification code < / span > < input class = "input code" type = "number" placeholder = "verification code" 
: value = "code" 
 ref = "code" v-on: change = "changecode" v-on: input = "changecode" > 
 < div @Log in < / div > < / div > < login < / div > < login < / div > < login < / div > < login < / div > < login < / div > < login < / div > < login < / div > < login < / div > < / div > < / div > < / div > < div > < / div > < div > < / template > < script > < script > < name: Name: "loginpphone", data() {data() {return return return return {photo photo photo photo > < 10 < script > < script > < script > < name: "loginpphone", "data(), data() {return return return {{photo photo photo {photo photo photo > < 10 < script > < script > < name:" loginpphone "," data(), data(), data() {data() return {return {ne: ', / / the mobile phone number in the input box Code: ', / / the verification code 
 codetext:' get verification code ', / / the countdown display text 
 timingboard: 60, / / countdown 
 timer: null, / / a timer is used to count down the verification code 
}, 
 methods: {logincode() {}, //Check the length of {}, {change code () / / check the length of {code (), {change code ()]

These are enough for you to implement a basic mobile phone login interface. For complete code, please click below Gist link

For complete code, refer to: https://gist.github.com/flxxyz/64ceb06a0754d67a771b3e3e7dc94d48

To be honest, I haven't seen the API after using Vue for such a long time. I found it by accident these days Vue.directive It's a good look

It's always used here Vue.use(ElementUi) Where to use Vue.use(axios) , has been staying at the level of usage. Just in time, I found that the consumption of writing markdown parsing instance seems to be a little high, and it may be more convenient to directly process it into instructions (it is really much more convenient, and there is less writing of a bunch of methods)

Briefly describe the process

During the mount life cycle of the component rendering an article, it will query whether there is a corresponding article in the local record. If it does not exist, it will request online search, otherwise 404.
This article is about markdown, considering that the front-end processing can be directly parsed out (after all, the front-end performance is over 233), reducing the back-end logical processing burden, and what consistency is not needed to be considered now.
Use the downmark parser marked The logic is as follows

 //Import Vue from 'Vue' / import app 'import markdown from'. / markdown ';; / / inject markdown parser into markdown parser Vue. Use (markdown. Install) Vue. Prototype. Prototype. $marker = markdown. Markdown = markdown.marker 
 new Vue ({store, 
 router, 
 render: H = > H (APP) 
 H (APP) 
 Vue. Use (markdown. Install) vue.prototype. $markd = markdown.markdown.marker = markdown.markdown 
 new Vue ({store, 
 router, 
 render: H = > H (APP) (APP) 
 H (APP) 
 H (APP) 
 H (app) 
 $mount (' ා app ')

Integrated marked and exposed as plug-ins

 //markdown.js

import marked from 'marked'
import('highlight.js/styles/atom-one-dark.css')

marked.setOptions({
    renderer: new marked.Renderer(),
    pedantic: false,
    gfm: true,
    tables: true,
    breaks: false,
    sanitize: false,
    smartLists: true,
    smartypants: false,
    xhtml: false, 
    highlight(code) {
        return require('highlight.js').highlightAuto(code).value;
    },
})

let install = (Vue) => {
    if (install.installed) return;
    Vue.directive('markdown', {
        bind: (el, binding, vnode) => {
            el.innerHTML = marked(binding.value)
        },
        update: (el, binding,  vnode) => {
            el.innerHTML = marked(binding.value)
        }
    })
}

export default {
    marked,
    install,
}

Use on label v-markdown instructions

 //This is an interface for finding articles = function() {return new promise ((resolve, reject) = > {resolve (ID)})}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 
export default {Name: "test", 
 data() { Return {article: ', 
 isnotfound: true, 
}}, 
 methods: {handlerarticle (ID) {
 / / find local article 
 let a = this. Findarticle (ID, async (ID) = > {return away this is an interface (ID); 
})              if (a == null) {
                    return 404;
                }

                return a;
            },
            findArticle(id, callback) {
                // let res = '## Test';
                let res = null;
                if (res === null) {
                    return callback(id); Use {this "} to find {this"} to find the error; this. Article = a; / / save the markdown content to the variable 
}} 
 < / script > directly

For complete code, refer to: https://gist.github.com/flxxyz/93e009d32ecd7e0c6785a52571577cd7

I bought an alicloud light server and switched to foreign lines with 5m bandwidth to reduce the packet loss probability. It's said that the online service of Hong Kong service is about to come out. I don't know how the online quality will be

Firewall relay chestnut

 #Port port = port = port = port: proto = TCP: TCP: topport = port: Port: Port: Port: toaddr = address of yogurt: permanent, port: firewall-cmd -- add-masquerade -- permanent, firewall-cmd -- add-forward-port = port = port: Port: Port: Port: Port: Port: Port: Port: Port: Port: Port: Port: Port: Port: Port Port: Port: Port: Port: Port: Port Port: port port port: port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port port he# Reload firewall CMD -- reload

Recently, I've been playing with golang recently. I put all online data in redis. The previously written configuration is not suitable. Hot loading is the king's way!

As the saying goes, a programmer who can't search is not a good programmer

After observing the writing methods of other big men, most of them are adopted Timer + goroutine Realized. It's not difficult. Start code

Configuration file structure

If our configuration file is a JSON file, it should be like this

 // conf.json
{
  "host": "127.0.0.1",
  "port": 6379,
  "passwd": "",
  "db": 0
}

The first thing is to write a structure exactly like it

 //JSON configuration file structure 
 type content struct {host string ` JSON: "host" '
 port Int ` JSON: "port"' 
 passwd string ` JSON: "passwd" '
 DB Int ` JSON: "DB"'}

If it is not safe to continue to write operation functions on this structure, serialized JSON is also a direct operation pointer. Before they split their trial and error, and finally let them together 233

Optimize structure

The file name, synchronization lock, last modification time and configuration file structure are integrated together

 //Configuration structure 
 type config struct {file string 
 lastmodifytime Int64 
 lock * sync. Rwmutex 
 data interface {}}}

Write factory functions for instance configuration (this is a conventional rule. You can verify the specific source by yourself. It has many advantages)

 func NewConfig(filename string, data interface{}) *Config {
    conf := &Config{
        Filename: filename,
        Data: data,
        Lock: &sync.RWMutex{},
    }

    conf.parse()

    go conf.reload()

    return conf
}

Here, the configuration structure is configured with default parameters. The external input parameters are The file name of the configuration file and Configuration file structure Here, the data type is the interface type. The advantage is that Config Can be independent, code Multiple reuse We also used it conf.parse() Method, parse the file for the first time, go conf.reload() Method starts a goroutine run separately (see the following for specific effects), and the result of course returns to the ontology

-Read the rest-