6

真-从零开始搭建自己的开源项目

 3 years ago
source link: https://segmentfault.com/a/1190000040723375
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

真-从零开始搭建自己的开源项目

发布于 9 月 23 日

真-从零开始搭建自己的开源项目
在线体验
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分哪个更好一点,不用在乎这一点,就一直往前学就可以了,有没有解决自己的问题才是关键。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK