猫窝私语 — Makumo's Blog

玛酷猫的温馨小窝,记录生活点点滴滴。

@玛酷猫6 天前

03/9
00:50
AI

从零开始用AI搓网站(二)

无数次历史都证明,重启能解决一切问题,如果不行,那么就再重启一次。重启以后编译器问题解决了,终于能快乐的输入hello world了。

下一步就是开个github仓库,这样有兴趣的养虾人可以自行去上面看看iFlow是如何一步一步编写代码的。由于自己本来就有github,直接新建一个叫cpp_practice_website的仓库,可以在activity里面看到每次提交内容。由于很久前配置过github密钥,将仓库地址喂给iFlow,第一次push意料之中的失败了。给出的提示是访问被拒绝,那大概就是密钥的问题。翻了下用户的.ssh/目录下,才发现之前配置过config文件,里面针对不同的host使用不同的密钥。重新将使用正确的host的github地址交给iFlow,再次push依旧报错。检查了下github后台管理的公钥列表居然是空的,估计可能时代太久远了,密钥更换了格式/或者单纯过期了。先解决密钥问题,用命令生成一对密钥

# xxx随便写,就是个备注,最后面是文件名,和其他区分,单独起了个名字
ssh-keygen -t rsa -b 4096 -C "xxx" -f id_rsa_alittlesir

然后将公钥上传到github后台,终端用命令测试下

ssh -T git@github.com

正常情况会得到github的欢迎词,Hi xxx! You’ve successfully authenticated, but GitHub does not provide shell access.
着我这却显示:“Error connecting to agent: No such file or directory”,查了下,是说open-ssh服务没开,用命令启动open-ssh,提示:无法启动ssh-agent服务,错误:1058,查了下系统设置,服务里面居然没有open-ssh。在设置->系统->可选功能->添加可选功能里面,显示open-ssh服务已经安装。估计是这个服务坏掉了,老办法,卸载重新安装,安装完了后测试了下,没有问题。可以正常的提交。
之前在处理编译器的时候iFlow尝试各种方案,其中有种就是把绝对路径写入代码里面,这显然是不安全的,让iFlow检查所有的文件,查看是否存在盘符的情况。

接下来的功能就是添加参考答案,直接对iFlow说:新增结构存参考答案,在前段新增查看参考答案的功能。
iFlow直接在题目的json结构里面,添加了参考答案,并且在前段添加了显示参考答案和将参考答案填入编辑器的功能。分分钟就出来了,效果看着还不错。

今天刚看到58大神沈剑的公众号提到“龙虾”的安全性问题,于是仿照文章的说法,也给iFlow加上了一些简单的规则,也添加了备份的规则。同时iFlow自身也有一定的判断,中高风险的操作也会在界面询问是否执行。iFlow对规则理解有些偏差,当我让它添加某一个规则,就比如修改.md文件的时候自动备份,它总是写出一个程序代码来实现,需要反复和他说这是你的角色规则,不需要额外的代码编写,他才会把这个写入自己的AGENTS.md文件中。

之前创建基础结构的时候自带了3个题目,我便问它这3个题目是你的知识库还是即兴生成的,它居然忘了,说是我或者其他开发者创建的,我和它说这个文件夹下面所有文件都是它创造的,我没有任何参与,它才承认,蛮有意思,然后我就让它在创建50道题目,嘿嘿

——two thousand years later——

经过漫长的时间,终于完成,还给了一个清单

接着就是经典的json格式问题,又让它修了半天。
由于数字数位问题,习题编号不连贯,我让它将所有数字数位全部改成4位,它也理解我的意思,但是在执行命令的时候出现严重的问题,

问题很严重!很多文件的 JSON 格式都被破坏了。这是因为 PowerShell 的替换操作有问题。让我检查一个损坏的文件
我看到了问题!description 字段中的中文被破坏了。这是因为 PowerShell 的文件操作可能使用了错误的编码。让我使用 Node.js来修复所有文件。我需要从 git 恢复这些文件:
问题已经提交到 git 了。我需要重置到之前的状态:
糟糕!文件已经损坏并被提交了。我需要删除所有损坏的文件,然后重新创建。让我先删除 problems 目录:

