Recently wrote a lot of articles, but very love post, until recently I use notion set up my blog, to rediscover the original intention of writing articles, in recent years has been committed to the backend, this tutorial is written I used to idle the front-end architecture, the bloggers all migration to the notion that finishing merger, by the way, It has been two years since we completed this tutorial based on vue2.0. For those of you who are professional, it may be a little outdated

My notion online blog: niubility. Me

Migration is a physical work, interested students, I can create a tutorial, notion can be seen

For this series, I have adopted the current mainstream technology stack

Grasp of the overall outline

This series of articles I try to take care of the front-end students and back-end students, not interspersed. As far as possible according to the front-end – back-end – deployment – operation and maintenance, of course, the midway involves cross-domain, Rest, oAuth2.0 before and after the coordination is still unable to avoid the incidental.

Such as:

This kind of directory reading may be very uncomfortable for students who only master the front-end/back-end technology stack, or students who just want to see the back-end/front-end/operation and maintenance. I will revise the outline to avoid this problem and proceed step by step.

You will learn

  • Learn more about pre – and post-separation and understand common architectures

  • Build and optimize front-end and back-end projects

  • Selection of front-end and back-end technologies

  • Tips to improve productivity during development

  • N solutions across domains in different scenarios

  • A few good habits increase debug’s power

  • Hybrid develops its own APP on the front end

  • Optimization of front end SPA mode

  • Learn to crawl for the resources we want

  • How do back-end architectures transition to microservices

  • How to deploy microservices using Docker

  • How to maintain the operation of the project

How to create from zero a separation of the Internet before and after the mainstream WEB project, I sincerely hope I can help you.

Part 2: Looking at the history of the WEB

I have unconsciously experienced half of the historical evolution of the WEB during my study in school and several years of work. I have a better understanding of the development of the WEB in recent years.

Evolution is not easy, but it is inevitable, because people always want to improve.

History of the WEB

First, the founder of the Mountain – Stone Age

A static web site

This is Apple’s website in 1997, and the website at that time was more like a web page, like a flashy color newspaper. It was pure HTML, and every page existed on the server, whether you visited the page or not.

CGI technology

Later, a more technical web site might run a small piece of code through CGI Perl to interact with a database or file system. Such as:

This is a1998In Google, in order to achieve search criteria, it is impossible to use a lot of manpower to stackA static page, so use this way “curve to save the country”, butCGIIt’s not very scalable: a new process is assigned to each request, it’s not secure (using file systems or environment variables directly), and it doesn’t provide a structured way to construct dynamic applications.

Static sites are the most popular with search engines, because they are relatively fixed, so SEO is very easy to do, and I guess this is one of the reasons why most document sites are static.

Too bad I didn’t get to see it with my own eyes

Two, predecessors planted trees – civilization era

Asp and JSP

Around 2005, Microsoft’s ASP and Java Server Pages [JSP] technologies successively emerged, replacing CGI, enhancing the security of WEB and Server interaction, and making it easier to use, but with the complexity of each company’s WEB business, shortcomings are gradually exposed:

1, single technology, difficult to maintain

A JSP page consists of HTML code and embedded Java code, using a common JSP snippet as an example:


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+": / /"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
    <%@ page import="com.zifangsky.OnlineFriend.model.article.ShowByPage"%>
<jsp:useBean id="showAllTitle" type="com.zifangsky.OnlineFriend.model.article.ShowByPage" scope="session"/>
Copy the code

JSP = HTML+Java

The above code HTML is heavily coupled with JAVA code, which can act as part of the server on the client side after being compiled by JSP. This makes it difficult to understand the role of the server and increases the complexity of debugging. To make the business a little more complicated, think about it: There’s so much Java code in THE HTML that it’s a pain to develop and maintain.

JSPS, like Java servlets, are executed on the server side and usually return an HTML text to the client. Every time we requested data and loaded content, the server returned the DOM for us after dyeing, which greatly reduced the flexibility of our website development. In this case, in the same year: Ajax became popular.

The emergence of AJAX

Why did Ajax catch on in 2005? Ajax wasn’t invented in 2005, it was invented in 1999.

In 1999, Microsoft released Internet Explorer 5, which for the first time introduced a new feature that allowed javascript scripts to make HTTP requests to servers (the original of today’s infamous ActiveX). The feature didn’t get much attention until the launch of Gmail in 2004 and Google Map in 2005

What did Google do? In 2005, Google made AJAX popular with Its Google Suggest, which went something like this:

Technology, now common, quickly exploded the technosphere to achieve: Since then, AJAX has become a synonym for scripting to initiate HTTP communication. The following year, W3C also released AJAX international standard in 2006

Conclusion:

Subsequently, a variety of JSP ASP improved template engine, a new way of interaction is also springing up. In addition, JAVA as a server has also emerged such as Struts, Spring, Hibernate, the older generation of frameworks, the use of back-end MVC to build WEB applications more sound, WEB services are gradually from the Stone Age to the age of civilization.

3. Simplify complexity – Industrial Revolution era

As time flies, there are several trends in front and back.

The front-end development

The mobile terminal

The mobile phone has developed a little bit, and the web has differentiated between web and mobile applications, but mobile is limited to the technology of the mobile industry at the time and has been slow to develop.

The emergence of the Jquery

A very popular JavaScript library, jquery, can quickly build dynamic and beautiful Web applications, perfectly encapsulating Ajax and making web development elegant for developers.

The prototype of the SPA

With the formal introduction of Ajax in civilization era and the extensive Application of CDN for static resource storage, SPA (Single Page Application) emerged, Backbone EmberJS AngularJS and other front-end frameworks emerged. However, in terms of supporting technologies at that time, SPA was not an easy path: SEO problems, excessive PAGES in SPA, VIEW binding in complex scenes, etc., were not well handled.

The backend development

After several years of development of Struts, Spring and Hibernate, SSM, a worded word today, almost became the primary selection of JAVA server at that time. I think this is also the main reason why many companies or outsourcing companies still maintain such a set of architecture.

To sum up, the rapid development in recent years has saved us a lot of experience, lowered the threshold of developers and development process, and greatly improved the development efficiency and iteration speed. I call it the Industrial Era

experience

You may not believe it: at the end of my junior year, I got my first job as an intern. I worked for 7 or 8 months on and off by myself. I studied these technologies and independently developed a Web application called Micro Treasure.

Project architecture from civilization -> to the last industrial age! I continued to rebuild, go online and study hard. I am very grateful to my boss for his trust in me and my colleagues for their help.

Four, a hundred schools of Thought contend – technology big bang era

Time, he never stopped, until today — technology can only be described as an explosion.

The front bang

SPA model proposed in the industrial era With the rise of NODE, the rapid development of server, various tools and containers, the front-end MVC MVVM mode is gradually clear, and a number of excellent open source projects emerge in the front-end: Package management: NPM YARN packaging: Grunt gulp module loading: RequireJS SeaJs Framework: VUE Angular React Hybrid: Ionic WEEx React-Native Electron preprocessor: Less SASS Echarts HCharts and animation to improve user experience, let us have more “face”

Even the front end can use Node to build its own simple server and is moving away from being a “client developer.

The back-end explosion

go

More suitable for server oriented programming, if you use C or C++ to do those things, use Go to do, such as virtual machine processing, file system, etc., strong like Docker Kubernetes (K8s) are written by Go

python

Like a biological language, it is now easier to deal with algorithms, artificial intelligence, web crawlers, operations and maintenance

java

A language that has been around for more than 20 years is getting stronger. A number of high-quality libraries have emerged, some of which are representative:

Netty RebbitMQ: easy to implement message queue elasticSearch: easy to implement search engine Spring-boot: easy to implement configuration oriented Web server Spring-cloud, dubbo: easy to implement microservices

And the coming formidable JAVA11

There are operations related to continuous integration of cloud services such as Devops

conclusion

The advent of Go and Python has enabled us server-side developers to do more things, such as automating operations and writing middleware. Gradually inclined to the direction of full stack development. The development of the JAVA ecosystem over the past 20 years has helped us write more robust services. We are dazzled by artificial intelligence, DevOps, cloud services, etc. Open source has become a trend, and technology sharing has become something everyone wants to do. I call it the age of technology explosion

experience

In the past two years, I have been very worried: how to make the front and back end more elegant communication?

I used a variety of back-end template engines until they were completely abandoned, and then went to Node for proxy, rendering + grunt for number processing, and then gradually used them

