CabloyJS 基于 EggJS 实现的模块编译与发布 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhennann
V2EX    Node.js

CabloyJS 基于 EggJS 实现的模块编译与发布

  •  
  •   zhennann 2021-07-04 16:37:49 +08:00 1763 次点击
    这是一个创建于 1592 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    现在,EggJS被许多开发团队所采用。有的团队基于商业知识产权的考量,往往会提一个问题:是否可以把EggJS当中的代码编译打包,然后再把代码丑化?

    模块编译的机制

    • EggJS为何不能便利的实现编译的特性?

    EggJS中,代码文件都是通过约定代码位置的方式组织并加载的。也就是说,代码文件都放置在约定的目录结构当中,EggJS 在启动系统时,在约定的位置扫描加载约定的代码文件。因此,在这种机制下,不能便利的实现编译特性

    • CabloyJS是如何实现编译特性的?

    EggJS作为企业级框架提供了足够灵活的机制,比如,允许上层框架提供自定义的加载器CabloyJS就是基于EggJS的这种机制实现了一套自定义的加载器

    CabloyJS中,模块当中的代码文件都是通过require的方式显式组织并加载的。这种加载机制为模块内部的源码文件提供了清晰的调用依赖关系,因此我们就可以采用Webpack完成编译打包,以及丑化代码的工作

    模块编译的意义

    1. 模块复用、构建生态:模块可单独编译,从而可以单独发布、单独部署,单独升级,从而促进 CabloyJS 整个生态圈的繁荣,进一步加速实际业务的开发
    2. 知识产权:模块可单独编译,也可以满足保护商业代码的需求

    如何编译模块

    # 进入模块所在目录 $ cd /path/to/module # 编译模块前端代码 $ npm run build:front # 编译模块后端代码 $ npm run build:backend 

    编译参数

    所有模块均采用缺省的编译参数,当然也可以提供自定义的编译参数,以模块test-party为例:

    src/module/test-party/build/config.js

    module.exports = { front: { productionSourceMap: false, uglify: true, }, backend: { productionSourceMap: false, uglify: true, }, }; 
    名称 说明
    productionSourceMap 是否生成SourceMap文件
    uglify 是否uglify代码

    模块加载约定

    在模块目录下,既有src源代码文件,也有dist打包文件。那么什么时候加载src,什么时候加载dist呢?

    模块有两类:全局模块局部模块。这两类模块有不同的加载约定:

    1. 全局模块:位于项目的node_modules目录中,系统总是加载全局模块dist打包文件
    2. 局部模块:位于项目的src/module目录中,系统优先查找src目录并加载模块源码,如果没有找到则加载局部模块dist打包文件

    理解了全局模块局部模块的代码加载约定,在将项目部署在生产环境时有利于做出正确的配置(主要的诉求就是:如何保护商业代码

    最佳实践(模块前端)

    在部署时,项目前端总是要进行整体编译,把所有全局模块局部模块的前端源码和前端资源都打包,然后输出到项目的dist目录

    如果模块作为局部模块而存在,则不需要考虑模块前端的编译环节

    如果模块要发布为全局模块,则必须先进行模块前端的编译

    最佳实践(模块后端)

    1. 不进行模块编译

    如果没有保护商业代码的需求,那么就不用考虑模块编译的环节。在部署时,直接作为局部模块加载源码运行即可

    2. 进行模块编译

    如果要进行模块编译,那么在部署时有两个选择:

    • 作为局部模块
      1. 模块仍然位于项目的src/module目录
      2. 将模块编译后,在生产环境删除模块的src源码目录即可
    • 作为全局模块
      1. 将模块编译后,发布至公司的私有仓库
      2. 在项目中将模块作为全局模块安装至node_modules目录
      3. 如果没有私有仓库,也可以采用npm link机制安装为全局模块

    模块发布

    当项目中的模块代码稳定后,可以将模块公开发布,贡献到开源社区。也可以在公司内部建立 npm 私有仓库,然后把模块发布到私有仓库,形成公司资产,便于重复使用

    $ cd /path/to/module $ npm run build:front $ npm run build:backend $ npm publish 

    由于发布到 npm 仓库的模块将作为全局模块来使用,因此需要先编译模块的前端和后端

    效果图(模块后端编译)

    编译之前的源码结构

    build-backend-before

    编译之后的输出文件

    build-backend-after

    相关链接

    2 条回复    2021-07-05 16:49:17 +08:00
    libook
        1
    libook nbsp;
       2021-07-05 10:22:12 +08:00
    本质上是个 Minify+Uglify ?不知道 Webpack 能不能搞定呢?

    如果想编译成二进制的话,可以考虑转换成 V8 的字节码,V8 有相应的接口。
    zhennann
        2
    zhennann  
    OP
       2021-07-05 16:49:17 +08:00
    @libook Webpack 可以搞定,关键就是提供合适的源码组织方式。V8 字节码和快照后续可以研究一下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     922 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 20:09 PVG 04:09 LAX 12:09 JFK 15:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86