感觉这个问题让iFlow一步一步崩坏了。我及时按esc取消了iFlow的进一步操作,由于已经从git回滚,problems下面包含没问题的1-50题目,和有问题的0001-0050题目,AI这块貌似不会处理了,准备一起干掉重新生成题目,那又要“two thousand years later”了。只能有人强制介入指挥它来行动,删除0001-0050这些有问题的题目,剩下的1-50题目检查JSON问题,都检查完后,做一个submit,免得再操作失误,回滚又要修正这50个题目里面的几个json问题。紧接着我询问你有没有其他方式更换4位数字。它在一顿尝试使用shell、脚本、node、python得到各种报错后,和我说PowerShell就是垃圾,太复杂了。咱还是不要动文件了,直接改前端显示页面吧。

随后又修改前端代码解决顺序问题。由于题目增加,页面左侧题目变长,我询问该如何处理,它给出了一些列处理办法。

小孩子才做选择,当然是全都要了。这次修改倒是挺快,完成后页面像这样。

终于有点像样了。今天就折腾到这吧,顺便查了下token用量,好家伙,一晚上直接干掉3千万。所以说养虾有风险,入行需谨慎。

项目地址:https://github.com/makumo/cpp_practice_website/ 有兴趣的可以去围观

从零开始用AI搓网站(二)

@玛酷猫1 周前

03/7
23:11
AI

从零开始用AI搓网站(一)

书接上回,装好iFlow CLI后,本地新建了一个aiprojecct文件夹,打开终端,进入该文件夹。运行

iFlow
#会打开浏览器跳转到心流平台登录认证
/init

iFlow将自动分析文件夹现有的文件目录(虽然是个空的),并生成AGENTS.md文件,并将一些基本环境信息写入其中。最有意思的是它根据文件名,“猜测这可能是一个计划用于AI相关开发的Node.js项目”。(新建文件夹的时候建到Node_project文件夹下了)随后给出了建议步骤。

初始化完成给,我给了它一个简单的需求:这是一个网站项目,网站用途是练习C++语言,网站会显示一些题目,用户需要在指定区域用C++编写需要的程序,提交后,网站会根据输入输出结果判断用户编写程序是否正确。
iFlow分析完这个简单的需求,梳理功能,项目结构建议,开发步骤,并给出两个技术栈方案。

我再次询问:建议采用哪种语言编写
iFlow给出了它的建议和理由,并询问时候开始搭建

回答当然是开始搭建
紧接着就是iFlow的亿顿操作猛如虎

感觉这不是一会半会能结束了,就去干别的了。

——two thousand years later——

等我再回看来得时候,iFlow已经干完了,并给出了下一步操作

那当然是安装依赖并启动了
又是亿顿操作,然后和我说已经完成了,并给出了测试地址,同时还生成个3道测试题目,第一道题目还是最经典的“Hello World – 输出 “Hello, World!””
当我满怀期望的打开测试页面,等待我的是一片空白。。。。反馈给iFlow,iFlow先是发现缺少某个依赖,加上后再让我重试,刷新页面后依旧空白,再次检查后才发现缺少bundle.js的引用,再次让我刷新,这回不是空白了,出现了标题,但是练习题不显示,继续反馈给iFlow,iFlow在代码中添加了很多console.log日志输出排查,最终发现习题的json格式错误,修正后,页面显示终于正常了。并且给出了hello world习题的答案给我测试。

看到页面刷出来的时候,“amazing!”脱口而出,右边填写给出的答案,现实却是比较残酷的,测试结果直接是错误。
再次提交给iFlow,iFlow多次排查错误后,找到原因,没有C++的编译器,被给出了解决办法

然后最坑的地方到了,MinGW-w64官网下载速度慢的令人发指,于是用planB,使用MSYS2,这个现在倒是还能接受,安装完后,按照提示安装mingw

pacman -S mingw-w64-x86_64-gcc