vue + webpack ——> Rest API

If you have to use NODE, you’ll just be a part of Rest and not have to communicate through NODE. This separation of front and back is satisfactory, so the front end doesn’t have to deal with the back end. Back end? Just write up your own service.

Part 3 Talk about separating architecture before and after

Before and after separation, has been a fairly general problem, before and after separation is good? There is no absolute right, there is no absolute wrong, and the industry has been debating this issue for years. The point of discussion is: separation is fine, but what services need to be split back and forth? To what granularity? How do the front and back ends fit together?

Screenshot time: Aug. 30, 2018-Github

The Issues of 1K library 11K are sufficient to illustrate the trend of separation. We can imagine the fierce degree of discussion in the industry: does the separation of the front and back end of the Web have great significance? It is worth mentioning that most of the front-row engineers who have discussed this issue deeply are full-stack engineers. Because the global understanding of the full stack is relatively stronger than the global concept of simple front-end and back-end, more problems are considered.

Thinking and analysis triggered by sifting resumes

The circle of back-end positions

I have taken a few partial pictures from the company’s resume library. I have interviewed a lot of 1-3 years Java developers in the past two years. In the process of resume screening and interview, I also found several problems: Quite a lot of Javaer technology stack is always so many HTML Ajax jquery bootstrap easyUi, looks very abrupt, if the interview mentioned the front-end technology stack, basic can not answer very well, even some people do not know the prototype chain. This is also the misunderstanding of most people to the full stack, in fact, I am not too cold such resume, because there is no bright spot, the technical stack is not written as much as possible, to sum up: they have a very basic grasp of the front-end, barely competent for some business work. So why do so many people know some front-end technology? In my analysis, there may be three points:

Reason to think:

  • The rise of training institutions mechanized teaching

  • The applicant’s own interests

  • Some companies have incomplete technology stack and no pursuit of technology. Most of them use the architecture of a few years ago, with great business coupling and a big market gap

Analysis of the

Since I’ve been working on sensitive projects for a few months, I know that people who only write on the server side are not qualified for this job. If most developers have resumes like this, I can guess: There is still an order of magnitude of front-end complexity in the IT industry, so they have to find people who know a little bit about front-end technology to develop projects, reduce the cost of communication and speed up the progress of projects. This has given rise to many so-called Web development training institutions.

Did I enjoy my maintenance? I’ll tell you later.

What is anterior and posterior separation

Anterior-posterior separation is not new, it is practiced everywhere. However, some historical projects have inevitably encountered various problems when moving from an all-in-one Web design to a forward-to-back architecture. Because of the endless problems, even some teams will question, integration is good, why do we want to separate the front and back end? In the end, it’s the technology and the mindset that haven’t changed.

Integration mode is actually in the beginning: throughout the evolution of history has been mentioned, not repeated.

The front and back separation should look something like this:

Before and after separation is to build the project at the architecture level or to separate the existing project client side and server side to reduce the coupling degree of the front and back end code. An example of the front and back end separation is SPA(Single-Page Application). All of the presentation data used is provided by the back end via JSON but not just JSON, the front end is about presentation, providing better and more colorful interactions, and the back end is about providing more robust and highly available services.

Do not have the idea of writing the project first and then refactoring it. It is best to get it right in the early stage of the project. Why refactor it and then have to throw away some components and libraries that have already been written?

What problem does this separation solve

Everyone does his job

Good developers are impossible to find, and it is even more difficult to find an excellent full_stack. It is not practical to recruit a programmer with average ability, which is less technology-driven and even slows down product iterations. Apart, we can focus on the front-end and server-side areas to find professional talent.

The decoupling

Front-end and back-end code a lot of coupling code looks like this:

Take a look at a simple example:

//(node processing)
if (is_weixin()) {
init([
'api'.'image'.'xxx'.'... ',].function () {
<%- doSomeGloble %>
});
} else{}// Receive some data from node
let blogs = <%- blogs %>;

let users = <%- users %>;
                     
Copy the code

This is not a JAVA template, but rather a relatively lightweight and elegant EJS rendering of NODE, which is fine, I’ve seen far worse code, and I won’t write it here because I often have to go back and read more code for a single problem.

So how does the front and back separation make their decoupling clearer? It will be added in combination with the server.

What items do not fit before and after separation

Blog, documentation,

You said you were building a blog, an API document system, a small project that one person could develop. We had a front and back separation, and we needed a separate deployment. Increased the complexity of SEO, increased the development cycle, increased the difficulty of user deployment, why? Of course, if it is only a learning way of technical practice, or welcome.

How to solve the problems caused by separation?

Communication cost

Front-end sister: brother, which interface to get all the blogs?

Oh, didn’t you get your paperwork sent yesterday

Front-end sister: I can’t find 😭

Oh, I’ll send it to you later at dinner


Front end girl: elder brother, the product proposes to automatically change the theme according to the phone case, do you have an interface?

. I see… Should be… No! May need Python support! You go ask him for it


Front-end girl: Brother, have you finished writing the interface to get blog according to TAG? What is an interface? So I can render the data

Don’t wait…


This is obviously not standardized. What we expect is that the front end and the back end should first agree an interface protocol. When the back end is not completed, the front end mocks the data by itself.

How to reduce communication costs? The back-end data is servified, and the unified OUTPUT of REST interface specifications is adopted to reduce the communication cost of front-end and back-end interface definitions. Avoid “verbal explanations.”

What is a RESTful API? So RESTful apis are RESTful apis. So what are the scenarios for using RESTful apis? In today’s Internet application front-end display media is very rich. There are phones, there are tablets, there are PCS and other display media. Therefore, it is the most scientific and economical way for the user requests received by the front-end to be processed by one back-end and returned to different front-end. RESTful API is a set of protocols to regulate the interaction modes between various front-end and the same back-end.

I usually use the Swagger + Mock platform to generate standard RESTful apis, but also support extending multiple programming languages such as Go Python

SEOThe problem

Take Vue + Webpack’s SPA as an example. Without the HTML returned by the back-end template, the front-end rendering is not accepted by the search engine’s crawler. In the future actual SEO before popular rendering bai crawler recognition difference:

Seo is essentially one server making a request to another server and parsing the request. But in general, search engines do not go back to execute the requested JS. That is, if you have a single page application, the HTML has not rendered part of the data on the server side, the data is rendered in the browser, and the search engine requests the HTML without rendering data. This is not conducive to the content of the search engine search. So server rendering is about trying to have data on the page before the server sends it to the browser.

Take blogs as an example:

  • Static services
<div>I'm text 1</div>
<div>I'm text 2</div>
<div>I'm text 3</div>
Copy the code

Crawlers directly capture HTML parsing – generate index

  • Traditional back-end rendering
 @RequestMapping("/index") 
    public String index(HttpServletRequest request,HttpServletResponse   response){ 
        return "welcome"; 
    } 
Copy the code

Here is more interesting, for example, we open the url is:

http://host:port/index is actually the server that acts as the Controller. The server directly returns the rendered page to you, as does the crawler, so SEO doesn’t have much of a problem.

  • Before and after the separationSPA
let blogs = [];

