0%

先引用一句名言:人用制度管,事用流程管

我理解,团队管理分三个维度:

  1. 对上管理
  2. 协作管理
  3. 对下管理

管什么?最主要管的是预期

  1. 老板的预期
  2. 协作方的预期
  3. 组员的预期

以及 我对这三个维度的预期。

先贴个总结
团队管理的几点沉淀
  1. 建立机制,反馈,奖惩,底线(态度),优先级
  2. 团队建设,人才梯度,技术结构,backup
  3. 团队文化,技术氛围、基调
  4. 业务导向,业务结果,规划
  5. 预期管理:对上管理(老板的预期),平行管理(对组员的预期,及组员的预期)
我的预期
  1. 如何教 别人 管理;团队的流程化,职业化?工作流?
  2. 有安全感,归属感,危机感,目标感,非安逸感

关于团队成长

团队的成长离不开组员的成长。一般会基于三个方向来培养组员,帮助成长

  1. backup能力:管理 + 业务
  2. 技术能力:技术栈深度/广度 + 架构设计
  3. 影响力:技术驱动 + 上层思维

从终局思维粗发,如何解读预期管理?

  • 接上面的观点:预期
  • 老板的预期哪里来👉大老板的预期
  • 大老板的预期是什么?当然是公司的营收,业务发展,好早日换车🚗换房🏡换…

所以,包括KPI、OKR什么的,最终目的是帮助老板完成大老板的预期

于是,各业务部门的战术规划,始终都要指向公司的战略目标!

  • 举个例子🌰
  1. 大老板:我们要完成GMV增长50%,利润增长30%
  2. 分析GMV成分:
  • 用户增长
  • 复购、客单
  • 成本控制
  • 新业务拓展
  1. 技术角度要做的事情
  • 技术创新、驱动–>业务效率
  • 组织架构、资源协同
  • 开发效能、稳定性、运维成本
  • 用户体验

那么分到各技术组的目标,就很明确了。

以业务为核心

不管是项目、管理、成长,核心都要基于业务出发,去考虑、规划、组织及架构。

必须要基于业务做的事情,业务导向

  • 组织架构
  • 团队/组员成长
  • 系统设计/架构
  • 基础建设

从业务粗发,如何来做团队管理?

RT。

为什么要总结? 理清思路,整体沉淀。给未来的自己一面镜子,持续地学习、沉淀,构成一个正向成长的飞轮模型✈️。

  1. 在一个电商技术团队中,前端对自己的定位📌
  • 横向支撑
    • 效率
  • 业务导向
    • 沟通
  • 技术驱动
    • 创新

三边关系

  1. 前端团队如何持续成长
  • 搭建团队的成长模型

金字塔成长模型

RT。

大环境不景气,为了生活,必须好好学习了 📚📖

一天一道算法题

1.【链表中倒数第k个节点】两个指针, a=0, b=k,一起向前移动,当k取值=null时,a=n-k。

  • 【 二叉搜索树中第K小的元素】中序遍历,k–
  • 【数组中的第K个最大元素】快速排序,不需要排序,只需要比较。

2.【全排列】递归(DFS), 依次取数组元素,除去当前元素再分别递归取数组元素(两for循环 + 递归)

3.【反转链表】一次循环{prev=null,cur=0, next=temp},当next = null时,结束while循环

4.【二叉树的层序遍历】广度优先BFS:while 同级遍历(队列shift) & 收集下一层节点(push)

5.【螺旋矩阵】巧技:削苹果。削掉最外面一层(shift数组及其余数组pop),翻转整个数组180度([].reverse),再削。

6.【复原IP地址】分割字符串, 递归(dfs), 检查每一段是否合法0~255

7.【岛屿数量】每遇到陆地格子=1, 则DFS搜索,标记已搜索过的格子(标记为2)。

8.【N叉树的层序遍历】BFS广度优先遍历root–>nextRoot[]–>nextRoot[]

9.【翻转二叉树】前、后序DFS深度遍历 or BFS广度优先遍历,不能用中序(会翻转两次)

10.【最长回文子串】https://writings.sh/post/algorithm-longest-palindromic-substring

11.【最长不含重复字符的子字符串】动态规划+ hashMap