安装也完成,也把bin添加到系统PATH环境变量
然后再终端测试c++,各种提示没有该命令,估计要重启电脑试试。
重启倒是不急,继续安排iFlow工作,生成项目文档、API文档、开发指南文档,随后创建git控制。由于要重启电脑,让iFlow将目前的对话内容保存起来,形成文档,方便以后查阅。
都处理完了,接下来就准备重启,看看如何解决C++编译器的问题了。

从零开始用AI搓网站(一)

@玛酷猫1 周前

03/6
23:56
AI

从零开始用AI搓网站(零)

最近龙虾(OpenClaw)横空出世,火到全网,大家都在纷纷养虾,分享养虾经验。网上甚至还出现上门安装业务,居然收费高达500,理解不能。作为一个不甘落后、海鲜过敏的程序员大叔,也投入到折腾龙虾的汪洋大海中,一番扑腾,一身鱼腥。事实证明,龙虾好弄,养起来很难。
OpenClaw官网很简洁,安装命令只有一条,本体+依赖+环境统统一步到位

# Works everywhere. Installs everything. You're welcome. 🦞
iwr -useb https://openclaw.ai/install.ps1 | iex

在powershell里面直接输入运行就能完成安装,但是也仅仅是安装,光配置就能难倒一大群人。首先是纯命令行的模式,让习惯使用UI配置的人直接麻瓜了,其次OpenClaw虽然是开源免费的,但是它需要一个大模型的API KEY,而大模型基本都是收费的,实际用下来token消耗相当的感人。所以如果只是尝鲜,建议还是再等等,以现在的发展趋势,过几个月各方面会更成熟,token的价格也会更便宜些。

正准备洗洗鱼腥,在岸边看别人养虾的时候,发现了阿里的iFlow CLI,主打一个包含各大模型,关键是token免费。这不弄只养养太对不起他的免费的价格了,养“虾”最好的方式莫过于找个项目实际操作了,于是乎就有了这个系列。之前朋友提起过他家孩子想学编程,需要一套检测学习成果的系统,当时想想开发起来蛮复杂的。正好可以用iFlow CLI从0开始搓一个C++学习网站,边搓边学习AI的调教。原则上自己不参与任何代码的编写,只提要求和看结果,其他完全交给AI。

说干就干,首先是安装,iFlow CLI需要Node22版本以上,控制台里面看了下环境,电脑居然有Node,也不知道啥时候装的,查了下版本,9.0,也是个古董版本。卸载了,从官网找到最新的版本,下载,安装。按建议安装了微软的终端Windows Terminal用来替代自带的PowerShell,安装好后打开终端,输入

npm install -g @iflow-ai/iflow-cli@latest
#测试安装成功与否
iflow --version

安装完后就可以干活了,具体工作就放在下一期。
PS:贴下今天的成果,网站一共创建了20个文件,共9652行代码。使用默认glm-4.7大模型,token使用量到了夸张的14,722,468,要是按照行情,每百万7块钱,一张毛爷爷没了。

从零开始用AI搓网站(零)

@玛酷猫5 年前

06/24
14:16
PHP

升级PHP8踩坑记

最近后台总是提示当前使用PHP(7.2)版本过低,建议升级7.4。看着着实难受,干脆直接升到8.0好了,免得过段时间又开始不停的弹提示。说干就干,作为一个懒人,本着能yum坚决不make的态度,先去查了下remi源里面,已经有了8.0的版本。

yum repolist all |grep php

没有remi源的话可以用下面命令添加

yum -y install https://mirrors.aliyun.com/remi/enterprise/remi-release-7.rpm

后面的就简单了

# 先卸载掉老的版本
yum remove php-*
# 切换PHP8的源
yum-config-manager --enable remi-php80
# 安装
yum install php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redis php-opcache

然后重启httpd,然后就是经典的报错了。。错误代码Invalid command ‘php_admin_value’。查了下站点的配置文件,使用的是如下配置

php_admin_value open_basedir "站点目录:/tmp/:/var/tmp/:/proc/"