this.axios.get('/index, {}) .then(res => { blogs = res.data; }) .catch(err => { console.error(err); }); <! <div v-for="(item, index) in blogs" :key="item">Copy the code

Again, we type http://host:port/index

Note: SpAs usually have their own routing policy, which is the first M in the front-end MVC MVVM

A typical SPA site

We type in the url and we get to this page, and then we go to the asynchronous request server, and then we get the front-end page rendering, and then we get the single-page service and if we don’t do anything, then you’re going to get dumped by all the search engines.

How to solve it?

As long as you do SEO products will do server-side rendering, if you have SEO needs, but the requirements are not high, only part of the page, you can save the country curve

Before NodeJS came along, there were two solutions. One was to create two sets of static pages, and the server would render static pages if the request came from a spider, or dynamic pages if it did not. Two is the server set up virtual browser software, the request to let the virtual browser run again, and then get the static page back to the client. Both approaches have performance issues on large projects.

With NodeJS, the dominant approach is the front and back end isomorphism scheme, where a set of code can be run on both the browser and node side, so that the data rendering template can be requested on the Node side, and the rendering result can be returned to the browser for final rendering. Take a look at the Vue SSR solution Angular SSR solution

How to study SEO more carefully later

Cross domain

Due to the use of front and back end separation deployment, naturally not a port, not a port must cross the domain, but this is not a problem at all for the current technical means

Development mode For faster and better development, dev generally uses Node as the proxy layer, to solve the cross-domain, almost barrier-free development, and can easily switch the environment.

Deployment mode Usually does not rely on Node for deployment, usually we publish to HTTP server, communication with the server, usually using Nginx for forward proxy.

Part4 what do you know about the front end?

Technology stack selection

First of all, we need to have a thorough understanding of the front-end ecosystem to build the front-end architecture, and it is better to have a certain technical perspective. A good technical architecture may be convenient to expand in the future, reduce the number of reconstruction, and even the reconstruction does not need to make a big fuss. I usually choose the technology stack according to the following three points:

First, put forward their own business requirements

  • Is SEO important?
  • Mainly for: mobile or PC?
  • Is there a plan to develop app?

With such a problem we can take the problem to focus on the selection of some of the more mature technical solutions to the problem of the technology stack.

Two, their maturity, whether the document is friendly

Here is an example of an actual development process in the past, in order to optimize the user experience and save development efficiency, the selection of a lightweight MVVM framework, unfortunately, the CTO did not have the decision, the selection of Avalon

At that time, the reason why there is no choice backbone, mainly because there is no mature Chinese documents, taking into account the team’s liquidity and overhand temporarily did not consider, the final choice of Situ Zhengmei avalon at that time is still relatively avant-garde, there are also some to go which network led by the large companies are in use. We were using Avalon2 shortly after it came out and went straight to 2.0, and we had a bit of a problem with it: Documents are discrete, one piece at a time, with postposition, less ecology and low cost performance for expansion. Sometimes, when encountering strange bugs, I may find the answer after searching the reasons for several times of demo and documents, but there is no key mark. It certainly made us a bit more efficient at the time, but I probably preferred Angular or Vue at the time. Because they have an unrivalled ecosystem and technical solutions for various issues, as well as a comprehensive developer documentation, it is worth mentioning that Avalon’s authors are maintained on a part-time basis, which I believe would be much better if avalon were operating on an all-stack basis. Looking at avalon’s source code would also help you a lot. We should be more careful about the technical selection of production.

3. Understand its ecosystem

I mentioned ecosystems above, and vUE, which I use a lot, The development of VUE has only officially provided us with 89 open source projects led by VUex, VUE-Router, VUe-Loader, VUE-CLI, vuepress, VUe-DevTools and VUE-SSR. Including countless VUE related UI libraries, Vue plug-ins and even Hybrid: Weex support provided by Taobao in the past two years

As of today, Github has 167,752 vUE related projects, 416,811 Angular related projects, and 594,272 React related projects.

Statistical time: September 1, 2018

I think with this kind of ecological support, we can fully meet more than 95% of the needs of our small and medium-sized projects, and it is meaningless to compare which is stronger.

Because I am familiar with it, I dare to choose VUE as the main structure of our SPA

Draw our desired front-end infrastructure model

Since we chose Vue in the last chapter, if we only consider the front end our initial idea: the technology stack looks something like this:

With node and Webpack support, vue component builds are packaged as traditional elements and published to HTTP services to request back-end services.

Then it might go something like this:

With the increasing number of mainstream third-party libraries and the technology’s early adoptions, the client side has either been forced to use them or has been proactive in referencing component libraries such as Babel less sass *. Loader and Hybrid.

The later technology stack needs to be improved gradually after we really step on the pit

Polyfill may be lazy loading XSS Protobuf for browser compatibility, speed optimization, SEO, communication protocol and other specific issues. So, early can not think too much, we just know: this problem we can solve, but now can not consider, some students, too “perfectionism” so that the idea is good, but to do a few days do not do, perfectionism kills people.

To understandWebpack

WebPack can be seen as a module packaging machine that analyzes the structure of your project to find JavaScript modules and other extensions that browsers don’t run directly: Stylus, Scss, less, TypeScript, CoffeeScript, etc., and convert and package them into appropriate formats for use by browsers. More commonly, you can also use webpack-dev-server for development mode hot updates

WebPack is a modular development solution

When WebPack works with an application, it recursively builds a Dependency graph containing every module the application needs, and then packages all of those modules into one or more bundles

Webpack can support a variety of language and preprocessor written modules through loader, and finally packaged into one (or more) browser-aware *JavaScript CSS * files

List of loaders currently supported

Understand the ES6

The official story

ECMAScript 6 (ES6 for short) is a JavaScript language standard officially released in June 2015. It is officially named ECMAScript 2015. Its goal is to make the JavaScript language usable for writing complex, large-scale applications.

The popular science

A lot of people are always confused about ES, so let’s be honest: they are in order: ES5, ES6(ES2015), ES7, ES8

In June 2015, the first version of ES6, officially known as the ECMAScript 2015 Standard (ES2015 for short), was released as version 6.0 after 2011 ECMAScript 5.1. Minor revisions to the ECMAScript 2016 standard (ES2016 for short) The ECMAScript 2017 standard (ES2017 for short) was released in June 2017. It is actually version 6.2, but some people would call it ES8.

Just like Kubernetes people gave him the name K8S (there are 8 words between K and S), he is not standard

Understand the Babel Traceur

Babel/Traceur is a platform for compiling JavaScript that allows you to compile code for the following purposes:

JavaScript.next-to-JavaScript-of-today compiler

Use the JavaScript of the future today

As of release date (September 04, 2018), there are no JavaScript proxies that fully support ES6 (either in browser or server environments), so developers keen to use the language’s latest features will need to translate ES6 code into ES5 code.

Enables you to use the latest JavaScript code (ES6, ES7…) Regardless of whether the new standard is fully supported by current browsers;

ES7 writers have no time to read, but Bable is gradually replacing Google’s Traceur in the mainstream. I’m a Philistine, so I’ll go with Bable

To understandSass Less Stylus

Did Sass violate China’s advertising law?

Preprocessors like Sass, Stylus, and Less are extensions of native CSS and allow you to write CSS using features like variables, Nesting, mixins, inheritance, etc., that don’t exist in CSS, The CSS preprocessor can convert these special types of statements into browser-aware CSS statements.

  • Compare three languages in one table
language implementation features The assignment The indentation
Sass Ruby Variable $beginning $var: value Don’t need
Less JavaSript Variable at sign @var: value Don’t need
Stylus NodeJs Do not start with @ var:10 Can be

Loaders: loaders: loaders: loaders: loaders: loaders: loaders: loaders: loaders

Less Loader Sass Loader Stylus Loader

Find it yourself: loader list

Like: Which language is better, more widely used and easier? Controversial bloggers don’t want to discuss it

To understandElectron

A framework that can use JavaScript, HTML and CSS to build cross-platform desktop applications, also a hybrid, the main scenario is PC, nothing to say.

It is worth mentioning that Visual Studio Code, Atom, GIthub Desktop are based on this build, sometimes press CMD + Option + I surprise oh

List of apps developed based on Electron

Part5 Quick build specification project skeleton “VUE”

Preliminary scaffolding

  • Tips

Any good open source project has the project-CLI scaffolding, which we use to generate the best and most desirable scaffolding quickly

I usually use the CLI to generate project skeletons and then make personal modifications on top of them.

What is a CLI

The command line interface (CLI) was the most widely used user interface before the popularization of the GRAPHICAL user interface (GUI). It usually does not support the mouse. Users input commands through the keyboard, and the computer executes the commands after receiving them. Some call it a character user interface

As the name implies XXX-CLI is the use of command line generation XXX program. I wrote a tutorial on creating a personalized CLI based on nodeJs

How to use Node to develop your own CLI tools and publish them to NPM.

vue-cli

As of September 02 2018, VUE-CLI is the latest version 3.0

Vue Chinese ecology is very perfect, let’s go to the official website to see:

cli.vuejs.org/zh/

Vue-cli2 versus VUe-CLI3

It is a pity that VUE-CLI-3 was released on August 11, 2018, and my forum started to build CLI-3 earlier, which delayed me some time. It will be mentioned later

Just a quick lookvue-cli3New features:

  • Pwa can be generated
  • Support UI interface check box can be selected
  • The compatible CNPM
  • Vue cli-service = vue cli-service = vue cli-service = vue cli-service = vue cli-service = vue cli-service

I was thinking about the project compatibility with VLI-3 when I was not busy these two days, but later I wasted a lot of time and the effect was still not ideal, so I rolled back the code and announced to give up.

Since using CLI-3 did not improve the performance of my project, and instead went through a lot of my mature infrastructure, I decided to use CLI-2 for the cost of time, with the general directory structure being the same.

The installation of vue – cli

Pay attention to the prerequisites before installation to avoid wasting unnecessary time.

Vue CLI requires Node.js version 8.9 or later (8.11.0+ recommended). (If you use CLI-2 like me, you don’t need such a new nodeJs.) You can use NVM or NVM-Windows to manage multiple versions of Node on the same computer.

I will not stay away, the official website is much better than I said.

You can install it using YARN or NPM

npm install -g @vue/cli
# OR
yarn global add @vue/cli
Copy the code

I used NPM to try again (if the speed of NPM is not ideal, try taobao CNPM and do not rely too much on CNPM) :

localhost:~ Venda-GM$ sudo cnpm i @vue/cli -g
Copy the code

TIPS

In NPM, install can be written as I, -g can be put anywhere, –save can be written as -s, –save-dev can be written as -d

Seeing this screen, the installation is complete.

Test to see if the version is correct, ok create project:

vue create new-bee
Copy the code

Pull 2.x template (old version)

Vue CLI 3 uses the same Vue commands as the older version, so Vue CLI 2 (VUe-CLI) is overwritten. If you still need to use older versions of vue Init, you can install a bridge tool globally:

npm install -g @vue/cli-init
Copy the code

vue initThe operation effect will follow[email protected]The same

Vue init webpack my-project # to generate a * CLI-2 * projectCopy the code

Use vue-CLI-2 to generate the project

vue init webpack new-bee
Copy the code

Here are the options I selected when I created the project:

Let me tell you a little bit about these three:

  • Vue build mode

It is recommended to use run time + compile, usually requiring webpack compile.vue templates.

  • Whether to select the preset Eslint

And is not suitable for everyone, some requirements are too strict, I have a mature, code here, with their own, of course, can be based on it to do some deletion.

  • It will execute install for us

If you have a good socket terminal proxy, you can use this, otherwise you can select No and use CNPM yourself

A first look at the directory structure

Let’s take a look at vuE-CLI2’s auto-generated project catalog, and I’ll label it to give a brief description for those of you who may be confused

The main purpose of our refactoring this time was to standardize and make it more suitable for multi-module collaboration, rather than to make it look more complicated. The project structure, esLint improvements, etc., in this paper were decided by the project team repeatedly and have certain production value.

Worrywart: Get ready for Electron

The cli generated project SRC is the source code directly below, but in order to consider the future use of electron we will use renderer wrapped, a bit more standard.

Take a look at electron-vue

Compatible with Electron source directory

The github tree plugin octotree can also be installed in the Google Store directly, saving a lot of time looking at the source code.

  • Don’t set upelectronmainThe folder andindex.ejsDependencies need to be added and are not currently needed.

Don’t forget to fix the webPack-related path issues

Plus the path to the renderer

 app: './renderer/src/main.js'
Copy the code

The @ path should also be changed in Webpack, otherwise the component will not be found

Need to change thewebpack alias[Alias] Configuration

What it looks like

alias: {
      '@': resolve('renderer/src'),
    }
Copy the code

Container-level directories

Create a container at the level of the components directory: separate the modules inside the container to make the project modules more visible. If the project with more than 10 people can divide the workspace well, establish a reasonable route, avoid unnecessary conflicts.

Take the current forum project for example

Routing directory adjustment specifications

Create blog.js for /container/blog under /router

const Blog = () = > import ( /* webpackChunkName: "blog" */ '@/container/blog/index')

/* All paths in container/blog are configured under children to avoid clutter */
let routes = [{
  path: '/blog'.name: 'blog'.component: Blog,
  children: [{
      path: 'blogdemo'.component: Blog
    } 
  ]
}]


export {
  routes
}

/ / note
/* webpackChunkName: "blog" */ 
// The route is loaded lazily

Copy the code
  • self-generatedindex.jsThe main road is like this

  • Disadvantages:

It’s too simple, we can’t write all the routes in it. As children, it looks very messy, difficult to handle development and debugging, and multiple people working together can easily cause conflicts.

We tried to bring blog.js here

Import the route from blog.js export and create an alias to prevent conflicts

import { routes as blogRoutes } from './blog'
Copy the code

Since there may be N more routing modules, we split the routes

The automatic generation is as simple as this:

Export default new Router({routes: [{path: '/', name: 'HelloWorld', Component: 'HelloWorld}]})Copy the code

Let’s break it down like this:

// Define base route let route = [{path: '/', name: 'HelloWorld', Component: // export default new Router({routes:) {route = route.concat(blogRoutes)} route, linkActiveClass: 'active' })Copy the code

Back up, let’s add some content to blog/index.vue to test it out:

<template>
  <div class="Blog">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: "Blog".data() {
    return {
      msg: "Welcome to Your Blog Page"}; }};</script>
Copy the code

Test the

First of all,

npm install
Copy the code

Disliking slow can use the CNPM of Taobao my previous article talked about

npm run dev
Copy the code

Enter http://localhost:8080/#/blog in your browser as prompted

Vue-cli2 WebPack-generated projects are hot deployable, so you don’t need to configure a lot of the configuration yourself from scratch, which is why I want you to use the CLI to save some time. Other login and other modules should follow this pattern.

Talk abouteslint

I find esLint to be of value in both individual projects and team collaborations as a way to standardize your own and your team’s code style. Now esLint can even predict if your code might have a problem. It is recommended that you make some rules and use your IDE(integration environment) for development: idea, WebStorm, vscode, etc. Plugins with detection, eslint package to detect compile failure is very strict or not to try in the early stage.

I referred to the configuration adjusted by Airbnb at that time, and gradually adjusted it after more than a year of project practice, which is still reasonable at present. The configuration rule code of esLint is here.

The code for this chapter is here

You can even see the step-by-step transformation process in this chapter in the commit

Part 6 Polish the front-end architecture

axios

You use VUE and realize that Vue can’t send requests, so you Google it and realize you can use vue-resource. You ask someone about vue-Resource and he says don’t use vue-resource because vue-Resource has officially stopped maintenance, you should use Axios or fetch. But we want to embrace ES6 without ES5 fetch (and of course es6-FETCH), here we use Axios!

Tips

When do you need to put dependencies in dependencies? When do you need to put dependencies in devDependencies?

DevDependencies: devDependencies only in dev mode (such as webpack. Loader, esLint, Babel)

< span style = “box-like: box-like: box-like; box-like: box-like

But basically don’t worry, the official website will provide start instructions, but we should generally understand the meaning, not mechanical copy.

The introduction of Axios

  • Go straight to the latest

The 2018-09-28 capture npmjs.com

  • Add the dependent
"dependencies": {    
    "axios": "^ 0.18.0." "
 }
Copy the code

Based on the previous chapter, don’t forget to download NPM I again

Remember the vue homepage script main.js that we automatically generated?

Encapsulation axios

SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils: SRC /renderer/utils Handles some common HTTP status codes.

  • Interceptors document

I wrote as detailed a note as I could for you.

// src/renderer/utils/request.js
import axios from 'axios'

/ / here generally refers to the backend API prefix, such as/baidu / * / * / 1. API/mi / * / * / 2. API
const BASE_API = ""

export function axiosIntercept(Vue, router) {
    const axiosIntercept = axios.create({
        baseURL: BASE_API
    })

    // HTTP request interceptors are usually used to plug in some global configuration before the request, or to enable some CSS loading animation
    axiosIntercept.interceptors.request.use(
        (config) = > {
            // Determine whether a token exists, and if so, add a token to each HTTP header
            // if (store.getters.accessToken) {
            // console.log(store.getters.accessToken)
            // config.headers.Authorization = `token ${store.getters.accessToken}`;
            // }

            //todo: load the animation

            // If necessary, you can handle the POST or change the POST transmission format
            if (config.method === 'post') {};return config;
        }, function (err) {
            return Promise.reject(err);
        });


    // HTTP response interceptors are usually used to do some processing based on some back-end protocol specific return values, such as permission aspect, 404... Or turn off some CSS loading animations
    axiosIntercept.interceptors.response.use(function (response) {
        // todo: Pause loading animation
        return response;
    }, function (err) {
        // Catch an exception
        if (err.response) {
            switch (err.response.status) {
                case 401:
                    // Do something here we write back end to do constraints and then improve}}return Promise.reject(err);
    });
    return axiosIntercept;
}


Copy the code

Remember that we used the vue home page script main.js generated by vue-CLI. Here we need to couple Axios and Vue.

// src/renderer/main.js
import axios from 'axios'
import { axiosIntercept } from './utils/request'

// Extend Axios to the Vue prototype chain
Vue.prototype.$http = axiosIntercept(Vue)
Copy the code

So we’re writing the business logic to send the request directly in the Vue context using this.$HTTP. Both interception and state sharing are realized.

Know what it is and why

  • What’s the point of this?

Save the amount of code, make the code more readable

  • Why is that?

Extending to the stereotype chain enables the Axios runtime to share the contents of the Vue stereotype chain, reducing the number of temporary variables that refer to the Vue

  • Take a chestnut

Traditional situation

import axios from 'axios'


new Vue({
  data: {
    user: ""
  },
  created: function () {
    // Now the scope is on Vue, cached and depends on this variable
    let _this = this;
    axios.get("/user/getUserInfo/" + userName).then(res= > {
            if (res.data.code === 200) {
                // The value of the vue binding is not available in axios, so we can only use the _this context that was cached_this.data.user = res.data.user } }); }})Copy the code

After the agent

 


new Vue({
  data: {
    user: ""
  },
  created: function () {
    // Axios becomes part of the vUE prototype chain, sharing vUE state.
    
    this.$http.get("/user/getUserInfo/" + userName).then(res= > {
            if (res.data.code === 200) {
                // Note that axios callbacks should use arrow functions as much as possible, which can inherit the parent context, otherwise it will be similar to closures, and still cannot share variables.
                // More elegant
                this.data.user = res.data.user } }); }})Copy the code

If you don’t understand Prototype, check out my previous articles

proxy

I’m just going to do it a little bit, just to set up a little bit of separation

webPack

  • WebPack alias
resolve: {
    extensions: ['.js'.'.vue'.'.json'].alias: {
      The '@': resolve('src/renderer'),}},Copy the code

For more elegant use, you can create aliases for each commonly used directory

resolve: {
   extensions: ['.js'.'.vue'.'.json'].alias: {
     'vue$': 'vue/dist/vue.esm.js'.The '@': resolve('src/renderer'),
     'assets': resolve('src/renderer/assets'),
     'components': resolve('src/renderer/components'),
     'container': resolve('src/renderer/container'),
     'utils': resolve('src/renderer/utils')}},Copy the code

Cross-domain issues in production and development

Dev is the directive launched at development time and build is the directive packaged by webPack at pre-release

Assuming that the author is just a front-end, usually, in the process of development and debugging, it is unavoidable to need API docking with students at the back-end, which will inevitably lead to cross-domain problems. Of course, traditional javaWeb does not need cross-domain, (IP domain port any difference is cross-domain) in DEV mode debugging, we try to choose the front-end environment to avoid cross-domain problems, rather than to build additional Nginx or change the back-end code.

Cross-domain is only for JavaScript, because developers consider scripting on browsers to be insecure.

Since our VUE project is a node family bucket, we rely on Node and webPack compilation to directly configure node’s proxyTable as a proxy for development, which is the simplest, one after another configuration, the team benefits.

Cnode mining community API example

cnodejs.org/api The CNode API above is free to call because the back end does the processing.

Check out the Nuggets:Xiaoce – timeline – API – ms. Juejin. Im/v1 / getListB…Please, the browser did a cross-domain alarm.

Oh, let’s adapt the Node agent

Official example in this: vuejs – templates. Making. IO/webpack/pro…

ProxyTable extension:


proxyTable: [{
      // Intercept all XHR requests starting with v1
      context: ['/v1'].target: "https://xiaoce-timeline-api-ms.juejin.im".cookieDomainRewrite: {
        / / without the cookie
      },
      changeOrigin: true.// A virtual service will accept or forward requests on our behalf
      secure: false}].Copy the code

Send the request again.

  • Happy to get the data

This way, separated projects can use the Swagger testing interface in this way without bothering anyone. Implementation of their own business logic, simple implementation point.

Code:

// blog/index.vue
<template>
  <div class="Blog">
    <h1>{{ msg }}</h1>
  <div v-for="(blog,index) in blogList" v-bind:key="index">
    <h3 >
      <a :href="`https://juejin.cn/book/`+blog.id" >
        <span>{{blog.title}}</span>
      </a>
      </h3>
  </div>
  </div>
</template>

<script>
export default {
  name: "Blog".data() {
    return {
      msg: "A look at the Gold Digger booklet.".blogList: []}; },created() {
    this.getBlog();
  },
  methods: {
    getBlog() {
      this.$http.get("/v1/getListByLastTime? src=web&pageNum=1").then(res= > {
        this.blogList = res.data.d; }); }}};</script>
Copy the code

release

  • literacy

After the code is written and deployed online, it will not clone the code online after the Npm run dev 😆, which will have too many garbage dependencies, bringing users disastrous network requests, usually with the help of webPack packaged and published to the server’s Web services.

run

 npm run build
Copy the code

The package directory is the previously configured Webpack

Well, a lot of people won’t be able to just double-click index.html.

Tip: built files are meant to be served over an HTTP server.

Opening index.html over file:// won’t work.

I usually use Python to start an HTTP service to run (script address). Of course, my IDE can also support HTTP start.

Cross-domain in production

In production, because the front-end and back-end are bound to have different ports, cross-domain is avoided. Nginx’s forward/reverse proxy is usually used as a means of cross-domain. (Not load balancing, two concepts)

server { listen 80; server_name localhost; location ^~ /v1 { proxy_pass https://xiaoce-timeline-api-ms.juejin.im; # agent. proxy_set_header X-Real-IP $remote_addr; Forwarded_forwarded_for ($forwarded_FORWARded_for); proxy_set_header Host $http_host; }}Copy the code

Nginx can do a lot of things.

Normalization of apis

Are you still using global search to find your own interface? Are you using global search to find your own interface?

Create an API folder under /renderer

Webpack.base.conf.js adds an API alias to make it easier to call a lot later

'api': resolve('src/renderer/api')
Copy the code

We created /renderer/ API /juejin.js


import axios from 'axios'

let Api = Function()

Api.prototype = {
    getBlog(page, fn) {
        axios.get(`/v1/getListByLastTime? src=web&pageNum=${page}`).then(res= > {
            // if (res.data.code === 200) {
            fn(res.data)
            // }
        }).error()
    }
}
export default new Api()


Copy the code

Modify the Axios request we just made in /blog/index.vue:

  • First introduced the API
import juejin from "@/api/juejin";
Copy the code

Annotate the previously discrete AXIOS and request the data using the XHR defined from the API.

getBlog() {
      // this.$http.get("/v1/getListByLastTime? src=web&pageNum=1").then(res => {
      // this.blogList = res.data.d;
      // });
      juejin.getBlog("1".response= > {
        this.blogList = response.d;
      });
    }
Copy the code

Part 7 Quickly build a website layout

In order to explain the convenience of refactoring and removing Element and VUX libraries, this article uses bulma, which is very popular recently, to be lightweight, fast and easy to read.

Project screenshots

Layout and Components

Layout

First of all, like the figure above, we think of a small website split into three parts: Header, Content, Footer, which is almost every website must have, usually the ten thousand years unchanged: Header, Footer made into a convenient general Layout.

Components

Content is then divided into Components according to business.

As shown above: Header and Content: Header don’t really need to be split. There are no reusable components, and Conntent is the layout element that must be split. Because Conntent, a dynamic site, changes with content, the more content, the higher the probability of reusable things, you need to extract reusable things

1, save code, improve code reading

2. Easy to modify (e.g. updating ads)

Start coding

Then we upload the source code in chapter 2, based on which we continue to improve the small site layout and componentization.

It’s worth noting that this series of tutorials follows one chapter after another and each chapter runs independently, with no “pop up” code snippets. It doesn’t give beginners the feeling that they don’t know where to start. If you’re new to code, you should read the next article carefully. You can either build on the code from the previous chapter step by step or download a brief preview of the code from this chapter.

  • Introduce bulMA style CDN
vim new-bee/index.html
Copy the code
<! Font --> <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <! - the CSS - > < link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.0/css/bulma.min.css" >Copy the code
  • New Layout directory
vim new-bee/src/renderer/components/layout
Copy the code
  • Create header. vue template components in Layout directory

This component is dedicated to writing header content, preferably with a grid to write as simple and responsive components as possible

<template>

    <div id="bee-header"   element-loading-text="Working to request Github..." element-loading-background="Rgba (0, 0, 0, 0.8)">
        <! - mask - >
        <div  :class=" loading ? `modal is-active` : `modal` " style="background-color: #ffffff36">
                < img src="https://img.actd.tw/images/2018/11/17/ez-4-05f4bba41fef" style="width: 300px" alt="">
        </div>

        <div class="is-underline ">
    <div class="container">
      <nav class="navbar ">
        <div class="navbar-brand">
          <a class="navbar-item"   >
            < img src="https://img.actd.tw/images/2018/11/17" alt="Bulma: a modern CSS framework based on Flexbox" width="92" height="28">
          </a >
          <div class="login-before is-hidden-mobile" style="padding-top: 5px;">
            <a class="navbar-item is-hidden-desktop" href="" target="_blank">
              <span class="icon" style="color: #333;">
                <i class="fa fa-lg fa-github is-size-2"></i>
              </span>
            </a >
          </div>
          <div class="navbar-item is-hidden-desktop ">
             <div class="field has-addons"  ><div class="control" ><input   type="input" class="input" name="email" placeholder="Do a search" required="required" style="Height: 36.4 px; width:130px"><input   type="hidden" name="redirect" id="name" value="/fr/#thanks"></div><div class="control"  ><input  type="submit" class="button is-warning" value="GO"></div></div>
          </div>
           
          <div class="navbar-burger burger" data-target="navMenuDocumentation" >
            <span></span>
            <span></span>
            <span></span>
          </div>
        </div>

        <div id="navMenuDocumentation" class="navbar-menu">
          <div class="navbar-start">
            <div class="navbar-item has-dropdown is-hoverable">
              <a class="navbar-link is-active">Found < / a ><div class="navbar-dropdown ">
                <a class="navbar-item " type="Collection"></a ><a class="navbar-item" type="Badge">Badge < / a ><a class="navbar-item " type="排名">Ranking < / a ><a class="navbar-item "  type="Work Life"></ A ></div>
            </div>
            <a class="navbar-item " href="https://bulma.io/expo/">
              <! - < span class = "bd - emoji" > ⭐ ️ < / span > -- >Column < / a ><a class="navbar-item " href="https://bulma.io/expo/">
              <! - < span class = "bd - emoji" > ⭐ ️ < / span > -- >chat<! -- Many people don't know what to do... -->
            </a >
            <a class="navbar-item " href="https://bulma.io/expo/">
              <! - < span class = "bd - emoji" > ⭐ ️ < / span > -- >Surface by < / a ><router-link class="navbar-item " to="/book">
              <! - < span class = "bd - emoji" > ❤ ️ < / span > -- >books</router-link>
          </div>

          <div class="navbar-end">
            <div class="login-before" style="padding-top: 5px;">
              <! -- pc -->
              <a class="navbar-item is-hidden-desktop-only" href="https://github.com/pkwenda/my-bbs" target="_blank">
                <span class="icon" style="color: #333;">
                  <i class="fa fa-lg fa-github is-size-2"></i>
                </span>
              </a >
            </div>

            <div class="navbar-item is-hidden-mobile ">
               <div class="field has-addons"  ><div class="control" ><input   type="input" class="input" name="email" placeholder="Do a search" required="required" style=Height: 36.4 px; ""><input   type="hidden" name="redirect" id="name" value="/fr/#thanks"></div><div class="control"  ><input  type="submit" class="button is-warning" value="GO"></div></div>
            </div>

            <div class="navbar-item is-hidden-mobile ">
              <! --<span class="icon is-medium">-->
              <i class="iconfont icon-tixing"></i>
              <! --</span>-->
            </div>

               
            <div class="navbar-item has-dropdown is-hoverable">
              <a class="is-hidden-mobile"  target="_blank">          
              < img src="https://avatars2.githubusercontent.com/u/14212375?s=400&u=dc515636befebfda36501309d1cdc087ee31d500&v=4" class=" header-avatar img-circle "
                                  style="margin-top: 10px">
              </a >
              <div class="navbar-dropdown ">
                <a class="navbar-item " type="Collection">Write an article </a ><a class="navbar-item" type="Badge">Settings < / a ><a class="navbar-item " type="排名">Out < / a ></div>
            </div>   
            
 
           
            <div class="login-before">
              <div class="navbar-item">
                <div class="field is-grouped">
                 
                  <p class="control">
                    <a class="button is-warning"  v-show=! "" isLogin"  >
                      <strong>The login</strong>
                    </a >

                  </p >

                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
    </div>
  </div>
    </div>
</template>


<script>
export default {
  name: "BeeHeader".data() {
    return {
      popupShow: false.isLogin: false.user: {},
      loading: false.userInfo: {}}; },created() {},
  destroyed() {},
  mounted() {},
  methods: {}};</script>

<style scoped>
.img-circle {
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
}
</style>

Copy the code

What styles can be written in.vue files

The familiar code above is the one that makes our heads round

<style scoped>
.img-circle {
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
}
Copy the code
  • The effect

I’m just being lazy here to say that for such a generic style, it’s confined to a.vue file marked scoped, declaring it unusable. Any module that wants to use this style will have to make a copy of it, which is obviously not standard, and we usually build generic CSS files to manage it. The CSS management specification for large projects will have a more stringent, standardized tree structure, depending on the CTO.

How to choose layout according to preference

According to the need to introduce

vim new-bee/src/renderer/components/HelloWorld.vue
Copy the code
<template> <div> <Header></Header> <! --<div class="container"> </div>--> </div> </template> <script> import Header from "@/components/layout/Header"; export default { name: "NewBeeIndex", components: { Header }, data() { return {}; }, destroyed() {}, mounted() {}, methods: {}, watch: {} }; </script>Copy the code

The disadvantage is that you have to introduce it one by one, but the advantage is that the code is readable

Introduced the global

  • App main entrance
vim  new-bee/src/renderer/App.vue
Copy the code
  • The introduction of
<template>
  <div id="app">
     <Header></Header>
    <! -- < img src="./assets/logo.png"> -->
    <router-view/>
  </div>
</template>

<script>
import Header from "@/components/layout/Header";
export default {
  name: "App".components: { Header }
};
</script>

<style>
</style>


Copy the code
  • See the effect

Thanks to webpack dad’s hot deployment, we didn’t have to refresh the browser, webpack secretly updated our content with WS. It seems perfect, but you may have noticed a problem. We can see it in the dom rendered by the browser:

We introduce the header layout in the main APP entrance, app. vue is the body element of the adjacent element, and all pages and subroutes of this program are subsets of the app. vue entrance, indicating that the global introduction layout will have the following problems:

1. All projects in this project will definitely carry the content rendered by the Header component. 2.

Of course, you could write logical conditions on the Header component to filter the specified routes, but this would break the legibility of the project and make it difficult to maintain

I personally recommend the first approach: on-demand introduction.

Continue to the layout

  • Follow suit and write Footer
vim new-bee/src/renderer/components/layout/Footer.vue
Copy the code
<template> <footer class="footer footer-light-medium " style="padding-bottom: 20px; padding-top: 20px;" > <div class="container"> <div class="columns"> <! -- Column --> <div class="column is-4"> <div class="mb-20"> < img class="small-footer-logo" src="https://img.actd.tw/images/2018/11/17/" alt=""> <div class="footer-description pt-10"> new bee Github is an open source community dedicated to technology sharing for developers. All source code can be found on Github, hoping to help developers. < / div > < / div > < div > < span class = "moto" > like project can thumb up support < a href = "https://github.com/pkwenda/new-bee" target = "_blank" > < span class="icon"><i class="fa fa-github"></i></span> </a >.</span> <div class="social-links mt-20"> </div> </div> </div> <! -- Column --> <div class="column is-6 is-offset-2"> <div class="columns"> <! -- Column --> <div class="column"> <ul class="footer-column"> <li class="column-header"> Links </li> <li class="column-item"><a href="https://github.com/pkwenda/new-bee">Home</a ></li> <li class="column-item"><a href="https://cssninja.io/themes">Blog</a ></li> <li class="column-item"><a href="https://github.com/pkwenda/new-bee/wiki">Wiki</a ></li> </ul> </div> <! -- Column --> <div class="column"> <ul class="footer-column"> <li class="column-header"> Ressources </li> <li class="column-item"><a href="https://cssninja.io/help">Help center</a ></li> <li class="column-item"><a href="https://cssninja.io/blog">Blog</a ></li> <li class="column-item"><a href="https://cssninja.io/help/rules">Rules</a  ></li> </ul> </div> <! -- Column --> <div class="column"> <ul class="footer-column"> <li class="column-header"> Terms </li> <li class="column-item"><a href="https://cssninja.io/help/terms/licenses/personal">Personal</a ></li> <li class="column-item"><a href="https://cssninja.io/help/terms/licenses/developer">Developer</a ></li> <li class="column-item"><a href="https://cssninja.io/help/terms/service">Terms of Service</a ></li> </ul> </div> </div> </div> </div> </div> </footer> </template> <script> export default { name: "Footer", data() { return {}; }, created() {}, destroyed() {}, mounted() { }, methods: {} }; </script>Copy the code

Don’t forget to introduce it in HelloWorld

  • See the effect

  • It looks like it’s working pretty well, and then the Content
vim new-bee/src/renderer/components/layout/Content.vue
Copy the code
<template> <div class="container" style="height:700px"> <h1 > <article class="column is-3" v-for="blog in blogs" v-bind:key="blog"> <a class="bd-article-image is-bootstrap" > <span class="bd-article-overlay"></span> <span class="bd-article-icon"> <i class="fa fa-tag"></i> </span> <strong class="bd-star-icon" ><i class="fa fa-star"></i> <span style="font-size: 1rem">&nbsp; {{blog.commendCount}}</span></strong> <strong class="bd-article-info"> <span> <time class="bd-article-date" datetime="2017-10-09T00:00:00+00:00"> {{blog.tag}} </time> <strong class="bd-article-title"> {{blog.title}} </strong> </span> </strong> </a> </article> </div> </template> <script> let article = { tag: "java", title: "java", commendCount: 0}; export default { name: "Footer", data() { return { blogs: [ article, article, article, article, article, article, article, article ] }; }, created() {}, destroyed() {}, mounted() {}, methods: {} }; </script> <style scoped> .bd-article-image.is-bootstrap { background-color: #6f5499; } .bd-article-image { background-color: #00d1b2; display: block; height: 240px; margin-left: auto; margin-right: auto; position: relative; text-align: center; }. Bd-star-icon {font-size: 19.2px; The font - size: 1.2 rem; color: #0a0a0a; Opacity: 0.25; bottom: 10px; left: 30px; position: absolute; -webkit-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; } .bd-article-icon, .bd-article-info { bottom: 0; left: 0; position: absolute; right: 0; top: 0; -webkit-box-align: center; -ms-flex-align: center; align-items: center; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .bd-article-info { padding: 20px; } a strong { color: currentColor; }. Bd-article date {color: rgba(0, 0, 0, 0.5); display: block; } .bd-article-title { color: white; display: block; The font - size: 1.8 rem; font-weight: 700; The line - height: 1.25; padding: 0 20px; } .bd-article-icon { color: #0a0a0a; Opacity: 0.25; } h1 { text-align: center; font-size: 30px; } .column.is-3, .column.is-3-tablet { -webkit-box-flex: 0; -ms-flex: none; flex: none; width: 25%; float: left; } </style>Copy the code
  • See the effect

  • The helloWorld.vue code looks like this

Ok, so let’s go on to figure 2

Specify the AD(advertising) component for Content.

vim new-bee/src/renderer/components/common/AD.vue
Copy the code

<template>
     
             <div class="ad"><h1>Macao XX casino is online</h1></div>
    
</template>

<script>
export default {
  name: "AD".data() {
    return {};
  },
  destroyed() {},
  mounted() {},
  methods: {},
  watch: {}};</script>
 <style   scoped>
.ad {
  width: 150px;
  height: 180px;
  background-color: #ececec;
  position: fixed;
  right: 30px;
  top: 80px;
}
</style>
 
Copy the code
  • Don’t forget to introduce it in Content.vue
.<AD></AD>. import AD from "@/components/common/AD"; export default { name: "Content", components: { AD }, ... }Copy the code
  • Look at the effect

  • Compare the sketches we did with Sketch

We’re almost done with our initial concept

Part 8 Front-end performance optimization

This section of olives

  • The front-end needs to understand the basic knowledge of Docker
  • Deploy front-end projects to local/extranet services
  • GZip optimization of front-end projects
  • Understand the importance of CDN
  • Webpack loads on demand
  • Image related optimization
  • How to analyze project dependencies to facilitate targeted treatment
  • How can I reduce the webpack size/speed

online

We usually develop locally, and the local environment is not exactly the same as the online environment. When many projects go online for the first time, they almost encounter problems that cannot be replicated locally, such as font and style problems, webpack compilation problems, and even local weird environment problems. Therefore, local perfect operation ≠ online perfect operation. We need to build the project and simulate online test to see if it can run perfectly. If there is any problem, we can make adjustments in time.

To prepare

In order to avoid polluting the local environment with this tutorial, it is recommended that you install a Docker, and the later operation and maintenance will be expanded according to docker.

See this Title: “Prepare for Docker”, do not be afraid to touch the front end, install one, dare to take the first step, do not learn is waiting for death “Click here to learn about Docker”

Although Tomcat Nginx, Apache, JBoss, Jetty, and so on can be used as HTTP services, this chapter starts with the most common nginx:

Let me introduce Docker in plain English

Docker is a more elegant way to do the virtual machine thing, and do better, programmable cluster management. By default, each container is isolated from each other. Of course, you can associate the container with link network, or directly use docker-compose compose. The premise of starting the container is an image, which is also similar to the image of the VIRTUAL machine. You must download the “pull” image first.

Using a docker

Maybe a lot of people have not, have not also don’t talk about how to install, go to see the official Internet cafe Chinese official website, community version download, Chinese image acceleration, Windows may want to open virtualization, Linux recommended Ubuntu, there is an article said: Please do not run Docker in centos for performance.

Let’s look at the images state

docker images
Copy the code

You can see I’ve got some mirrors “I’ve deleted nginx”

DockerHub pulls Nginx images

docker pull registry.docker-cn.com/library/nginx:latest
Copy the code

Normal docker pull nginx will do, the middle section is the Chinese image source

Ok, we successfully pulled down the Nginx image. The default storage image name is registry.docker-cn.com/library/nginx

packaging

Go to the source directory of our previous chapter and build it. The source code for the previous chapter is here

npm run build
Copy the code

Start the Docker container

docker run --name nginx -d -p 8888:80 -v /new-bee/dist:/usr/share/nginx/html  registry.docker-cn.com/library/nginx
Copy the code

  • Up-order some explanations “don’t say much, avoid indigestion, explore yourself”
CMD explain
-d  Daemon running
-p Port mapping 8888:80 Docker80 port mapping to the native “host”
-v A directory to mount the host native “host” : docker container
– the name Name the container

Test the

http://localhost:8888/#/
Copy the code

Of course, the first time you try Docker you may have more questions:

  • How do you know you need to mount your home directory to: /usr/share/nginx/html?
  • Can/How can I view Nginx logs?
  • Can nginx be configured in a container?
  • .

These little white issues will be discussed briefly in this chapter and separately in the future when doing automatic operation and maintenance. You can follow my blog

gZip

We can use Webpack to compress the script file and upload it to the HTTP server. When browsing, the browser decompresses the compressed HTTP reply packets. Compared with compression, decompression speed is very fast (as long as the data is normal and can be decompressed). So don’t worry that the time the browser takes to decompress will degrade the user experience. In fact, the amount of time it takes to decompress a browser is much smaller and more manageable than the amount of time it takes to unpack packets due to network congestion.

 

In the HTTP request packets sent by the browser to the server, the accept-Encoding field indicates the compression format supported by the browser, that is, the types of compressed packets (gzip and Deflate provided by the Zlib library) that can be decompressed. Server Reply The content-Encoding field is used to specify the compression mode used in the HTTP response packet sent by the client.

GZip hack webpack, Nginx

Like me, a diaosi server generally buy 1M, large resource files can not hold, a at 400K Vendar file this is very painful, not gZIp is very uncomfortable.

Open network and observe:

It’s 144K in size

Take the core vendor packaged with WebPack as an example. We find that the client requests the gZIp resource accept-encoding from the server: Gzip, deflate, but unfortunately the server does not give us the desired response-Content-encoding: gzip response, we need to check the reason.

  • First of all, let’s see if webpack has been played out. See if his directory has js.gz files.

Unfortunately not, just a few zip files and a map file for location, it looks like we had a problem with packaging in the first place.

Remember this picture I sent out when we were building the project?

  • Package. json project description file

Open and see which script the build command executes.

Open build.js to see what’s being done. Is vue-CLI not configuring webPack gZip for us?

Const webpackConfig = require(‘./webpack.prod.conf’);

Oh, we see that WebPack does configure gZip for us.

But it turns out that the configuration is wrapped in this judgment:

if (config.build.productionGzip) {

}
Copy the code

To track down

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false.Copy the code

All of our doubts were solved when the developer commented on his reasons, which I’ll translate briefly:

First download dependencies:

Json "devDependencies": {"compression-webpack-plugin": "^1.1.12",}Copy the code

Then productionGzip changes to true

  • Without further ado, try packing:
npm run build
Copy the code

Zg file, but gZip requires server support. The server uses the accept-encoding header of the client request to determine which format of the script to return, and then decompresses the browser. We pulled down the nginx image, Nginx does not configure gZIp server compression for us by default, let’s check it out.

Access the Docker host

 docker exec -it nginx /bin/bash
Copy the code

or

 docker exec -it nginx "bash"
Copy the code

CMD explain
exec Enter the Docker container
-i  -i: Runs the container in interactive mode, usually with -t.
-t -t: reassigns a pseudo-input terminal to the container. It is usually used together with -i.
-it -it = -i -t
“Bash” or/bin/bash /bin/bash is useful because the docker background must run a process or the container will exit

The first thing to get into the Nginx host

Where is Nginx??

The Linux whereis command is used to find a file.

The directive looks for files in a specific directory that match the criteria. These files should belong to raw code, binaries, or help files.

This command can only be used to locate binary files, source files, and man man pages. You need to use the Locate command to locate common files.

grammar

Whereis [-bfmsu][-b < directory >... [-m < directory >...] [-s < directory >...] [file]...Copy the code
  • View the nginx location
root@e0017cab245f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
Copy the code

  • We found the root directory HTML/in /usr/share/nginx

  • We found the nginx configuration file in /etc/nginx/

Ps middleware so many, who can remember, remember not to see their own line is not it?

  • Take a look at the nginx configuration

It is true that gZip is not enabled, it is noted out.

We open the comments for gZip, and in case the server is lazy with CSS, we add a few lines of classic configuration in one go.

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/json;
gzip_vary on;
    
Copy the code

The nginx configuration code is here

How to modify the internal configuration of Docker

For now, you have two options:

  • Modify directly to the EXEC container to add the above gZip code snippet. Disadvantages: If you want to rebuild a container based on images, the configuration inside the container will be lost. (Unless you commit the mirror)
  • Separate configuration files, once and for all.

Based on the second point, we created a directory nginx/ at the level of new-bee/ to create an nginx.conf file with the same name.

The nginx configuration code is here

  • Stop the nginx container first
docker stop nginx
Copy the code
  • Delete the nginx container
docker rm nginx
Copy the code
  • Rebuild the nginx container
docker run --name nginx -d -p 8888:80 -v /new-bee/dist:/usr/share/nginx/html -v /nginx/nginx.conf:/etc/nginx/nginx.conf:ro registry.docker-cn.com/library/nginx
Copy the code
  • See the effect
http://localhost:8888/#/
Copy the code

To prevent the browser from loading the 304 cache, clear the browser cache or put it in incognito mode

It has worked.

  • Let’s see how much the size has shrunk

It’s only about 50K, which is about 2/3 of the size, and for large projects, the savings are not just 100K, but even more. Compression algorithms like WebPack or GZ, mark all the pieces that repeat a lot individually, so the more they repeat, the more they compress. This is important for cloud services where bandwidth is now more expensive than gold.

CDN

Notice that some of the ones that can use CDN I choose to use CDN, so how important is CDN for online services?

The principle of

Request to speed

Without further ado, I’ll give you a comparison map to test the location

  • This is my forum

You can see that there are only a few places that are good, the rest of the place is a mess

  • This is taobao

Needless to say? But also good, this part we have insufficient funds lost is also very normal, but you may also know about the meaning of CDN, the main meaning is not save the open source project server bandwidth, but the national various nodes access speed, also explains: I deployment project access speed is good, why are you so slow here, your network is bad? CDN to tell you the answer.

cookie

Let’s take the actual BBS forum as an example to check the network status:

Several advantages of using CDN

  • Access to fast
  • Low pressure on the server
  • Webpack is small and fast (below)

The cookie on the client side is bound to the server domain name. As shown in the figure above, we need the XHR request to access the server with the cookie to obtain the corresponding permissions, but consider: Every JS, IMG and even CSS carries garbage cookies. With a large number of users, the server suffers from pain that should not belong to it, and such consumption should be avoided. We can browse any mature website and find our own CDN service. This not only optimizes the access speed of different regions in China, but also greatly reduces the overhead of the server.

Save webPack packaging size/speed

A long time ago, I experienced the problem of the company’s front-end Webpack compilation being very slow. In dev mode, we could note out routes outside the development scope, but it seemed impossible to solve the problem when the build was released. It was still not satisfactory to use Happypack multi-threaded packaging

We can exclude externals and use webpack’s webpack.dllPlugin to generate dependent libraries (which is important) with much less speed.DllPlugin essentially does the same thing as we do manually separating these third-party libraries. But for applications with a large number of packages, automation significantly accelerates productivity.

How do you analyze project dependencies

webpack-bundle-analyzer

Maven has its own set of data analysis tools, both from third parties. Here is a brief introduction to NPM data analysis tools: Webpack-bundle-analyzer, which generates a report in the browser that visually shows what is big, what needs to be optimized, and predicts the size of gZip, again using a live project as an example:

Download the build script specified in the dependencies, package.json file, as configured in the official guidelines:

"analyz": "NODE_ENV=production npm_config_report=true npm run buildProd".Copy the code

Run it:

npm run analyz
Copy the code

Effect:

Analysis:

Found the problem, the static to hightlight the documents/static file is large, rich enough to contemplate a CDN, node_modules/element – the UI hungry? Component is bigger, (I compare lazy, global import, which can be applied into which avoid global packaging problems) can be optimized, And then the boring students have nothing to do with it.

Webpack loads on demand: Everything module

Javascript packages can become very large when packaged to build applications, affecting page loads. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed. Webpack code segmentation function to achieve lazy loading of routing components.

Official details

Official said quite detailed, here is a lazy steal code, to provide you with a classic treatment, we do not put on the component, directly split the route, you can see the actual project route split route

You’ll find many comments like this:

const Blog = () = > import(/* webpackChunkName: "blog" */ '@/container/blog/Blog')
Copy the code

So something like this:

/* webpackChunkName: "blog" */
Copy the code

It is not written in vain, it is in collaboration with Webpack to split the project from each path, we can see the actual project load situation:

The blog. Hash. Js

It’s not written by us, it’s split by Webpack, so that a single page architecture like Vue doesn’t load a module and always loads all scripts, which greatly improves the loading speed.

The image processing

I don’t want to talk about it, but the most common ones are SVG, Base64, or cdN-like services that use fastDFS components.

base64

To put it simply, Base64 will reduce the number of HTTP requests you make. To know that XHR is not an easy light, it will bring additional processing request and processing response loss. For example, dozens of HTTP requests for facial expressions seem to be too retarding, so base64 is usually used for processing. Reduces the number of HTTP requests, but increases the size of the image itself. If you use Webpack and your emoticons are native, webpack can automatically base64 encoding for you.

The compressed image

Users to upload images can be compressed size or quality to reduce bandwidth oh, usually use GM is necessary for users to upload pictures of big lock compressed into different sizes, depending on the business load, such as head, the default will not request the original pictures, today’s headline text, use the traffic conditions will be loaded by default insets, None of this can be done on the client side and requires server side compression.

conclusion

Of course, the first step of the long march of knowledge, the future optimization of the road is vast, can probably think of such as: Lazy-load (optimizing the first screen experience), PWA (building a Web APP), server rendering (for SEO), skeleton screens (improving the user experience), the back end and server side have not been written yet.

SO – Work hard!

Blog archive address: github.com/pkwenda/blo…

Blog example address: github.com/pkwenda/new…