Intro If you have lint compliants as following when using ESLint( and plugins likeeslint-plugin-prettier) with Prettier, read this article. or Use semicolons in JavaScript In JavaScript, it is not mandatory to use a semicolon at the end of each line. However, I am opinionated with a semicolon to end each statement explicitly. I don't want to argue which is better. If you do not enforce semicolon usage (or omission) in any particular way, ignore this article. Code formater and beautifier tool Prettier is sticky to this style and enabled semi to true by default. Meanwhile, we usually combine a linter tool like ESLint to do static code checker, but ESLint has its own rules to format code which may not be consitent with Prettier. Different default semi rules However, ESLint's recommended rules don't like semicolons, and don't allow semicolons at the end of the code lines, and overrides Prettier's semi option setting. In the other word, the ASI(Automatical Semicolon Insertion) will not work even when we turn on Prettier's semi option as ESLint recommended rules turns it off by default. They conflict with each other. While using them together: When we run eslint to check the code, complaints come out as Prettier still expects semicolons while ESLint supressing the semicolons. This is really annoying. Turn on ESLint's semi rule So, what about turning on ESLint's semi rule in eslintrc.js? Yes, ASI is enabled, however, the linter still complains: The tooltip will appear on each semicolon after I apply the semi rule in the config file. I guess(I am not sure)…

2021年04月14日 0Comments 4307Browse 1Like Read more

There are many git commands that uses HEAD to operate. Some people say it is a pointer by analogy to the concept in programming language, but this is still vague. There are threads topic 1 topic 2 on Stackoverflow talking about HEAD, it may help us have a better understand of HEAD. However, having more knowledge of git core internals and concepts will make us better understand how git works as a version control tool, and I am trying to understand HEAD by learning more about git internals. Git is indeed a content-addressable filesystem. We can consider the core of Git as a key-value database. This means that you can insert any kind of content into a Git repository, for which Git will hand you back a unique key you can use later to retrieve that content. $ mkdir project && cd $_ # create and enter an empty project directory $ git init # this will initialize an empty database. $ ls -al # and we will find a hidden direcotry named .git .git $ ls -F .git # list the files or direcotries created in .git, including 5 directories and 3 files, and one file name is HEAD. branches/ config description HEAD hooks/ info/ objects/ refs/ $ ls -R .git/objects # and there are two empty folders in ./git/objects/ .git/objects: info pack .git/objects/info: .git/objects/pack: $ echo 'test content' > test $ git add test $ ls -R .git/objects # git add will generate a d6 folder d6 with a file inside it, the filename consitis of 38 digits…

2020年11月23日 0Comments 2095Browse 1Like Read more

I aliased the xampp start script in my shell rc file, so lamp in the below means sudo /opt/lampp/lampp, I am using Linux, while on Mac, the script locates at /Applications/XAMPP/xamppfiles/xampp Mysql start issue It started MySQL at first, after a second or two, it reported mysql daemon is terminated: Fix Way 1: Change the default mysql service port Edit mysql configuration file, find [mysqld] section (not the [client] section), change the default port number 3306 to another value. Or use the GUI tool to change: Way 2: Terminate the process taking port 3306 The reason why I cannot start mysql is due to I am running a mysql docker container which has already taken the port. So I am not able to start XAMPP's mysql before I kill the docker-proxy process or stop mysql container. Other XAMPP start issues and solutions As a matter of fact, all these issues are related to ports confliction: 1. XAMPP: Another Web Server is already running. If you run Xampp on Ubuntu, you may have apache2 installed and started by default, so: Or just change the Xampp's apache service default ports to other values instead of 80(http) and 443(https). 2. XAMPP: Another FTP daemon is already running

2020年09月24日 1Comments 9950Browse 3Like Read more

Redux Redux is a predictable state container for JavaScript apps. As state in application becomes increasingly complicated for SAP, there might be more different types of state to manage: local created data which is not persisted to the server, UI data like UI elements properties, routes, spinners, paginations which determines the UI display; and server returned and cached data, etc. Redux attempts to make state mutations predictable for complicated application state by imposing certain restrictions on how and when updates can happen. These restrictions are reflected in the three principles of Redux. Three principles of Redux Single source of truth for application state: The global state of application is stored in an object tree within a single store; State is read-only: The state cannot be modified directly by views or network callbacks, the right way to mutate is to dispatch an action to notify the reducer to process. As all changes are centralised and happen one by one in a strict order, there are no subtle race conditions to watch out for; Changes are made with pure functions: Change state via reducers. A reducer is a pure function with two characteristics: It returns same result when the input parameters are the same; the only dependency of the returned data are the input parameters, and the result is consistent regardless of where/when it is called. no side-effects: the function will not do jobs like: modify external data, render DOM elements, execute network requests, IO operations. These characteristics provides assurance to make state predictable. Three core concepts of Redux Actions: an action…

2020年09月05日 0Comments 2591Browse 1Like Read more

Ways to share data between Vue components without middleware component props: parent --> child $parent, $child, ref and $refs: access parent, child or referred component data emit events: child (this.$emit('event_name', data)) ---> parent ( @event_name="eventHandler") $attrs/$listeners: pass comoponent props(v-bind) or events(v-on) downside level by level provide/inject: ancient component provides shared data for all the descendant components to use. Event Bus, $emit and $on: use an empty Vue instance as the global shared event bus. By means of events carried by the event bus, parent, child, sibling components can share data without restriction. or add Event Bus to Vue prototype property in main.js Web Storage API: HTML5 provides localStorage and sessionStorage API for data persistance for different scale and period. Thus, the page components can call these APIs to read/write data for sharing. slot-scope: Put slot-scope into template tag, and bind the template with data exposed by the child component. This allows the parent to render child component with different UI styles or data by the template slot. By this way, the parent component can used data inside the child component and render it with styles from parent itself. This is a very limited scope data sharing between parent and child components. Why and When to use Vuex? Ways to communicate between components mentioned above can be used according to different rscenarios. Some ways are strictly restricted by components relationship and are not flexible for global data sharing; Athough the Event Bus provides a lightweight way for share data globally, it's not easy to manage events and state when it's used…