这是将php作为httpd的一个module使用,为嘛使用这个已经无法考证了,估计八成多年前从哪抄来的。网上搜了下,基本都是说httpd缺少module,在编译的时候需要修改配置,加上–with-apxs2参数,要重新编译。我这是直接yum的,这个就跳过。此外还有更换调用方法,例如FastCGI模式,将php-fpm作为服务启动,httpd将.php的请求发送到php-fpm服务上。懒人理念直接跳过,google上翻了半天,终于找到了解决办法,一句话

yum install mod_php

这才对嘛,既然是yum安装的问题,肯定可以用yum的方法解决。重启httpd,已经正常启动,打开网站,500错误,意料之中,毕竟大版本升级。查看了下httpd的日志,某个10年前的插件中还存在这个函数create_function(),而货已经在8中被干掉了,直接删除了这个插件。刷新,页面轻松打开,重新查看了下日志,一大堆PHP Warning,都是插件的问题,这个就主要等着各位插件作者后续更新了。

升级PHP8踩坑记

@玛酷猫7 年前

01/10
14:39
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)

接下来就是页面的迁移,先用命令创建原来项目对应的页面,例如登录页面

ionic g page pages/signIn

这是会在src/app/pages目录下面生成sign-in文件夹,里面包含5个文件,相对于Ionic3,除了文件名命名有些许区别外,同时还多了一个测试文件,对比下Ionic3的sign-in.ts和4的sign-in.page.ts文件的主体结构