12.【二叉树的最近公共祖先】思路1:DFS(二叉遍历)算出路径,然后对比两个路径的分叉点;

  • 思路2:两个值都在左边,则最近root在左边;一左一右,则当前root就是最近公共祖先。

13.【旋转图像】两个for,置换 matrix[j][n - 1- i] = matrix[i][j]

14.【无重复字符的最长子串】滑块->map标识字符位置,max标识当前最大位置

15.【合并两个有序数组】双指针,依次比较放入到一个新数组

16.【求根到叶子节点数字之和】dfs算法,标记已访问过的子节点(左or右)

17.【路径总和】dfs算法,标记已访问过的子节点(左or右)

18.【最大子序和】 单循环下,curSum < 0则舍弃&重新累加,curSum>maxSum && maxSum = curSum

19.【两数之和】建一个map,放入index和value,顺便比对下已放入的是否可以配对

  • 【三数之和】2.双指针法:排序数组 & 选定[a,b,c] = [i,i+1,len-1],target=-num[i]

20.【数组中的第K个最大元素】快排法(选择一个基准p,小于p移到左边,大于p移到右边),从i=0指针移动,如果当前指针 i=k,则return

21.【长度最小的子数组】 滑块->map标识字符位置

22.【字符串相加】转数组&反序reverse,满10进1

23.【二叉树的最大深度】前序遍历
24.【LRU算法】new Map(),map是一个散列队列,set总是到队列最后一个


一些资料

  • 字节算法面试题:github.com/afatcoder/LeetcodeTop/blob/master/bytedance/frontend.md
  • leetcode Top: github.com/afatcoder/LeetcodeTop
  • 看完这篇,你会理解图和树的遍历: https://zhuanlan.zhihu.com/p/98406357
  • 二叉树遍历: github.com/liusaint/ls-blog/issues/25

待续

2023-10-11

  • 记录一些必须要关注的选股指标

    • 量能,交易量,换手率
    • 市场主线,热度,参与度
    • MACD线
    • 近七日成交量趋势
    • 均线走势
    • 【重要】资金流向:结合均线、MACD线及量能、交易量,评估对当前大资金vs散户的占比,判断未来股价走势
      • 大单、中单资金,也有可能是割肉🥩单
      • 小单大部分都是散户单,中单也可能是散户单
    • 筹码分布
  • 重点强调纪律 + 心态


