V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
fewspider
V2EX  ›  程序员

宣传一下自己封装的 NPM 库-处理 JSON 数据

  •  
  •   fewspider · 2021-09-29 12:22:59 +08:00 · 4074 次点击
    这是一个创建于 1181 天前的主题,其中的信息可能已经有所发展或是发生改变。

    开发的原因

    前端处理 JSON 数据是最基本的一个需求,无论是啥框架,能够方便简洁地拿到数据,可以大幅度地方便开发

    主要功能

    处理一些 JSON 数据,拿不到值,取默认值,具体可以看 README.md

    NPM 地址

    https://www.npmjs.com/package/js-safe-json

    第 1 条附言  ·  2021-09-30 05:29:59 +08:00

    看了一些留言,分几个点回复一下

    1、这个库不成熟,会优先考虑 lodash 之类成熟的库

    想说 test 脚本是摆设吗,test 里面也写了很多测试,能通过测试,达到预期结果了,这个还算不成熟吗

    2、.d.ts

    个人不喜欢ts,npm的发包也没规定一定要ts吧

    3、lodash 可以 _.get(object, 'a.b.c', 'default');

    如果我要拿一个string类型的值,刚好假设说 a.b.c 是个数字, 那么我拿到的东西,我的预期是拿到字符串的值,这部分它是没办法实现的,而我的库能办到,同理数组类型那些也是一样

    let obj = { 
      a: { 
        b: { 
          c: 233 
        } 
      } 
    }
    
    // 会是 233
    let lodashResult = _.get(obj, 'a.b.c', '');
    // 会是 ‘233’
    let myLibResult  = fetchString(obj, 'a', 'b', 'c');
    

    4、为啥不设计跟 lodash 一样的传参

    a.b.c 这样,这个是可以,但是我不喜欢这样做,容易写错,这个东西,并没有一个标准说怎样好,我的习惯是分开,会更加注意参数的值,避免没必要的错误

    5、这部分是后端处理的,前端没必要,或者说这部分的业务需求是什么

    接口并不能保证健全,这也是我弄这个库的初衷,程序需要健壮性,不能全部指望后端,尤其是现在 Vue 跟 React 基本也依赖于数据是渲染虚拟DOM,所以数据的健壮性还是有必要的

    另外的补充

    1、lodash 我也在用处理数据,正常来说,这边只是先拿到预期类型结果的数据,再用 lodash 进行数据处理, lodash 更像是操作数据进行加工,达到需要渲染页面的数据结构

    2、纯抛砖引玉,有些老哥建议就不错,有些就感觉随便写,啊这,蚌埠住了,吧啦吧啦,没啥意义吧,深拷贝的实现方式有多种,我也清楚,觉得多余,也没求你用我的东西呀,键盘侠是不需要什么成本的,我也很暴躁,我也没碍着你什么呀

    26 条回复    2021-10-15 10:41:43 +08:00
    xieqiqiang00
        1
    xieqiqiang00  
       2021-09-29 12:28:28 +08:00
    这种需求有点不理解
    tinkerer
        2
    tinkerer  
       2021-09-29 12:42:10 +08:00
    这也要发个库么...
    hyy1995
        3
    hyy1995  
       2021-09-29 12:45:23 +08:00 via iPhone
    我愣住……
    pansongya
        4
    pansongya  
       2021-09-29 12:51:15 +08:00 via Android
    有用 不过应该是后端做的事
    masterclock
        5
    masterclock  
       2021-09-29 12:55:51 +08:00
    coolcoffee
        6
    coolcoffee  
       2021-09-29 12:56:10 +08:00   ❤️ 5
    首先,我这边第一反应就是为什么不用 lodash 的_.get 。

    其次,我觉得取值之前都要已经知道是什么类型,而且要执行对应类型的取值方法:fetchString 、fetchBoolean 等,那我为什么不_.get("a.b.c") || false 或者 _.get("a.b.c") || "",大不了在使用比较过程中再用"!!"或者"+" 转换一下类型。

    最后就是,这年头没 typescript 就算了,但是不能没有 type.d.ts ;

    最最重要的一点就是,直接全量引入了一个 underscore,这个是很难接受的。 虽然您这边打包出来才几 kb,那是因为是用的 esm,没办法直接在 js 上使用。
    kekxv
        7
    kekxv  
       2021-09-29 12:57:25 +08:00 via iPhone
    为什么不用||?
    let number = json.number || 0;
    LancerComet
        8
    LancerComet  
       2021-09-29 13:00:23 +08:00   ❤️ 1
    @xieqiqiang00 JSON 正反序列化器最重要的意义是保证类型安全,然后在此基础上加一些工程特性,比如 JSON 字段与 Model 字段名称映射,规则校验等

    但对于切图仔来讲有点尴尬的是,JS 如果要做类型安全,那么 API 设计的就比较丑陋,一般需要声明一个 Schema,然后人工维护字段关系,这样就比较繁琐,而且代码不是那么随意抽插;如果要学习类似 JSON.NET 的声明式注解,虽然 API 会好看很多,感觉有点像 AOP,但项目一定要上 TypeScript 并且打开 emitDecoratorMetadata,因为要用到反射,但某些时候项目已经不能支持,或者类似 Vite 这样 ESBuild 的工具链,如果为了这一个特性就大动干戈就比较难受.

    我觉得切图仔对 JSON 正反序列化器也是有需求的,我自己仿造 JSON.NET 的 API 做了一个序列化器,然后在公司项目中大规模使用了,公开的版本在这里 https://github.com/vuevert/Vert-Serializer,不过是需要 TS + 装饰器 + emitDecoratorMetadata 环境的.

    这个我在项目里一般和数据访问层结合,然后 API 大概可能长这样:

    ```ts
    @Serializable()
    class User {
    @JsonProperty()
    name: string = ''

    @JsonProperty('user_age') // 数据源字段名称可以和 Model 不一样,比如接口里为 user_age.
    age: number = 0 // 如果接口返回的不是 number 则取 0 作为默认值.
    }

    function getUserData (id: string) {
    return HttpService.get({
    url: '/user',
    data: {
    id
    },
    type: User
    })
    }

    getUserData('1') // Promise<User>
    ```

    这样就可以直接把 JSON 变为 Model.

    另外我个人喜欢在项目中将各个功能集成在 Model 上以便查找,避免分散代码:

    ```ts
    @Serializable()
    class User {
    @JsonProperty()
    @IsString(1, 20, '请填写用户名,长度在 1- 20')
    name: string = ''

    @JsonProperty('user_age')
    @IsInt(0, 120, '请填写正确的年龄.')
    age: number = 0 // 如果接口返回的不是 number 则取 0 作为默认值.
    }
    ```

    然后直接在视图中使用:

    ```tsx
    const userValidator = getValidator(User)

    <Textfield rules={userValidator.name} />
    <Textfield rules={userValidator.age} />
    ```

    这样视图中就不需要再额外写验证器逻辑了.

    其实这些设计非常传统.
    LancerComet
        9
    LancerComet  
       2021-09-29 13:01:23 +08:00
    @LancerComet 格式炸了 😢
    mritd
        10
    mritd  
       2021-09-29 13:02:24 +08:00 via iPhone   ❤️ 8
    这是我硬盘最佩服 前端圈 的一点,每次 npm install 似乎都是一次海量小文件压测
    Kilerd
        11
    Kilerd  
       2021-09-29 13:13:37 +08:00
    啊这。。。。
    towry
        12
    towry  
       2021-09-29 13:25:45 +08:00
    https://github.com/towry-archived/term-cursor

    火钳刘明,宣传下我 N 年前下的一个 NPM 裤。。
    fewspider
        13
    fewspider  
    OP
       2021-09-29 13:38:36 +08:00
    @coolcoffee 把 underscore 干掉了
    lisongeee
        14
    lisongeee  
       2021-09-29 13:50:21 +08:00
    怎么连个 .d.ts 都没有?
    myCupOfTea
        15
    myCupOfTea  
       2021-09-29 14:17:08 +08:00
    lodash 的 get
    xingguang
        17
    xingguang  
       2021-09-29 17:58:11 +08:00   ❤️ 2
    ```js
    function clone(obj) {
    return JSON.parse(JSON.stringify(obj));
    }

    ```
    蚌埠住了
    muzuiget
        18
    muzuiget  
       2021-09-29 19:22:49 +08:00
    看上去就是取个默认值?

    如果是服务端接受客户端发过来的不可信 JSON,可以定义 ajv.js.org 这种工具直接校验后,再取值使用。

    况且现在 JS 有空值运算符了,连 lodash 这种省了,例如 a.b?.c?[1]?.d ?? 'default'。
    mxT52CRuqR6o5
        19
    mxT52CRuqR6o5  
       2021-09-29 19:25:06 +08:00
    有标准里的 optional chaining 优先考虑用标准里的特性,不用 optional chaining 也会优先考虑 lodash 这种成熟的库
    DOLLOR
        20
    DOLLOR  
       2021-09-29 23:19:00 +08:00
    @coolcoffee
    _.get(object, 'a.b.c', 'default');
    lxml
        21
    lxml  
       2021-09-29 23:51:15 +08:00
    卑微后端偷偷问一下,前端 我想用 typesctipt 描述一个结构,想要 找到的一个 Json 序列化的办法(json.parse 或者第三方库都行) 能让我在 定义的 interface {} 中 有个 Map,让 json 中 object 被反序列化成 Map 而不是默认的 js object.
    CodingNaux
        22
    CodingNaux  
       2021-09-30 10:05:02 +08:00
    估计这库应该用不到.......
    如果是#8 那种,还有点意思,不过一般前端项目也用不到吧
    CodingNaux
        23
    CodingNaux  
       2021-09-30 10:07:06 +08:00
    话说后端提供的接口没文档吗?字段还会随意变吗?
    CodingNaux
        24
    CodingNaux  
       2021-09-30 10:22:51 +08:00   ❤️ 1
    反感一个文件 100 多行的 npm,不算啥解决方案,纯脆一个 helper 方法,自己都能在项目里撸出来,想复用直接发布到公司私有 npm 源就行
    有些小库就很好,比如 cookie, qs (URLSearchParams 有些场景有问题)。大家需要的其实是这种类型的库
    leelz
        25
    leelz  
       2021-09-30 13:49:15 +08:00
    几个工具方法凑起来就是一个库,感觉是在教别人怎么发 npm 包 。
    DimitriYoon
        26
    DimitriYoon  
       2021-10-15 10:41:43 +08:00
    这玩意我怎么看着有点像 GraphQL 呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1000 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:28 · PVG 04:28 · LAX 12:28 · JFK 15:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.