# ionic3
import { Component, OnInit } from '@angular/core';
@IonicPage({
  segment: 'sign-in'
})
@Component({
  selector: 'page-sign-in',
  templateUrl: 'sign-in.html',
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

# inoic4
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
  selector: 'app-sign-in',
  templateUrl: './sign-in.page.html',
  styleUrls: ['./sign-in.page.scss'],
  encapsulation: ViewEncapsulation.None
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

整体上差别不大,主要区别在@Component部分,选择器的命名,模板文件和样式文件的引用,3中的@IonicPage部分在4种移除,部分功能被放在Angular的路由中。此外特别提下encapsulation: ViewEncapsulation.None的问题,这部分我也没完全弄明白,大概理解是Ionic4使用了标准的Web Components,可以在页面上看到大量的shadow-dom,默认情况下,由于Angular提供的样式包装机制来封装组件,使得组件的样式不受外部影响,就是说无法修改组件的样式,所以这里要将封装模式调整成none,以便于修改组件的样式,详细说明请参考官方文档,传送门。此外由于使用标准Web Components,样式也要大量的使用CSS4 Variables的写法。

页面生命周期

在Ionic3中,常用的页面生命周期函数有下面6种

  • ionViewDidLoad 当页面加载的时候触发,仅在页面创建的时候触发一次,如果被缓存了,那么下次再打开这个页面则不会触发
  • ionViewWillEnter 当将要进入页面时触发
  • ionViewDidEnter 当进入页面时触发
  • ionViewWillLeave 当将要从页面离开时触发
  • ionViewDidLeave 离开页面时触发
  • ionViewWillUnload 当页面将要销毁同时页面上元素移除时触发

在Ionic4中,使用Angular的生命周期函数,具体ionViewDidLoad被ngOnInit替代,ionViewCanEnter和ionViewCanLeave被路由守卫替代,其他的暂时可以正常使用,不过可能在以后的版本中被其他用法做代替。

组件的标准化

由于使用Web Components标准,很多组件和属性的写法也发生变化,譬如

// ionic 3
<button type="button" ion-button clear small icon-start (click)="findPassword()" class="option-password">忘记密码</button>

<ion-list radio-group no-lines [(ngModel)]="schoolCode">
  <ion-item *ngFor="let s of schools">
    <ion-avatar item-start><img src="{{s.logo}}"></ion-avatar>
    <ion-label>{{s.name}}</ion-label>
    <ion-radio value="{{s.code}}"></ion-radio>
  </ion-item>
</ion-list>

// ionic 4
<ion-button type="button" fill="clear" size="small" (click)="findPassword()" class="option-password">忘记密码</ion-button>

<ion-list lines="none">
  <ion-radio-group [(ngModel)]="schoolCode">
    <ion-item *ngFor="let s of schools">
      <ion-avatar solt="start"><img [src]="s.logo" alt=""></ion-avatar>
      <ion-label>{{s.name}}</ion-label>
      <ion-radio [value]="s.code"></ion-radio>
    </ion-item>
  </ion-radio-group>
</ion-list>

除了button标签替换成ion-button以外,很多属性也发生变化,譬如button的所有属性都进行了更换,clear更换成fill=“clear”等,其他标签的属性,譬如item-start更换为solt=“start”,此外类似radio-group的用法也发生大变化。由于不少用法发生变化,具体还是对应着官方文档进行迁移,传送门

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)

@玛酷猫7 年前

01/4
10:59
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(二)

首先是更新NodeJS版本,Angular6要求版本不低于8.X,由于之前安装高版本的nodeJS一直有着不可描述的问题,导致node-sass无法安装,无奈只能安装6.X的版本使用本地文件来强行安装node-sass,不过现在貌似没这个问题了。更新也比较方便,卸掉重新安装就好了。
开启一个新的tab项目,详细的安装可以参考官方文档

ionic start myApp tabs --type=angular

provider迁移
项目建好后,先将原来项目中的provider复制到新项目中,这时候会看到满篇的错误提示,一个一个来调整。
1、storage在Ionic4中不再是默认自带,需要单独安装

npm install --save @ionic/storage

2、换用新的http模块

//ionic3 部分代码
import { Http, Headers, RequestOptions } from '@angular/http';
//……中间其他代码……
const headers = new Headers();
let Token: string = '';
headers.append('Token', Token);
this.options = new RequestOptions({ headers: headers });

//ionic4 部分代码
import { HttpClient, HttpHeaders } from '@angular/common/http';
//……中间其他代码……
const headers = new HttpHeaders();
let Token: string = '';
headers.set('Token', Token);
this.options = { headers };

由于需要和数据服务器API通讯,用户的信息token是存放在请求的header中,在Ionic3中使用的Headers, RequestOptions来处理请求头部,这两个组件在3中也属于不推荐使用的,当时因为还能用,图省事就继续使用了。4种更换为HttpClient、HttpHeaders,和以前方法使用变化不大,调整下就好。

3、调整Components用法,这部分也是整个项目变动最多的地方,几乎所有的Controller都有参数变动和使用方法的变动,想像迁移文档说的那样直接复制进来就能用基本没法实现。举个例子,项目中有个全局的顶部消息提示控件

//ionic3
toast(message: string) {
  this.toastCtrl.create({
    message: message,
    duration: 1500,
    position: 'top'
  }).present();
}

//ionic4
async toast(message: string) {
  const toast = await this.toastCtrl.create({
    message: message,
    duration: 1500,
    position: 'top'
  });
  toast.present();
}

在Ionic3中可以直接创建后接present()来触发使用,而在4中,需要配合async/await来使用。

4、RxJS的调整,官方有个迁移文档,传送门,并且给出了一个迁移工具,不过试了下不是太好用,可能原本的项目写的就不是很规范,只能自动修复一小部分。还是老老实实手动来吧,顺便加深下印象。以下是一个登录的代码片段

//ionic3
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
//……中间其他代码……
PostSignIn(request: PostUserSignInRequest): Observable<any> {
  return this.http.post(this.coreService.baseUrl + '/tokens', request)
    .map(res => res.json());
}

//ionic4
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
//……中间其他代码……
PostSignIn(request: PostUserSignInRequest): Observable<any> {
  return this.http.post(this.coreService.baseUrl + '/tokens', request)
  .pipe(map(res => res));
}

首先是引入调整,这个全项目批量替换下就好,然后是原来的链式操作(dot-chained operators)要更换为管道操作(pipeable operators),简单点说就是将原先所有的.xxx操作全部放置到pipe()这个方法中,其他的用法项目中用到的少,可以去查看官方文档。

Ionic 3 升级 Ionic 4 迁移踩坑系列(二)

@玛酷猫7 年前

01/3
23:01
WordPress 建站日志

小窝加装泛域名SSL证书

(本来打算写在上篇的,篇幅有点长,干脆拆成两篇好了)
书接上回,话说随着chrome的版本更新,所有的http访问的网站都会在网址前面标一个大大的不安全,这都9102年了,不给网站弄的SSL证书也太不像话了。免费证书哪家强,当然是选择Let’s Encrypt,而且今年去年年中的时候已经支持泛域名的证书,B格更高,同时也推出了新的申请方式,相对于以前单个域名的申请,方便很多。

首先要下载acme.sh,安装成功后断开重新连接下终端,要不会后续的命令提示找不到

curl https://get.acme.sh | sh

由于acme.sh可以自动配置DNS,这就需要获取到域名的API,我的域名是使用DNSPOD解析的,这里就用DNSPOD做例子,其他的请参考官方指南。登录DNSPOD,在控制台——用户中心——安全设置里面,启用API Token,创建新的API Token,这里一定要保存好Token,因为这个是只显示一次,关掉后就没法获取完整,只能删掉重新建,同时记下Token对应的ID,然后运行下面命令,等待120秒验证,屏幕上会显示倒计时,如果一切正常的话,屏幕会显示申请成功并显示4个证书文件的路径。

export DP_Id='ID数字'
export DP_Key='Token字符串'
acme.sh --issue -d makumo.com -d *.makumo.com --dns dns_dp

然后打开站点的Nginx的配置文件,添加相关的配置,例如:

server 
    {
        listen 443 http2 ssl;
        server_name makumo.com;
        index index.html index.php;
        root  站点目录;
        ssl_certificate /root/.acme.sh/makumo.com/fullchain.cer;
        ssl_certificate_key /root/.acme.sh/makumo.com/makumo.com.key;
        ssl_trusted_certificate  /root/.acme.sh/makumo.com/ca.cer;
        include proxy-pass-php.conf;
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }
        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }
        location ~ /\.
        {
            deny all;
        }
}