炒股的经验教训沉淀,主要是为了警醒自己Σ(⊙▽⊙”a

  • 设定预期及固定时间点

    • 单支股票的预期上限价格,及计划卖出时间点
    • 单支股票的预期下限价格,及计划卖出时间点
    • 保持个股的资产总额,及持仓占比
  • 重点!!!每只股票,都需要设置自己的预期上限和下限

!切记!

  • 机会每天都有,不必博反弹,不必抄底。
  • 预期 不是 欲望,务必井然有序,执行力要强。

失败案例📚(单支亏损>10w)

  • 同花顺
  • 贝特瑞
  • 易华录(22年新增😔)

基金挑选标准⭐️

  • 基金经理从业6年以上、从业年化收益20%以上、在管规模300亿以下(兴全破例);产品3年夏普比率1.5以上。
    🐔基金推进

待续

为什么要读这本书?

从业十余载,其中从事技术管理工作已有4+年,佛系股龄5+年 👉👉 新韭菜变老韭菜。

期间不乏遇到一些问题,且知识面&认知无法解决。

诸如团队主动性如何调动?奖惩、激励等

又如大盘风向、趋势,及未来规划等

想得越多,盲区越大。

于是,需要慢慢沉淀下来,用时间来消化。

恰巧,看群里推了这本神作,买来看看。

第一章对组织事权的讲解,很多点消化掉,便能用来实践🤔

对事权的理解

  • 事权划分三原则:
    • 规模经济(公共服务的覆盖范围 效益)
    • 信息复杂性(下级的信息优势),
    • 激励相容(有效机制来激励下级完成上级的目标)

  • 关于 房住不炒 的理解
    • RT。 首先要清楚,房价为什么会这么高?它是地区经济发展某一阶段的必然产物.
      1. 土地在城市化快速推进的过程中起到的杠杆作用
      • 地方政府将土地作为资本注入融资平台(城投、产业引导基金等LP),撬动为城市建设服务的资金杠杆
      • “注入土地-土地抵押-城市建设-土地升值-土地出让-还债”的模式成为地方政府通过融资平台举债融资、基建投资的最基本运营模式。导致政府显性、隐形 债务巨大。
      1. 产业基建快速发展,大量人口涌入;但忽略民生建设,居民收入水平提升有限
      2. 不动产持续增值,吸引大量投资客入场;不动产货币化、以土地为信用锚的现象
    • 所以,为什么我国前些年GDP一直在高速增长。驱动GDP增长的主要因素(三家马车)
      • 消费->内销、居民可支配收入->旅游为GDP贡献巨大,占10%+
      • 外贸->出口、跨境->2021年上半年外贸为主要的GDP贡献来源,占30%+
      • 房地产->城市化快速推进的产物,完全(直接&间接)贡献约17%的GDP
        • 说明:欧美房地产的GDP贡献,包括租金和税收,二手房交易及贷款的贡献占比很小。
    • 从另一个角度看,我们的房地产产业结构属于粗放型,需要一系列改革,实现集约型增长。
      • 服务于民生,有利于内循环
      • 降杠杆,解耦地方债务;符合城市多元化、都市圈发展方向
    • 那么,如何改善产业结构👉房住不炒。我理解,这是未来我国五到十年的政策核心,使得GDP结构朝着可持续的集约型经济增长
      1. 改善居民可支配收入,民生服务
      2. 改善外贸的工厂模式,产能过剩问题
      3. 优化房地产产业结构
    • 那么,目前可预见的,如何改善房地产产业结构?我理解
      1. 房市从卖方市场全面转向买方市场
      2. 卖方有两个方向
      • 投向租赁市场
      • 套现离场
      • 交税,贡献GDP(目前,除了房屋买卖,持有不动产是不交税的,不贡献GDP)
    • 所以,房产税势在必行,且肯定是针对卖方。
    • 那么房地产以后就不会继续增值了么?要看具体区域
      • 二三线城市,配套不成熟,or 没有配套升级规划的
      • 一线都市圈核心城市,且是核心区域的房市,理论上是有升值空间的。
    • 但整体上,房价不会涨,至少涨不过居民收入,通货膨胀,弱化投资理财属性。
      • 也不会跌,至少不会大跌,出现恐慌性抛盘,因为房价与民生及地方经济的稳定息息相关
    • 关于地域间的发展不平衡
      • 一般,房价涨幅应该与当地人均GDP相匹配。比如加州的人口占米国约12%,相应的GDP也占了12%
      • 反观我们,内地人口大省如河南,人口超东部沿海省市,但GDP远低于东部,导致人均GDP偏低
      • 所以,规划发展都市圈及户籍改革,有助于改善地域间发展不平衡的现状,让低收入者进入高收入城市,发展第三产业;且第三产业的发展,也有利于招商引资&人才引进,发展优化土地配置,提高利用率,使得房价与人均GDP相匹配

待续

hexo操作

  • 安装hexo:
    • npm install -g hexo-cli
    • hexo init myBlog
    • 生成文件目录
      1
      2
      3
      4
      5
      6
      7
      8
        .
      ├── _config.yml # 网站的配置信息,您可以在此配置大部分的参数。
      ├── package.json
      ├── scaffolds # 模版文件夹
      ├── source # 资源文件夹,除 _posts 文件,其他以下划线_开头的文件或者文件夹不会被编译打包到public文件夹
      | ├── _drafts # 草稿文件
      | └── _posts # 文章Markdowm文件
      └── themes # 主题文件夹
    • 本地预览:hexo s

github操作

  • 创建仓库

  • 将该仓库设置为静态站点托管。

    • 点击仓库菜单Settings->Pages
    • 注意:Github 仅能使用一个同名仓库的代码托管一个静态站点
      logo
  • 在页面https://github.com/settings/tokens创建 Personal access tokens
    token

  • 添加仓库变量

    • 设置HEXO_DEPLOY_PRI, value 是上步生成的 BLOG_DEPLOY_TOKEN 的值
      pri
  • 添加 workflow, 文件路径为root/.github/workflows/deploy.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72

    name: CI

    on:
    push:
    branches:
    - master

    env:
    GIT_USER: ghyghoo8
    GIT_EMAIL: ghyghoo8@qq.com
    THEME_REPO: theme-next/hexo-theme-next
    THEME_BRANCH: master
    DEPLOY_REPO: ghyghoo8/ghyghoo8.github.com
    DEPLOY_BRANCH: master

    jobs:
    build:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
    runs-on: ubuntu-latest
    strategy:
    matrix:
    os: [ubuntu-latest]
    node_version: [14.x]

    steps:
    - name: Checkout
    uses: actions/checkout@v2

    - name: Checkout theme repo
    uses: actions/checkout@v2
    with:
    repository: ${{ env.THEME_REPO }}
    ref: ${{ env.THEME_BRANCH }}
    path: themes/next

    - name: Checkout deploy repo
    uses: actions/checkout@v2
    with:
    repository: ${{ env.DEPLOY_REPO }}
    ref: ${{ env.DEPLOY_BRANCH }}
    path: .deploy_git

    - name: Use Node.js ${{ matrix.node_version }}
    uses: actions/setup-node@v1
    with:
    node-version: ${{ matrix.node_version }}

    - name: Configuration environment
    env:
    HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
    run: |
    sudo timedatectl set-timezone "Asia/Shanghai"
    mkdir -p ~/.ssh/
    echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    ssh-keyscan github.com >> ~/.ssh/known_hosts
    git config --global user.name $GIT_USER
    git config --global user.email $GIT_EMAIL
    cp _config.theme.yml themes/next/_config.yml

    - name: Install dependencies
    run: |
    npm install

    - name: Deploy hexo
    env:
    GITHUB_TOKEN: ${{secrets.HEXO_DEPLOY_PRI}}
    run: |
    rm -rf .deploy_git
    npm run deploy

  • _config.yml文件配置下新增配置,支持github自动部署

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # Deployment
    ## Docs: https://hexo.io/docs/one-command-deployment
    deploy:
    type: git
    repo:
    github:
    url: https://github.com/ghyghoo8/ghyghoo8.github.com.git
    branch: gh-pages
    token: $GITHUB_TOKEN

  • 提交到github后,就能触发仓库Actions
    ci

参考

  • https://segmentfault.com/a/1190000017986794
  • https://timemachine.icu/posts/1eb3f811/

Domain-Driven Design,DDD

我理解,DDD非常适合应用于偏业务的中大型复杂项目迭代中,尤其是电商之类的web项目。基于业务架构的系统设计,再完美匹配微服务架构,可以达到业务维度的高度统一。

我的学习沉淀

领域驱动设计

  1. 实例: 领域模型(抽象逻辑) :抽象/封装 数据+行为
  2. 方法:分治、抽象、知识(DDD提供了这样的知识手段,让我们知道如何抽象出限界上下文以及如何去分治)
  3. 限界上下文—>微服务边界划分,从业务维度做分治。上下文是领域的解系统,映射到团队,高效协作
    • 核心上下文
    • 支撑上下文
    • 通用上下文
  4. 防腐层ACL,适配&提供访问机制。
  5. 耦合程度控制在数据耦合层(数据库)

核心诉求:将业务架构映射到系统架构,想呼应。

微服务,则追求业务层面的复用

系统结构与组织结构 对齐,保持一致。

战术设计:数据+行为

  1. 实体 Entity (标识区分(唯一)的对象),有状态
  2. 值对象 Value Object (值描述的对象,不唯一)
  3. 聚合根 Aggregate,Aggregate Root,根实体
  4. 领域服务:Service,领域抽象功能点的实现。serverless处理流程,无状态
  5. 领域事件:通常是用来与其他聚合解耦的,采用观察者模式,一个聚合订阅另外一个聚合的事件。
  6. 库Repository:持久聚合,redis
  7. 工厂:创建聚合根 or 实体 or 值对象
  8. 模块:命名空间,概念隔离

在前端的业务域-如何实践DDD?

挖个坑

关于接入Sentry后,不影响chunk的hash值的解决方案

  1. Sentry.init({ release: window.__SENTRY_RELEASE__ }) 将release变量注入到入口html(entry)的window对象上
  • HtmlWebpackPlugin的配置中加入代码:
    • sentry_release_by_commit_id:’
  • 入口html(index.html)页头加入代码:
    • <%= sentry_release_by_commit_id %>
  1. package.json中加入命令:
  • “sentry-cli”:”VERSION=$(sentry-cli releases propose-version) && sentry-cli releases files $VERSION upload-sourcemaps –url-prefix ‘<your static cdn url prefix, like //xxx.com/dist/js >’”
  • propose-version命令的作用,使用sentry-cli建议的version值(默认取commit-id)

Rust是什么?

Rust 是一种兼顾内存安全高并发稳定运行的编程语言。它有着惊人的运行速度(有些领域甚至超过 C/C++),能够防止运行错误,并保证线程安全。RUST 语言使每个人都能够构建可靠、高效的软件。

不足之处

  1. 学习门槛
  2. 编译成本(RAII, Resource Acquisition Is Initialization 资源获取即初始化)

Node的一些优缺点

  • 优点
    • 异步/高并发,promise、迭代器
    • 函数式,react
    • 包管理,npm
    • 事件模型,epoll
    • 门槛低/易上手,javascript
  • 缺点
    • 匿名函数、容错性
    • 单进程(易阻塞)
    • 性能(CPU密集)

node的一些应用场景

  • RUSTful / Graphql API
  • SSR
  • Electron
  • websocket

如何去拓展Node的能力&应用场景?

Node Addons 🍾

适合写Node(V8 + libuv) Addons的语言👇

  • C++(node-gyp)
  • Rust
  • golang

🌰

用node实现一个文件监听功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const Koa = require('koa');
const app = new Koa();
const chokidar = require('chokidar');
const PORT = 3000
const watch_history = ['👇record static/* files change history👇']
const ICON_EMUN = {
'add': '📃',
'addDir': '📂',
'unlink': '❌',
'change':'🌋'
}
app.use(async ctx => {
ctx.body = `<table width=900 ><tbody>${
watch_history.map(rec=>`<tr>${rec}</tr>`).join('')
}</tbody></table>`
});
chokidar.watch('./static').on('all', (event, path) => {
if (['add', 'change'].includes(event)) {
watch_history.push(`<td>${ICON_EMUN[event]||'🧐'}</td><td>${event}</td><td>${path}</td><td>time:${new Date().toLocaleString()}</td>`);
}
console.log(event, path);
});
console.log(`server run===> http://localhost:${PORT}`)
app.listen(PORT);

用Rust实现一个文件监听功能

file.rs 文件内容👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#![allow(non_snake_case)]
use super::WatcherTrait;
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;

/// 文件同步器
pub struct FileWatcher {
/// 文件路径
path: PathBuf,
/// 文件内容
pub content: Arc<Mutex<String>>,
/// 内容版本,初始化为1,文件一次修改累计1
pub version: Arc<Mutex<usize>>,
}

impl FileWatcher {
/// 创建新的同步器
pub fn New(path: &Path) -> Self {
if path.exists() {
let file_content = fs::read_to_string(path).unwrap();
let content = Arc::new(Mutex::new(file_content));
let version = Arc::new(Mutex::new(1));
Self {
path: PathBuf::from(path),
content,
version,
}
} else {
error!("watch an nonexist file!");
panic!("watch an nonexist file!");
}
}
}

impl WatcherTrait for FileWatcher {
/// 新线程启动观察器
fn watch(&mut self) {
let path = fs::canonicalize(&self.path).unwrap();
let content_guard = self.content.clone();
let version_guard = self.version.clone();
thread::spawn(move || {
let (tx1, rx1) = mpsc::channel();
let mut watcher: RecommendedWatcher =
Watcher::new(tx1, Duration::from_secs(1)).unwrap();
watcher
.watch(path.parent().unwrap(), RecursiveMode::NonRecursive)
.unwrap();

// loop监听,匹配 file event
loop {
match rx1.recv() {
// 文件写入,创建
Ok(event) => {
info!("watch event: {:?}", event);
match event {
DebouncedEvent::Remove(p)
| DebouncedEvent::Write(p)
| DebouncedEvent::Create(p) => {
if path == p {
let mut content = content_guard.lock().unwrap();
let mut version = version_guard.lock().unwrap();
(*version) += 1;
match fs::read_to_string(&p) {
Ok(c) => {
*content = c;
info!("wrote file: {:?} #{}", p, *version);
}
Err(_) => warn!("file not exist: {:?}", &p),
}
}
}
_ => {}
}
}
Err(e) => {
error!("watch error: {:?}", e);
}
}
}
});
}

/// 文件内容
fn content(&self) -> String {
let content_guard = self.content.clone();
let content = content_guard.lock().unwrap();
(*content).clone()
}

/// 文件更新次数
fn version(&self) -> usize {
let version_guard = self.version.clone();
let version = version_guard.lock().unwrap();
*version
}
}


使用Rust-FFI 暴露外部接口给Node调用

⚒️ 脚手架&工具集,帮助你快速地将 node与rust 绑定(Rust bindings)

  • neon
  • node-rs
编译出native文件,即可被node引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

const Koa = require('koa');
const app = new Koa();
const chokidar = require('chokidar');
const fs = require('fs');
const nativeTools = require('./lib/fw/native');
const PORT = 3001
const watch_history = [`native-->hello方法输出:${nativeTools.hello()}`,'👇record static/* files change history👇']
const ICON_EMUN = {
'add': '📃',
'addDir': '📂',
'unlink': '❌',
'change':'🌋'
}

const BASE_PATH = './static'

const filesCache = {}; // 缓存file watcher Map
app.use(async (ctx, next) => {
const files = fs.readdirSync(BASE_PATH)
files.map(f => {
const _path = `${BASE_PATH}/${f}`;
let type = false;
let d = filesCache[_path];
if (d) { // 已缓存,则直接拿 watcher
if (d.version < d.watcher.version()) {
d.version = d.watcher.version()
type = 'change';
}
} else {
const wathcer = new nativeTools.NodeFileWatcher(_path);
d = {
path: _path,
watcher: wathcer,
version: wathcer.version()
}
filesCache[_path] = d; // 缓存 watcher
type = 'add';
}
// 有变更,则增加渲染数据===>
type && watch_history.push(`<td>${ICON_EMUN[type]}</td><td>${type}</td><td>${_path}</td><td>${d.version}</td>`)
})
await next();
})


app.use(async ctx => {
ctx.body = `<table width=900 ><tbody>${
watch_history.map(rec=>`<tr>${rec}</tr>`).join('')
}</tbody></table>`
});


console.log(`server run===> http://localhost:${PORT}`)
app.listen(PORT);

neon简单教程

  • npm install neon-cli —global
  • neon new <projectname>
  • root—-> neon build
  • 生成 native/index.node——> const nativeTools = require(‘./lib/fw/native’);

创建的项目<projectname>目录结构:

  • lib
    • index.js
  • native
    • build.rs
    • Cargo.toml
    • src
      • lib.rs
    • package.json

native/src/lib.rs👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
extern crate neon;

#[macro_use]//可以使用 info! 的log宏,打印log===>
extern crate log;

mod sync;
use sync::JsFileWatcher;

use neon::prelude::*;

fn hello(mut cx: FunctionContext) -> JsResult<JsString> {
Ok(cx.string("hello neon"))
}

// 注册导出 & binding
register_module!(mut cx, {
// 导出一个方法
cx.export_function("hello", hello);
// 导出一个class
cx.export_class::<JsFileWatcher>("NodeFileWatcher")
});

Rust在大前端领域,还能做什么?

  • swc(高性能>babel)
  • 监控(v8、system…)
  • 跨端(by FFI)
    • wasm
    • so
    • dll

学习资料

  • 演练场:https://play.rust-lang.org/
  • 社区wiki:https://learnku.com/rust/wikis
  • 官方blog:https://blog.rust-lang.org/
  • Cargo文档:https://doc.rust-lang.org/cargo/
  • Demo仓库😁:https://github.com/ghyghoo8/rust-learn
  • node转rust:https://candle.dev/blog/javascript-to-rust/javascript-to-rust-day-1-rustup/

test

建个blog

logo