Online experience
- https://cssbattle.wuwenzhou.com.cn/index Come and have a try, real warriors, see how many layers you can go down!!!
requirement analysis
- I found it on YouTube https://cssbattle.dev/ This practice css website (if you need to visit, remember to visit foreign websites). This is a good idea and triggered my own idea. In fact, this thing is a good application on icon. Because css is definitely one of the best practices for expressing web style.
- Advantages: using the new features of Web Components and css3 is definitely less resource loading, better rendering experience and simpler resource reuse than the current icon scheme. Similarly, a ring using svg needs 1237 bytes, while the css code only needs 160 bytes, and the compression ratio is close to 90%. There is basically no scene for Web Components to be played by the Componentization of the three frameworks, but is only ui rendered icon a good entry point?
- code implementation
class CircleInfo extends HTMLElement { constructor() { // Always call super first in constructor super(); // Create a shadow root const shadow = this.attachShadow({ mode: "open" }); const wrapper = document.createElement("span"); wrapper.className = "content"; wrapper.innerHTML = ` <div class="circle"></div> `; 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 < circle info > < circle info > in the body tag of html
- Advantages: some styles similar to absolute positioning still have global style penetration. The support of ide syntax tags is not very friendly. The zoom size must be realized with zoom. To put it bluntly, there are some mental burdens.
flow chart
sequenceDiagram front end->>front end:to write css of icon code front end->>front end:generate icon preview front end->>Server: Select the to use on demand icon Server->>Server: generate Web Components of js file Server-->>Alibaba cloud oss: upload oss Alibaba cloud oss-->>Business items: Import resource tag Business items-->>Business items: Select an icon to render
Technology selection
- Front end: react + umijs practice with your wife
- Back end: the high concurrency scenario of golang + gin + mongodb driver makes the overall business relatively simple
- Database: mongodb has simple business, most storage format code blocks and high concurrency support
- Tool support: Python + Flash + numpy + CV2 + tensorflow image recognition, code comparison, matching score, intelligent generation of icon
- Just learned everything before
Project start
Website basic preparation
- Tencent cloud link https://dnspod.cloud.tencent.com/
- Buy a domain name.
- Website filing - you need to buy a server for a certain period of time.
- Set DNS resolution.
- Download ssl certificate.
Project foundation preparation
front end
- Buying oss and writing scripts for packaging and uploading oss (note to add version number) can generally be done with CI CD using runne
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 construction completed`)); step('\nUploadOss...'); await uploadOss(); console.log(chalk.green(`oss Upload successful`)); 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'], { 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 profile complete`)); } try { main(); } catch (error) { console.log(error); console.log(chalk.red(`Task failed`)); }
- Purchase cdn and configure cdn policy.
Operation and maintenance and project management
- Containerization: using docker+ https://hub.docker.com/ + https://github.com/containrrr/watchtower Project deployment and update
Other precautions
Monitoring and embedding points
Baidu data + elk may also have some similar sentry, or some paid manufacturers' Shence and so on
python must configure the domestic image source of apt get and pip, otherwise the speed is worrying
golang also needs to configure the source and workspace
ENV GOPROXY=https://goproxy.cn,direct WORKDIR $GOPATH/src/github.com/fodelf/cssbattle
- ng configuration: pay attention to the support of history mode, and forward on 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; } location ^~ /api/ { # ^~/api represents a request that matches the prefix api proxy_pass http://110.42.220.32:9527; # Note: proxy_ The end of pass has /, - > effect: the path after / api / * will be spliced directly to the back when requesting # proxy_set_header function: set the request header value sent to the backend server (proxy_pass above) # [when the Host is set to $http_host, the value of the request header will not be changed; # When host is set to $proxy_host, the host information in the request header will be reset; # When it is the $Host variable, its value is the value of the Host field when the request contains the Host request header, and the main domain name of the virtual Host when the request does not carry the Host request header; # When it is $host:$proxy_port, which carries the port to send ex: $host:8080] proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # To obtain the user's real ip on the web server, configure the condition ① [$remote_addr value = user ip] proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# To obtain the user's real ip on the web server side, you need to configure the conditions ② proxy_set_header REMOTE-HOST $remote_addr; # proxy_set_header X-Forwarded-For $http_x_forwarded_for; # $http_x_forwarded_for variable = x-forward-for variable } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
summary
- Technology selection must be based on scenarios. In fact, the biggest scenario is business, image intelligent recognition and so on. Can't java do it? Can you do it? Whether there is such a person in the team, we should consider everything to maintain, but the first step is to figure out whether this choice is the most appropriate technology selection, and then learn technology. We should not degrade gracefully because of business pressure, and finally lack scalability and capacity.
- There is a full score or 60 points, which is better. Don't care about this. Just keep learning. Whether you solve your own problems is the key.