Electron组件化

electron组件化概念

框架/语言              Flutter                      Electron                       Swift
依赖声明文件          pubspec.yaml                 package.json                    Podfile
官方仓库               pub.dev                      npmjs.com                   cocoapods.org
私有仓库                 支持                          支持                          支持
安装命令               pub get                     pod install              npm/pnpm install
  • Flutter本地引用方式:
dependencies:               
  local_package:             
    path: xx/xx/local_package     
  • Electron本地引用方式:
dependencies:{
  "local-ui":"file: ../local-ui"
}
  • Swift本地引用方式:
pod 'local', :path => 'xx/local'

创建一个本地组件,发布到官方仓库

  • 注册帐号
  • 终端登陆:
    npm login
    
  • 查看当前源:
    npm config get registry
    //如果显示的是 https://registry.npmjs.org/ → 官方源(可注册、发布)
    //如果显示的是 https://registry.npmmirror.com/ → 淘宝镜像(只读)
    
  • 切回npm官方源:
    npm config set registry https://registry.npmjs.org/
    
  • 也可以指定某些包从镜像安装,某些包从官方安装:
    npm install 包名 --registry=https://registry.npmmirror.com/
    
    or
    npm install 包名 --registry=https://registry.npmjs.org/
    
  • 创建一个组件包
    mkdir electron-test
    cd electron-test
    npm init -y
    
  • 得到一个文件夹electron-test,目录结构是:
    electron-test/
          └──package.json
    
  • electron-test/package.json:
    {
     "name": "electron-test",
     "version": "1.0.0",
     "main": "index.js",
     "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
     },
     "keywords": [],
     "author": "",
     "license": "ISC",
     "description": ""
    }
    
  • 创建electron-test/index.js:
    function helloUI() {
    console.log("Hello from electron-cc-kit-ui");
    }
    //CommontJS,只能在node.js环境中使用
    module.exports = { helloUI };
    
  • 发布到npm:
    npm publish --access public
    
  • 验证发布:
    • npm search搜索的索引有延迟,通常需要 5~15 分钟(有时候甚至 1 小时以上)才能用 npm search官方仓库 搜索到。
    • npm search 已经不再推荐用于查找包
      npm search electron-test
      
    • 官方文档推荐用官方仓库去查,或者npm view/npm info查看
      npm view electron-test
      
      npm info electron-test
      
  • 任意项目中安装:
    npm install electron-test 
    
  • electron的main.js或者preload.js使用:
    const electronTest = require('./electron-test');
    electronTest.helloUI();
    



父组件,管理众多独立的子组件(都发布到 官方仓库

  • 父组件,管理众多子组件,安装父组件,就能自动安装众多子组件
  • 众多子组件也可以单独安装

一. 文件结构
  • 结构示意图:
      electron-manager/
              └── package.json
              ├── index.js
              └──  electron-http/
                          └── package.json
                          ├── index.js
              └──  electron-ui/
                          └── package.json
                          ├── index.js
              └──  electron-file/
                          └── package.json
                          ├── index.js
    
  • 众多子组件:
    electron-http/package.json:
    electron-ui/package.json:
    electron-file/package.json:
    {
      //"name": "electron-http",
      //"name": "electron-ui",
     "name": "electron-file",
     "version": "1.0.0",
     "main": "index.js",
     "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
     },
     "keywords": [],
     "author": "",
     "license": "ISC",
     "description": ""
    }
    
  • 子组件electron-http/index.js:
    // 你的功能函数
    function get(url) {
      console.log(`GET request to ${url}`);
    }
    
    function post(url, data) {
      console.log(`POST request to ${url} with data`, data);
    }
    
    // 暴露给外部
    module.exports = {
      get,
      post
    };
    
  • 子组件electron-ui/index.js:
    function render() {
      console.log(`electron-ui render`);
    }
    module.exports = {
      render
    };
    
  • 子组件electron-file/index.js:
    function save(path) {
      console.log(`save ${path}`);
    }
    module.exports = {
      save
    };
    
  • 父组件electron-manager/package.json:
    {
     "name": "electron-manager",
     "version": "1.0.0",
     "main": "index.js",
     "dependencies": {
       "electron-http": "^1.0.0",
       "electron-ui": "^1.0.0",
       "electron-file": "^1.0.0"
      }
    }
    
  • 父组件electron-manager/index.js:
    // 统一导出所有子组件
    module.exports = {
      http: require('electron-http'),
      ui: require('electron-ui'),
      file: require('electron-file')
    };
    

二. 发布
  • 先发布每个子组件:
    cd electron-http
    npm publish
    
    cd ../electron-ui
    npm publish
    
    cd ../electron-file
    npm publish
    
  • 再发布父组件(确保 dependencies 指向的子组件都发布了):
    cd electron-manager
    npm publish
    

三. 安装使用
  • 安装:
    npm install electron-manager
    
  • 使用:
    const electronManager = require('electron-manager');
    
    electronManager.http.get('https://example.com');
    electronManager.ui.render();
    electronManager.file.save('/path/file.txt');
    
    or
    import { http, ui, file } from 'electron-manager';
    
    http.get('https://example.com');
    ui.render();
    file.save('/path/file.txt');
    
  • 也可以单独安装众多子组件:
    npm install electron-http
    npm install electron-ui
    npm install electron-file
    
  • 使用:
    const http = require('electron-http');
    const ui = require('electron-ui');
    const file = require('electron-file');
    
    http.get('https://example.com');
    ui.render();
    file.save('path/file.txt');
    



