Online experience

  • Cssbattle.wuwenzhou.com.cn/index to give it a try, really can see his mighty under how many layer!!!!!!

Demand analysis

  • Check out youtobe’s discovery of cssbatto.dev /, an exercise in CSS (remember to visit science online if you need to). This is a good idea, which also triggered my own idea. In fact, this thing is a good application in icon. Because CSS is definitely one of the best practices for expressing web styles.
  • Advantages: The new features using Web Components and CSS3 are definitely less resource loading, better rendering experience, and easier resource reuse than the current ICON scheme. The same circlet using SVG needs 1237 bytes, while CSS code only needs 160 bytes, and the compression ratio is close to 90%. Web Components are almost no scene by the three major framework componentation, but is only the UI rendering icon a good starting point?

  • Code implementation
  class CircleInfo extends HTMLElement {
          constructor() {
            // Always call super first in constructor
            super(a);// Create a shadow root
            const shadow = this.attachShadow({ mode: "open" });
            const wrapper = document.createElement("span");
            wrapper.className = "content";
            wrapper.innerHTML = ` 
      
`
; const style = document.createElement("style"); style.textContent = ` .content { height: 400px; width: 400px; display: flex; justify-content: center; align-items: center; Zoom: 0.05; } .circle{width:200px; height:200px; border-radius:50%; box-shadow:0 0 0 10px red,0px 0 0 20px white,0px 0 0 30px red,0px 0 0 40px white,0px 0 0 50px red} `; shadow.appendChild(style); shadow.appendChild(wrapper); } } customElements.define("circle-info", CircleInfo); // Just add to the HTML body tag. Copy the code
  • Advantages: Some styles like absolute positioning still have global style penetration, IDE syntax tag support is not very friendly, zoom size must be implemented with zoom, which is a bit of mental burden to put it bluntly.

The flow chart

SequenceDiagram Front end ->> Front End: Write ICON code front end ->> Front end: Generate icon preview front end ->> Server side: Select icon server side to use on demand ->> Server side: Generate js file of Web Components server -->> Ali cloud OSS: upload OSS Ali cloud OSS -->> Business item: Import resource label business item -->> Business item: select a specific icon to render

Technology selection

  • React + umijs Practice with your wife

  • Back-end: Golang + gin + mongodb-driver with high concurrency, the overall service is relatively simple

  • Database: mongodb service is simple, storage format code block is in the majority, high concurrency support

  • Tool support: Python + flask + NUMpy + CV2 + Tensorflow image recognition, code comparison match score, intelligent generation icon

  • I just got through all the school

Project start

Website Basic preparation

  • Tencent dnspod.cloud.tencent.com/ cloud link
  • Buy a domain name.
  • Site record – need to purchase a certain amount of time server.
  • Example Set DNS resolution.
  • Download the SSL certificate.

Project Foundation Preparation

The front end

  • Buy OSS, write a package and upload oss scripts (note adding version numbers). Runne can be used with CI-CD
const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const execa = require('execa');
const { uploadOss } = require('./upload.js');
const run = async (command, commandArgs, opts = {}) => {
  await execa(command, commandArgs, { stdio: 'inherit'. opts }); };var targetVersion = '0.0.0';
const step = (msg) = > console.log(chalk.cyan(msg));
const args = require('minimist')(process.argv.slice(2));
async function main() {
  step('\nUpdateVersion... ');
  await updateVersion();
  step('\nUpdateConfig... ');
  await updateConfig();
  step('\nBuildPackage... ');
  await buildPackage();
  console.log(chalk.green('Static resource build complete'));
  step('\nUploadOss... ');
  await uploadOss();
  console.log(chalk.green('OSS uploaded successfully'));
  step('\nbuildDocker... ');
  await buildDocker();
  console.log(chalk.green('Web Docker published successfully'));
}

async function buildDocker() {
  await run('docker'['rmi'.'fodelf/cssbattleweb']);
  await run('docker'['build'.'-t'.'fodelf/cssbattleweb'.'. ']);
  await run('docker'['push'.'fodelf/cssbattleweb']);
}

