Commit 54cd56f1 authored by Master Q's avatar Master Q

init

parent 04e15bbf
### 注意事项
## 利用babel 简化 FYGE 的开发方式
> useAni 默认会去 清除 子元素上的所有tween,所以,里面的tween 不要加 延时,否则会清除不掉
> 本质上 利用jsx 的用法, 让我们 编写页面逻辑的时候,能够能搞的 ui层和 数据层分开,在一定程度上可以 简化开发思路
> 装饰器 ts 推导有点问题 UseAni
jsx => new => render => back
> 场景 这里怎么处理好呢, 怎么判定 是预加载,或者,预加载的时候,需要下层 场景呢
> 场景需要切换的时候 带有动画呢,做锤子🔨
生命周期 就很简单 render => ref => didRendered
new => RenderComponent => render => back
ref 会在 改节点 didRendered 完成之后才会执行,用nextTick 微任务 实现
ref <= didRendered
new => FYGE.Container
### 优势
FYGE.Shape 画出来的 width 和height 外面又一层 20 ??
> 本质上是为了 让开发模式上 的改变,在一定程度我们可以 用类似 react 的方式去做 。我们可以写一些 我们更好理解的 东西, 比如我们 写一个 Img 组件,支持src 里面就我们 资源组的 name 或者 直接网络图地址的形式
babel acorn => Javascript 编译器
```javascript
export class Sprite extends Dream.RenderContainer<{
src: string | FYGE.Texture
}> {
render() {
const {
src
} = this.props
高级语言 =》 低级语言
const sp = new FYGE.Sprite()
高级语言 更加符合 人类想的逻辑, 描述逻辑的语言特性,比如 分支,函数 循环,面向对象
if (typeof src === 'string') {
RES.getResAsync(src, (d: FYGE.Texture) => {
sp.texture = d
})
} else {
sp.texture = src
}
return sp
}
}
```
低级语言 更加 适合机器, 会操作寄存器,内存,需要开发熟悉计算机的工作原理, 比如汇编语言
基本除了 没有diff 这一层,在一定程度上都是 可以用 react 的方式去做。 Just for try。
所以,分为了三步 parse =》 ast 抽象语法数, 你可以已经为是一个特殊的 数据结构,里面 摒弃了一些 无用的 显示字符, 比如 {},; 这样机器就知道了我们源码是什么意思
### 注意事项
词法分析和语法分析
> 本质上先阶段只是 一个简单的 用例, 其主要实现就是 Dream 下的 development.
transform 去遍历,修改 ast
> useAni 默认会去 清除 子元素上的所有tween,所以,里面的tween 不要加 延时,否则会清除不掉
generate 修改了好了就用 去 生成我们源码
> 装饰器 ts 推导有点问题 UseAni
[babel](https://astexplorer.net/#/gist/09113e146fa04044e99f8a98434a01af/0ff37c4d88c90f10a71897a8ebf021c55e1f3334)
> 场景 这里怎么处理好呢, 怎么判定 是预加载,或者,预加载的时候,需要下层 场景呢
> 场景需要切换的时候 带有动画呢,做锤子🔨
@babel/core 下面都有
new => RenderComponent => render => back
parser 阶段
@babel/parser
transfrom阶段
@babel/traverse
generate
@babel/generator
ref <= didRendered
插件、 preset 预设 =》 插件集合
new => FYGE.Container
默认只能解析 js 想 flow,ts jsx 需要特定的 语法插件 才能解析
\ No newline at end of file
FYGE.Shape 画出来的 width 和height 外面又一层 20 ??
\ No newline at end of file
......@@ -6,14 +6,13 @@
"scripts": {
"dev": "node ./scripts/devServer.js",
"flushRes": "node scripts/flushRes",
"handleRes": "node scripts/delRel && node scripts/copyRes",
"handleRes": "node scripts/delRel && node scripts/copyRes && node scripts/imageMin.js",
"upload": "node scripts/upload",
"prod": "npm run handleRes && npm run upload && npm run buildTS",
"buildWeb": "npm run handleRes && node scripts/upload 1",
"buildTS": "webpack --config webpack.prod.js && node scripts/mergeJs",
"babelbuild": "babel src --out-dir dist --extensions .ts,.tsx",
"build": "webpack --config webpack.prod.js",
"check-type": "tsc --watch"
},
"author": "",
......@@ -28,19 +27,18 @@
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.1",
"@babel/preset-typescript": "^7.18.6",
"ali-oss": "^4.11.4",
"babel-loader": "^8.2.5",
"chalk": "^2.3.0",
"co": "^4.6.0",
"del": "2.2.1",
"form-data": "^4.0.0",
"progress": "^2.0.0",
"ts-loader": "^9.4.1",
"typescript": "^4.8.3",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0",
"ali-oss": "^4.11.4",
"chalk": "^2.3.0",
"co": "^4.6.0",
"progress": "^2.0.0"
"webpack-merge": "^5.8.0"
}
}
/**
* imageMin.js
* Created by 还有醋v on 2022/9/29 下午7:19.
* Copyright © 2022 haiyoucuv. All rights reserved.
*/
// const imagemin = require("imagemin");
// const imageminJpegtran = require('imagemin-jpegtran');imagemin-mozjpeg
// const imageminJpegtran = require("imagemin-mozjpeg");
// const imageminPngquant = require("imagemin-pngquant");
const fs = require("fs");
const path = require("path");
const chalk = require("chalk");
const tinyImage = require("./tinyImage");
// 要处理的图片文件夹路径
const altasPath = "./released/resource/";
function getImgFiles(dir) {
let fileArr = [];
if (fs.existsSync(dir)) {
const files = fs.readdirSync(dir);
files.forEach((file) => {
const fpath = dir + '/' + file;
const stat = fs.lstatSync(fpath);
if (stat.isFile() && /\.jpg|\.png|\.jpeg$/.test(file)) {
fileArr.push(fpath);
} else if (stat.isDirectory()) {
fileArr.push(...getImgFiles(fpath));
}
});
}
return fileArr;
}
const folders = getFolders(altasPath);
folders.map(async (folder) => {
// const files = await imagemin([altasPath + folder + '/*.{png,jpg}'], {
// destination: altasPath + folder,
// plugins: [
// imageminJpegtran(),
// imageminPngquant({
// quality: [0.6, 0.8]
// })
// ]
// });
// if (files && files.length) {
// files.forEach((v) => {
// console.log("压缩图片成功:", v.sourcePath.substring(v.sourcePath.lastIndexOf("/") + 1, v.sourcePath.length))
// })
// }
// TODO 2022/07/12 修改到线上到图片压缩服务
// TODO 2022/09/21 压缩图片并行压缩,图多能节省大量时间
const files = getImgFiles(altasPath + folder);
const ps = [];
for (const file of files) {
ps.push(
tinyImage(file)
.then((tinyBuffer) => {
fs.writeFileSync(file, tinyBuffer);
console.log(chalk.gray("压缩图片成功:" + file));
})
.catch((e) => {
console.log(chalk.red("压缩图片失败:" + file));
})
);
}
await Promise.all(ps);
});
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function (file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
/**
* tinyImage.js
* Created by 还有醋v on 2022/9/29 下午7:19.
* Copyright © 2022 haiyoucuv. All rights reserved.
*/
/**
* tinyImage.js
* Created by 还有醋v on 2022/9/19 下午6:10.
* Copyright © 2022 haiyoucuv. All rights reserved.
*/
const FormData = require('form-data');
const fs = require("fs");
const tinifyUrl = 'https://tinify.duiba.com.cn/tinify';
function isPng(buffer) {
if (!buffer || buffer.length < 8) {
return false;
}
return buffer[0] === 0x89
&& buffer[1] === 0x50
&& buffer[2] === 0x4E
&& buffer[3] === 0x47
&& buffer[4] === 0x0D
&& buffer[5] === 0x0A
&& buffer[6] === 0x1A
&& buffer[7] === 0x0A;
}
function isJpg(buffer) {
if (!buffer || buffer.length < 3) {
return false;
}
return buffer[0] === 255
&& buffer[1] === 216
&& buffer[2] === 255;
}
/**
* 压缩图片
* @param {Buffer|string} bufferOrFile
* @return Promise<Buffer>
*/
async function tinyImage(bufferOrFile) {
let buffer = bufferOrFile;
if (typeof bufferOrFile === 'string') {
buffer = fs.readFileSync(bufferOrFile);
}
return new Promise((resolve, reject) => {
if (buffer && buffer.length > 0) {
let extname = isPng(buffer) ? 'png' : 'jpeg';
let form = new FormData();
form.append('file', buffer, {
filename: 'image.' + extname,
contentType: 'image/' + extname,
});
form.submit(tinifyUrl, function (err, res) {
if (err) {
reject(err);
}
else {
res.resume();
let resBuffer = Buffer.alloc(0);
res.on('data', (d) => {
resBuffer = Buffer.concat([resBuffer, d], resBuffer.length + d.length);
});
res.on('end', () => {
if (resBuffer.length > 256 || isPng(resBuffer) || isJpg(resBuffer)) {
resolve(resBuffer);
}
else {
let str = resBuffer.toString();
let json;
try {
json = JSON.parse(str);
}
catch (e) {
console.log(e);
}
reject(json.msg);
}
});
res.on('abort', () => {
reject('abort');
});
}
});
}
else {
reject('empty buffer');
}
});
}
module.exports = tinyImage;
......@@ -70,9 +70,6 @@ export const nextTick = (function () {
textNode.data = counter + ''
}
} else {
// webpack attempts to inject a shim for setImmediate
// if it is used as a global, so we have to work around that to
// avoid bundling unnecessary code.
// webpack默认会在代码中插入setImmediate的垫片
// 没有MutationObserver就优先用setImmediate,不行再用setTimeout
const context = inBrowser
......
......@@ -5,6 +5,5 @@ export const ResJson = {
"name": "skybox"
}
],
// eslint-disable-next-line
"path": "https://yun.duiba.com.cn/db_games/activity/template/1664529402/resource/"
"path": "./resource/"
}
\ No newline at end of file
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const template = require('@babel/template').default
const generate = require('@babel/generator').default
const ast = parser.parse(`
const a = 3
const b = <a></a>
console.log(12323)
f()
class Clazz {
render() {
return (
<div>
{console.log(11)}
</div>
)
}
}
`, {
sourceType: 'unambiguous',
plugins: ['jsx']
})
const t = ['log', 'info'].map(s => `console.${s}`)
traverse(ast, {
CallExpression(path, state) {
const node = path.node
if (node.isSkip) return
const str = path.get('callee').toString()
if (t.includes(str)) {
const newNode = template.expression(`console.log('========${str}======')`)()
path.insertBefore(newNode)
newNode.isSkip = true
node.isSkip = true
}
}
})
const {
code
} = generate(ast)
console.log(code)
export namespace Dream {
}
// export namespace Dream {
// }
declare global {
namespace JSX {
......
......@@ -1517,6 +1517,11 @@ ast-types@^0.13.2:
dependencies:
tslib "^2.0.1"
asynckit@^0.4.0:
version "0.4.0"
resolved "http://npm.dui88.com:80/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
babel-loader@^8.2.5:
version "8.2.5"
resolved "http://npm.dui88.com:80/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e"
......@@ -1771,6 +1776,13 @@ colorette@^2.0.10, colorette@^2.0.14:
resolved "http://npm.dui88.com:80/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
combined-stream@^1.0.8:
version "1.0.8"
resolved "http://npm.dui88.com:80/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=
dependencies:
delayed-stream "~1.0.0"
commander@^2.20.0:
version "2.20.3"
resolved "http://npm.dui88.com:80/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
......@@ -1955,6 +1967,11 @@ del@2.2.1:
pinkie-promise "^2.0.0"
rimraf "^2.2.8"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "http://npm.dui88.com:80/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
depd@2.0.0:
version "2.0.0"
resolved "http://npm.dui88.com:80/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
......@@ -2254,6 +2271,15 @@ follow-redirects@^1.0.0:
resolved "http://npm.dui88.com:80/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
form-data@^4.0.0:
version "4.0.0"
resolved "http://npm.dui88.com:80/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha1-k5Gdrq82HuUpWEubMWZNwSyfpFI=
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
formstream@^1.1.0:
version "1.1.1"
resolved "http://npm.dui88.com:80/formstream/-/formstream-1.1.1.tgz#17259d2440c35ca9736db9f45fb3ba3f8669c750"
......@@ -2871,7 +2897,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
resolved "http://npm.dui88.com:80/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "http://npm.dui88.com:80/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment