前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >真-从零开始搭建自己的开源项目

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

原创
作者头像
吴文周
修改2021-09-23 15:14:21
3830
修改2021-09-23 15:14:21
举报

在线体验

css.png
css.png

需求分析

  • 在看youtobe发现的cssbattle.dev/ 这个练习css的网站(如需访问大家记得科学上网)。这是很好的想法,也触发了我自己的想法,其实这个事情在icon上面是一个很好的应用。因为用css绝对是表达web样式的最佳实践之一。
  • 优势:使用 Web Components和css3的新特性绝对比现在的icon方案,更少的资源加载,更好的渲染体验,更简单的资源复用。同样一个圆环使用svg的方式需要1237个字节,而css代码只要160个字节,压缩比例接近百分之90,Web Components被三大框架的组件化打的基本没啥场景了,但是只有ui渲染的icon是不是一个很好的切入点呢?
圆环.svg
圆环.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
jiling.jpeg

技术选型

  • 前端:react + umijs 跟老婆一起练手一下
  • 后端:golang + gin + mongodb-driver 高并发的场景,整体业务比较简单
  • 数据库:mongodb 业务简单,存储格式代码块居多,高并发支撑
  • 工具支撑:python + flask + numpy + cv2 + tensorflow 图像识别,代码比较匹配得分,智能生成icon
  • 正好把之前学都上了
jis.jpeg
jis.jpeg

项目启动

网站基础准备

  • 腾讯云链接 dnspod.cloud.tencent.com/
  • 购买域名。
  • 网站备案-需要购买一定时间的服务器。
  • 设置DNS解析。
  • 下载ssl证书。
zhuce.png
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
oss.png
  • 购买cdn,配置cdn策略。
cdn.png
cdn.png

运维与项目管理

其他注意事项

监控和埋点

  • 百度数据+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.edu.cn/simple
复制代码
  • 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分哪个更好一点,不用在乎这一点,就一直往前学就可以了,有没有解决自己的问题才是关键。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在线体验
  • 需求分析
  • 流程图
  • 技术选型
  • 项目启动
    • 网站基础准备
      • 项目基础准备
        • 前端
        • 运维与项目管理
    • 其他注意事项
      • 监控和埋点
        • docker配置
        • 总结
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档