async function buildPackage() {
  await run('npm'['run'.'build']);
  const { stdout } = await execa('git'['diff'] and {stdio: 'pipe' });
  if (stdout) {
    step('\nCommitting changes... ');
    await run('git'['add'.'-A']);
    await run('git'['commit'.'-m'.`chore(all): release v${targetVersion}`]);
  } else {
    console.log(chalk.green('No changes to commit.')); }}async function updateVersion() {
  const pkgPath = path.resolve(__dirname, '.. /package.json');
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
  const currentVersion = pkg.version;
  console.log(chalk.green('Online version number${currentVersion}`));
  let versions = currentVersion.split('. ');
  versions[2] = Number(versions[2]) + 1;
  targetVersion = versions.join('. ');
  console.log(chalk.green('Release version number${targetVersion}`));
  pkg.version = targetVersion;
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null.2) + '\n');
}

async function updateConfig() {
  const jsPath = path.resolve(__dirname, '.. /.umirc.ts');
  var data = fs.readFileSync(jsPath, 'utf8');
  const pkgPath = path.resolve(__dirname, '.. /package.json');
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
  data = data.replace(
    /(\wuwenzhou.*? \')/g.`wuwenzhou.com.cn/web/${pkg.version}/ '`,); fs.writeFileSync(jsPath, data);console.log(chalk.green('Modify configuration file completed'));
}
try {
  main();
} catch (error) {
  console.log(error);
  console.log(chalk.red(Task failed));
}

Copy the code

  • Purchase a CDN and configure a CDN policy.

Operation and maintenance and project management

  • Containerization: use docker + hub.docker.com/ + github.com/containrrr/… Deploy and update the project

Other Matters needing attention

Monitor and bury points

  • Baidu data + ELK may also have some similar to Sentry, or some paid manufacturer shence and so on

Docker configuration

  • Python must be configured with apt-get and PIP domestic mirror sources otherwise the speed will be too slow
RUN sed -i 's|security.debian.org/debian-security|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
RUN  pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
Copy the code
  • Golang also requires the configuration of sources and workspaces
ENV GOPROXY=https://goproxy.cn,direct
WORKDIR $GOPATH/src/github.com/fodelf/cssbattle
Copy the code
  • Ng configuration note that history mode is supported, forwarding ports 80 and 443 under HTTPS
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 2048; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; client_max_body_size 10M; server { listen 80; server_name *.wuwenzhou.com.cn; return 301 https://$host$request_uri; } server { listen [::]:443 ssl http2 ipv6only=on; listen 443 ssl http2; charset UTF-8; server_name *.wuwenzhou.com.cn; client_max_body_size 4M; root html; index index.html index.htm; ssl_certificate /etc/nginx/1_cssbattle.wuwenzhou.com.cn_bundle.crt; ssl_certificate_key /etc/nginx/2_cssbattle.wuwenzhou.com.cn.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:! NULL:! aNULL:! MD5:! ADH:! RC4; Ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } the location ^ ~ / API / {# ^ ~ / API proxy_pass http://110.42.220.32:9527; said matching prefix for the API request # proxy_set_header ('/API /* ', '/ API /*') $proxy_host = $proxy_pass; $proxy_pass = $proxy_pass; $proxy_pass = $proxy_pass $host:$proxy_port; $host:$proxy_port; $host:$proxy_port; $host:$proxy_port; $host:8080 】 proxy_set_header host $host; proxy_set_header X-Real-IP $remote_addr; [$remote_addr = http_forwarded_for] Proxy_set_HEADER X-Forwarded_for; ② proxy_set_header remote-host $remote_addr; # proxy_set_header X-Forwarded-For $http_x_forwarded_for; $http_x_forwarded_for = x-Forwarded-for} error_page $http_x_forwarded_for = x-Forwarded-for} error_page $http_x_forwarded_for = x-Forwarded-for; location = /50x.html { root /usr/share/nginx/html; }}}Copy the code

conclusion

  • Technology selection must be based on the scene, in fact, the biggest scene is business, image intelligent recognition and so on Java can not do? Can do? If there is such a person in the team, it is necessary to consider what to maintain, but the first step is to think clearly about whether this is the most appropriate technology selection, and then to learn the technology. Don’t downgrade gracefully because of business pressures, and end up being less scalable and capable.
  • There is a full mark and door door 60 minutes which is a bit better, need not care about this, it is ok to learn forward all the time, have solved his problem is the key.