proxy-pass-php.conf文件即为上一篇中的关于转发到Apache的部分.

nginx -s reload

重新加载Nginx配置文件就能使用https访问站点,这时候还会存在几个问题,站点中图片、脚本、样式还是使用的http来引入,在浏览器中会报出错误,后台无法进入,浏览器会显示过多的重定向,网络里面会看到一堆的302重定向,搜了下,绝大部分都会说在Wordpress配置文件中添加开启SSL的配置,如下:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

但是我这么设置后,前台没问题了,后台还是无法进入,虽然不报过多的重定向,直接报403错误了。
搜素了半天,还在有更简便的解决方案,安装插件really-simple-ssl,一次性解决各种恶心的问题。
另外,由于站点使用七牛作为图片的CDN缓存,站点切换为https后也需要将七牛的CDN改成https模式,在七牛的后台添加下证书(之前申请证书的4个文件,fullchain.cer是证书,域名.key就是对应的密钥),关联域名开启SSL就好了,这也是泛域名证书的方便之处,不用再次申请单域名证书了。七牛的https是收费的,看了下,0.28元/G,之前还有赠送的10元余额。应该能用段时间。

小窝加装泛域名SSL证书

@玛酷猫7 年前

12/28
16:31
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(一)

Angular今年的发展真是快,去年年底5刚刚发布,年中就发布6,到年底7也来了,大版本的升级也导致它的很多组件也随之升级,慢慢的放弃了对低版本的支持,这对于使用基于Angular的Ionic开发的本人来说就是件很郁闷的事情。之前一直使用Ionic 3开发项目,还是基于Angular5的,年中的时候本地开发环境更新组件没注意,直接把Angular升级到6了,然后可想而知,项目直接跑不起来了。还原package.json后每次更新组件都检查下版本,避免错误升级,很是麻烦。随着Ionic4的测试版本不断的更新,Ionic cli动不动就提示更新Ionic4,稍不留神就傻逼,再加上越来越多的组件默认使用Angular 6,主要是其中RxJS的语法变动很大,导致没法向下兼容5,这也将Ionic升级到4的想法提上日程。毕竟ios和android还在不停的更新版本,每次更新或多或少都会出现兼容性问题,组件导致的兼容性问题主要还是靠组件作者更新,虽然可以自己fork一个分支处理,毕竟费时费力。