发布的父组件,管理众多本地的子组件

一. 文件结构
  • 结构示意图:
      electron-manager/                                           # 父组件(发布到 npm)
              └── package.json
              ├── index.js
              └── packages/
                      └──  electron-http/                        # 本地子组件(不发布)
                                   └── package.json
                                   ├── index.js
                      └──  electron-ui/                          # 本地子组件(不发布)
                                   └── package.json
                                   ├── index.js
                      └──  electron-file/                        # 本地子组件(不发布)
                                   └── package.json
                                   ├── index.js
    
  • 众多子组件的package.json/index.js如上

二. 配置
  • 方法 1:父组件依赖本地子组件(file:)
    • 发布父组件时,本地路径依赖不会被上传到 npm。
    • 本地开发时会链接到子组件。
    • electron-manager/package.json:
      {
       "name": "electron-manager",
       "version": "1.0.0",
       "main": "index.js",
       "dependencies": {
         "electron-http": "file:packages/electron-http",
         "electron-ui": "file:packages/electron-ui",
         "electron-file": "file:packages/electron-file"
        }
      }
      
  • 方法2: 父组件通过 workspace 管理本地子组件:
    • 发布父组件,workspace 里的子组件不会随父包发布。
    • 本地开发时,workspace 会自动链接子包。
    • 所有子组件,必须在文件夹packages/路径下
    • electron-manager/package.json:
      {
        "name": "electron-manager",
        "version": "1.0.0",
        "private": true,
        "main": "index.js",
        "workspaces": ["packages/*"],
        "dependencies": {
          "electron-http": "*",
          "electron-ui": "*",
          "electron-file": "*"
        }
      }
      
三. 安装&使用
npm install electron-manager



未发布的父组件,管理众多未发布的子组件,让宿主项目可以在渲染层直接使用

  • 上面的几种方式,都是node环境,electron的渲染层不能直接import {xxx} from `xx/xx/xx`;
  • 上面的几种方式,在electron的main.js或者preload.js,可以直接使用const {xxx} = require('xxx');
  • 渲染层直接使用组件,不能使用CommonJS,只能使用ESM
  • ESMCommonJS区别;
    特性                            ESM                               CommonJS                  
    定义                    Node.js 传统模块系统               JavaScript 标准模块系统(ES6+)      
    导入               const x = require('module')             import {x} from 'xx/xx.js'       
    导出                    module.exports = {}                export {} / export default
    是否支持浏览器           否,浏览器不认识require                          是
                       需要设置nodeIntegration: false      浏览器原生支持 <script type="module">
                             contextIsolation: true
    
  • 由于是要给渲染层html/js直接使用的组件,就不能使用node.js的接口
  • 父组件electron-manager的结构:
      electron-manager/                                  # 父组件(不发布到)
              └── package.json
              ├── index.js
              └──  electron-ui/                        # 本地子组件(不发布)
                        ├── index.js
                        └── package.json
    
  • electron-manager/package.json:
    {
     "name": "electron-manager",
     "version": "1.0.0",
     "type": "module"
     "main": "index.js",
     "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
     },
     "keywords": [],
     "author": "",
     "license": "ISC",
     "description": "",
     "dependencies": {
       "electron-ui": "file:/electron-ui"
     }
    }
    
  • electron-manager/index.js:
    ///⚠️这里很关键,是要使用ESM导出方式
    export { default as UI } from './electron-ui/index.js';
    
  • electron-ui/package.json:
    {
     "name": "electron-kit-hid",
     "version": "1.0.0",
     "type": "module",
     "main": "index.js",
     "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
     },
     "keywords": [],
     "author": "",
     "license": "ISC",
     "description": ""
    }
    
  • electron-ui/index.js:
    function buildButton(){}
    
    export default buildButton;
    

宿主项目的使用

  • 宿主项目的package.json
    {
    
     //添加本地组件到开发依赖
     "devDependencies":{
       //使用file,获取到本地父组件electron-manager到宿主项目的相对路径
      "electron-manager": "file:../../electron-manager" 
      },
     //添加本地组件到发布依赖
     "dependencies": {
       "electron-manager": "file:../../electron-manager"
     },
      "build": {
      // 禁用 asar 打包,确保打包后项目的文件路径正确
      "asar": false,
      "files": [
        "**/*",
        "!build/**/*",
        "!src/hid_on.js",
        "!.vscode/",
        "!node_modules/*",
         ///如果做了减少打包后包体大小的处理,要特别注意,要把本地组件放出来,打包进去 
        "node_modules/electron-manager/**/*"
      ],
      }
    }
    
  • 宿主项目渲染层xx.js导入:
    开发时,可以直接使用本地组件的相对路径:
    ///这里⚠️,使用ESM导入方式
    import {
        UI
    } from '../../../../../electron-manager/index.js';///⚠️,这里要使用父组件electron-manager的路径
    
    打包,一定要使用项目里node_modules的相对路径:
    import {
     UI
    } from '../../node_modules/electron-manager/index.js';
    
  • 宿主项目中,本地组件的使用:
    UI.buildButton();
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容