2020年09月03日 0Comments 2588Browse 1Like Read more

The official definition of GraphQL: A query language for your API. GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools. My underdtanding of GraphQL The initial impression of GraphQL to me is that it is one type of SQL language for images, however, this is completely wrong after I read the docs, and I get a better understanding of it by doing some practice. It's not used for picture/images queries, it is just a new open-source data query and manipulation language for APIs, originally developed by facebook. Most of developers know the popular REST API, and there are also other types of API specifications like JSONAPI, SOAP as well. GraphQL query language is used by clients to query data from a GraphQL API service. It's a API query language, not a database query language like SQL. Thus, it doesn't mean that the client uses GraphQL to query data from a database, it queries data from the GraphQL service. It's also a runtime, this means GraphQL can play a role as a server-side service layer for executing the client queries, by using a type system defined for the data. In fact, it isn't tied to any specific database or storage engine and is instead backed by the existing code and data at…

2020年08月28日 0Comments 2456Browse 0Like Read more

ECMAScript 2020, the 11th edition, introduces the Promise.allSettled, a new Promise combinator that does not short-circuit; And Promise.any is scheduled to be supported in ES2021 standard. The two new features are inroduced five years after Promise.all and Promise.race functions which were introduced in ES6(2015). The four combinator functions will make a more complete implementation of Promise for different asynchronous use cases. Status of a Promise A settled promise means that it is not pending, i.e. it is either fulfilled or rejected. Promise.all The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input's promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error. Promise.all will shortcut on the first rejected promise, so we cannot get any resolved data/status once a promise is rejected even when some promises have already been resolved. In order to get all the results(including status) of each promise after call Promise.all, we need to add a new function to return a new promise( promise.then() ), and return a new value with the status known in promise.then (either through the resolved branch or the rejected branch). Then iterate the results and filter the status after call Promise.all. Promise.allSettled The similarities and diffrences with Promise.all: They both receive an array of promises, and return a…

2020年08月25日 0Comments 2476Browse 0Like Read more

Scenario and issues If we have internal page data to update, we can implement it by calling component methods to update when the event is triggered, other than to do a whole page re-render. However, we need to call $router.push() method to navigate to a destionation page from another one, and this is my case: I make a component(a button) which is used in different pages to navigate to page A, the component calls $router.push() to jump to page A , Meanwhile, this component is also used iniside page A, that means it's internal route jump to update a part of content in page A; I use the named route with params binding the changed data page A needs in $router.push(). By this way, page A can always get data from the named route and doesn't need to take care of these two different types of navigation. But the issue comes: I cannot do an internal update of page A when the I trigger the component in page A; To watch $route or use beforeRouteUpdate hook to capture changes in page A is not working. The route navigation doesn't trigger these functions, even when the passed params are changed in push(). More details about $route.push() method After trying some ways I fixed this issue and found more details about push() method, which may not be clearly elaborated in the official docs. push() methods returns a promise, so we can catch the error to get reasons when it fails. By adding try catch, I got this: Error: Avoided redundant navigation to…

2020年08月15日 0Comments 5983Browse 1Like Read more

I experienced the issue(mentioned in the article title) when using the push method of Vue router to redirect to a new URL when clicking on some anchors today. Usually, there are two typical ways to go to the new page(route) via using push method: The params passed by the first way(use params)will not be shown in the URL, so if we want to hide more details of the page, it's a better way. However, when I use this way, the web page turns out to be blank when I press F5 to update, as the page cannot get the route parameters which are used as data request params. The route params won't be persistant via this way, they will not exist when page reloads. This is becuase the named route is not pushed into history records, the browser is not able to find a record to reload. Ways to fix To fix this, we can use the second way(use query) to push route params and the parameters will persit even if a F5 update happens. However, the parameters will show up in the URL, and object parameters with several level-depth will turn into long garbled code. I don't want this as I hope to keep the URL address clean. How about the other ways to fix this? I tried to create another state in the Vuex store to keep the data, but this doesn't work as well unless I use the plugin vuex-persistedstate. I checked its github repo and find it uses localStorage, sessionStorage or cookie to persist data. so…

2020年08月12日 0Comments 2044Browse 0Like Read more

A Router is commonly known as a hardware device for computer networking, we all have wired or wireless routers at home, offices or other locations for devices networking. Router in Web Application We'll get different page content from a site when we change the string after the domain name in a URL, or click the menu items of a webpage. This navigation feature of web apps is done by a Router middleware of the modern web app as well. Accessing to a specific URL path will trigger a respective route response from the web app's routing table, the web app usually uses a specific Router middleware to manage all the routes, no matter whether the routing pages are rendered from server-side or client-side. For example: Backend routing: in Node.js, we can implement routes by express.js, and each endpoint will render the template to html for client-side, each time accessing to a new path(route), there will be a new request sent to the backend. Front-end routing: React.js and Vue.js have their own favorable routing middleware from their ecosystem: react-router and vue-router respectively. The front-end routing is always used for SPA(single page application) website, as it prevents un-neccessary requests to the server, the change of a route accessing will lead to only partial internal view change inside the page, which is usually related to a specific component view of the web app, and whole page rendering is avoided. Understanding Routing mechanism in SPA by Analogy We don't care whether it is called as a path, a uri, or a route when browsing…

2020年07月27日 0Comments 1645Browse 0Like Read more
12