去Ionic官网翻了翻迁移指南,官方写的实在是太简单,全文如下:

  1. Generate a new project using the blank starter (see Starting an App)
  2. Copy any Angular services from src/providers to src/app/services
    • Services should include { providedIn: ‘root’ } in the @Injectable() decorator. For details, please see Angular provider docs.
  3. Copy the app’s other root level items (pipes, components, etc) keeping in mind that the directory structure changes from src/components to src/app/components, etc.
  4. Copy global Sass styling from src/app/app.scss to src/global.scss
  5. Copy the rest of the application, page by page or feature by feature, keeping the following items in mind:
    • Emulated Shadow DOM is turned on by default
    • Page/component Sass should no longer be wrapped in the page/component tag and should use Angular’s styleUrls option of the @Component decorator
    • RxJS has been updated from v5 to v6 (see RxJS Changes)
    • Certain lifecycle hooks should be replaced by Angular’s hooks (see Lifecycle Events)
    • Markup changes may be required (migration tool available, see Markup Changes)

In many cases, using the Ionic CLI to generate a new object and then copying the code also works very well.

大概意思就是用命令新建一个空的项目,将原来项目各个部分拷贝进来,注意4的路径有所调整。服务的声明有所调整、全局样式文件不一样、RxJS请自己看升级文档、页面生命周期时间沿用Angular。看来不麻烦呀,于是乎我就傻呵呵的按着文档操作一顿后,都不用试跑的,IDE上满屏幕的红色波浪线(各种错误)仿佛在嘲笑。看了看IDE上面提示的各种错误,连最基本的ionic、angular的引用方式都有所变化,我就不信有人能按照这个智障的迁移文档,把项目跑起来。尤其是看到文档最后一句话:“In many cases, using the Ionic CLI to generate a new object and then copying the code also works very well. ”,还信誓旦旦的说大部分情况下按照这个操作项目都能跑起来,我&……¥&*……&#,还是老老实实一个模块一个页面的迁移好了。

经历的大半个月的迁移工作,虽说还没有完全结束,迁移过程中踩的坑可真不少,准备做一个系列来写了。一方面记录下的这些问题,方便以后查看,另一方面也希望帮助其他的人,毕竟目前在国内,相对于React和Vue,Angular还太小众,各种文档和解决方案都很少,遇到问题都要爬google搜索,要不就去啃官方论坛和stackoverflow。

随带一提的是Ionic(Angular)的发展简直是坑神一样的存在,当年AngularJs升级Angular(ionic1到2)的时候,惊呼上当受骗,本以为是个版本升级,能迁移的时候菜发现这明明就是两种不同的东西,没办法相当于重新学了一遍,ionic2/3到4又相当于再重学一边,4为了更标准化web component,修正了以前版本各种不标准的用法和属性,而且可以说不在依赖框架,也就是说以前Ionic和Angular是捆绑在一起的,从4版本开始,也可以使用React和Vue来做开发,更加灵活。并且使用标准化的web component后,以后也不会出现类似1到2、2/3到4这种痛苦的迁移过程了,应该会很平滑的升级,版本迭代的速度应该会更快。

Ionic 3 升级 Ionic 4 迁移踩坑系列(一)

@玛酷猫8 年前

03/23
15:12
Ruby

Rails5踩坑系列——Vagrant和NFS共享文件夹

新年新项目,被老项目折腾大半年后,部门一直认为新项目要脱离老的Rails3.2版本,拥抱新版本。先准备前期环境,对应的安装了最新的Ruby2.5和Rails5.1.5,开始项目后台框架搭建工作。同事用vm搭建的虚拟机环境,没啥问题,我是用的Vagrant搭建的虚拟机环境,由于Vagrant自身共享模式很慢,一直配置着vagrant-winnfsd插件使用NFS来做文件共享,速度是快很多,就是经常性会遇到I/O错误,关掉日志防止频繁写入共享盘就好了。新项目跑起来就开始报错,报错信息类似如下

Errno::EEXIST at / File exists @ dir_s_mkdir - tmp/cache/assets/sprockets/v3.0/jG

