V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhennann
V2EX  ›  Node.js

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

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

    背景

    现在,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  
       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   ·   我们的愿景   ·   实用小工具   ·   3880 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 00:55 · PVG 08:55 · LAX 17:55 · JFK 20:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.