乐趣区

关于前端:真从零开始搭建自己的开源项目

真 - 从零开始搭建本人的开源我的项目
在线体验
cssbattle.wuwenzhou.com.cn/index 来试一试,真的壮士看本人能下多少层!!!
css.png

需要剖析
在看 youtobe 发现的 cssbattle.dev/ 这个练习 css 的网站(如需拜访大家记得迷信上网)。这是很好的想法,也触发了我本人的想法,其实这个事件在 icon 下面是一个很好的利用。因为用 css 相对是表白 web 款式的最佳实际之一。
劣势:应用 Web Components 和 css3 的新个性相对比当初的 icon 计划,更少的资源加载,更好的渲染体验,更简略的资源复用。同样一个圆环应用 svg 的形式须要 1237 个字节,而 css 代码只有 160 个字节,压缩比例靠近百分之 90,Web Components 被三大框架的组件化打的根本没啥场景了,然而只有 ui 渲染的 icon 是不是一个很好的切入点呢?
圆环.svg

代码实现
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);
// 只须要在 html 的 body 标签中增加 <circle-info><circle-info>
复制代码
劣势:一些相似相对定位的款式仍然会呈现全局款式穿透,ide 语法标签的反对不太敌对, 缩放大小必须配合 zoom 实现,说白了就有一些心智累赘。
流程图
前端
服务端
阿里云 oss
业务我的项目
编写 css 的 icon 代码
生成 icon 预览
按需抉择应用的 icon
生成 Web Components 的 js 文件
上传 oss
引入资源标签
具体抉择某个图标渲染
前端
服务端
阿里云 oss
业务我的项目
jiling.jpeg

技术选型
前端:react + umijs 跟老婆一起练手一下

后端:golang + gin + mongodb-driver 高并发的场景,整体业务比较简单

数据库:mongodb 业务简略,存储格局代码块居多,高并发撑持

工具撑持:python + flask + numpy + cv2 + tensorflow 图像识别,代码比拟匹配得分,智能生成 icon

正好把之前学都上了

jis.jpeg

我的项目启动
网站根底筹备
腾讯云链接 dnspod.cloud.tencent.com/
购买域名。
网站备案 - 须要购买肯定工夫的服务器。
设置 DNS 解析。
下载 ssl 证书。
zhuce.png

我的项目根底筹备
前端
购买 oss, 编写打包上传 oss 脚本(留神增加版本号)个别能够配合 ci-cd 应用 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( 动态资源构建实现));
step(‘\nUploadOss…’);
await uploadOss();
console.log(chalk.green(oss 上传胜利));
step(‘\nbuildDocker…’);
await buildDocker();
console.log(chalk.green(web docker 公布胜利));
}

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(线上版本号 ${currentVersion}));
let versions = currentVersion.split(‘.’);
versions[2] = Number(versions[2]) + 1;
targetVersion = versions.join(‘.’);
console.log(chalk.green(公布版本号 ${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(批改配置文件实现 ));
}
try {
main();
} catch (error) {
console.log(error);
console.log(chalk.red( 工作失败));
}

复制代码
oss.png

购买 cdn,配置 cdn 策略。
cdn.png

运维与项目管理
容器化:应用 docker + hub.docker.com/ + github.com/containrrr/… 进行我的项目部署与更新
其余注意事项
监控和埋点
百度数据 +elk 可能还有一些相似 sentry, 或者一些付费的厂商神策等等
docker 配置
python 肯定要配置 apt-get 和 pip 的国内镜像源 否则速度堪忧
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.ed…
复制代码
golang 也是须要配置源以及工作空间
ENV GOPROXY=https://goproxy.cn,direct
WORKDIR $GOPATH/src/github.com/fodelf/cssbattle
复制代码
ng 配置留神 history 模式的反对,在 https 上面 80 和 443 端口的转发
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 示意匹配前缀为 api 的申请
    proxy_pass  http://110.42.220.32:9527;  # 注:proxy_pass 的结尾有 /,-> 成果:会在申请时将 /api/* 前面的门路间接拼接到前面
    # proxy_set_header 作用:设置发送到后端服务器 (下面 proxy_pass) 的申请头值  
        #【当 Host 设置为 $http_host 时,则不扭转申请头的值;
        #   当 Host 设置为 $proxy_host 时,则会从新设置申请头中的 Host 信息;
        #   当为 $host 变量时,它的值在申请蕴含 Host 申请头时为 Host 字段的值,在申请未携带 Host 申请头时为虚拟主机的主域名;
        #   当为 $host:$proxy_port 时,即携带端口发送 ex: $host:8080】proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; # 在 web 服务器端取得用户的实在 ip 需配置条件①【$remote_addr 值 = 用户 ip】proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 在 web 服务器端取得用户的实在 ip 需配置条件②
    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   500 502 503 504  /50x.html;
location = /50x.html {root   /usr/share/nginx/html;}
}

}

复制代码
总结
技术选型肯定要基于场景,其实最大的场景在于业务,图像智能辨认等等 java 不能做吗?能做?团队外面有没有这样的人,保护什么都是要思考的,然而第一步要想分明这样抉择是不是最合适的技术选型,再去学习技术。不能因为业务压力去优雅降级,最初扩展性和能力有余。
有一门满分和门门 60 分哪个更好一点,不必在乎这一点,就始终往前学就能够了,有没有解决本人的问题才是要害。

退出移动版