网上搜了一下,发现一篇博文说到这个,传送门,大体意思就是NFS是大小写不明感,rails在运行中会将assets生成静态文件缓存,存在tmp/cache/assets/sprockets/v3.0/ 目录中,文件按照前两位字母建立文件夹归档,这时候就会遇到类似jg、JG、jG、Jg属于4个不同文件夹,但是NFS大小写不明感,就会认为是一个,在创建的时候就会返回文件夹已存在的问题,文中给出的方案是修改配置文件,将这个文件移出共享文件夹。由于不想将虚拟机原始文件系统里面放置额外的文件,这个方案被我否定了。查了下原来项目里面老版本文件缓存情况,类似的结构和生成方式,不过生成的文件缓存文件名都是大写,文件夹也都是大写,就不存在大小写的问题。本想找办法对应修改下,翻了下Asset Pipeline相关文档和sprockets的相关配置,都没有找到,遂放弃这个办法。在查看文档中,有关于静态资源文件缓存的存储方式的说明,默认似乎是文件方式,文档给出的修改例子是内存方式,于是在development.rb中添加这个配置,重启项目,一切OK。下面的禁用方式也试了下,影响速度还是很明显,同样不考虑。

此外上述文中还提到了其他几种由于NFS大小写不明感而引起的问题以及处理办法,目前暂时还没遇到。下次遇到了也心里有数了。

Rails5踩坑系列——Vagrant和NFS共享文件夹

@玛酷猫8 年前

11/3
10:46
Ionic(Angular)

Ionic3应用中添加Faye功能

公司rails项目中通过Faye来实现一个简单的好友聊天互动的功能,移动端需要开发简易的教师上课点名的小功能,想想正好可以利用Faye服务来实现,具体逻辑很简单,在课程页面,教师点击点名模块,设置密钥后进入点名页面,通过Faye发布该课程点名信息,学生接收到点名信息后在页面上显示签到按钮,学生点击签到按钮输入密钥,通过Faye服务传递到教师点名页面上,时时反馈签到情况,最后教师通过关闭按钮结束签到并通过Faye告知所有学生,学生页面隐藏签到按钮。

逻辑理顺了,页面搭建完毕,加入Faye犯难了,官方文档只是简单写了下浏览器端如何使用,引入Faye服务端js,然后可以使用subscribe和publish来发布和接受了。在Ionic3项目里面就傻眼了,第一步引入js就不知道咋搞了,网上翻资料,绝大部分都是使用ionic 1.x的资料,度娘里面居然还掺杂一大堆王菲的搜索页面。。。谷歌研究了半天,参考了一篇关于ionic3部署socket.io的文章,终于搞定。

首先还是安装Faye组件

npm install faye --save

新建一个服务provider,初始化同时把相关的推送接收用法写进去

import { Injectable } from '@angular/core';
import * as Faye from 'faye'

@Injectable()

export class FayeService {
  clientUrl: string;
  data: any;
  client: any;

  constructor() {
    this.clientUrl = 'https://your website/faye';
    this.data = null;
    this.client = new Faye.Client(this.clientUrl)
  }

  subscript(callback:any, channelName:string){
    this.client.subscribe('/' + channelName, function (data) {
      callback(data);
      // console.log('receiced data:'+data);
    })
  }

  publish(channelName:string, data:any){
    let publication = this.client.publish('/' + channelName, data);
    publication.then(function() {
    }, function(error) {
      console.log('There was a problem: ' + error.message);
    });
  }

}

最后在app.module.ts中引入这个provider并声明下就可以在项目中使用了。

此外还有一点,由于项目的browser版和接口都启用的ssl,直接使用http://your website:8080/faye 会报错,提示在ssl下访问非ssl存在安全问题balabala之类的,这个需要在nginx中设置端口转发。

在nginx的接口配置文件中添加faye的upstream

upstream faye-socket{
    server 127.0.0.1:8080;
}

接着在配置443的server下面添加转发规则

location /faye {
	proxy_pass http://faye-socket;

	proxy_http_version 1.1;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header Host $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_cache_bypass $http_upgrade; 
}

保存后重新加载nginx配置即可。

nginx -s reload

Ionic3应用中添加Faye功能