Electron Temas Avanzados

Electron no solo puede construir aplicaciones de escritorio multiplataforma, sino que también admite integración profunda con el sistema y expansión de funciones avanzadas. Dominar estas técnicas avanzadas puede hacer que la aplicación sea más profesional y potente.


Integración de módulos nativos de Node

Uso de node-gyp

  • node-gypEs una herramienta de compilación de módulos nativos de Node.js, admite la compilación de módulos C/C++
  • Instalación:

    npm install -g node-gyp
  • Inicializar proyecto:
    node-gyp configure
    node-gyp build
  • Salida.nodearchivo, se puede cargar directamente en Electron:
    const native = require('./build/Release/native.node')

Compilar módulos nativos

  • Los módulos nativos deben compilarse para la versión de Node y ABI de Electron
  • Usarelectron-rebuildherramienta:
    npm install --save-dev electron-rebuild
    npx electron-rebuild
  • Asegurar que el módulo sea compatible con la versión actual de Electron

Solución de problemas comunes

  • Incompatibilidad de ABI: Electron usa una versión diferente de Node, se necesitaelectron-rebuild
  • Error de compilación: Verificar el entorno de compilación de C++ (Windows requiere Visual Studio Build Tools, macOS requiere Xcode Command Line Tools)
  • Problemas de ruta: Asegurar que la ruta del módulo sea correcta, usar ruta absoluta para cargar.nodearchivo

Integración profunda con el sistema

Detección de tema del sistema

  • Detectar tema oscuro/claro:
    const { nativeTheme } = require('electron')
    console.log(nativeTheme.shouldUseDarkColors)
    nativeTheme.on('updated', () => {
      console.log('主题更新:', nativeTheme.shouldUseDarkColors)
    })
  • Evitar que el sistema entre en suspensión:
    const { powerSaveBlocker } = require('electron')
    const id = powerSaveBlocker.start('prevent-display-sleep')
    powerSaveBlocker.stop(id)
  • Detectar estado de energía:
    const { systemPreferences } = require('electron')
    console.log(systemPreferences.getSystemIdleTime())

Gestión de pantallas

  • Obtener información de la pantalla:
    const { screen } = require('electron')
    const primaryDisplay = screen.getPrimaryDisplay()
    console.log(primaryDisplay.size)
  • Compatibilidad con múltiples pantallas, detección de resolución y adaptación automática de ventanas

Detección de inactividad del sistema

  • A través desystemPreferences.getSystemIdleTime()Obtener el tiempo de inactividad del usuario
  • Se puede usar para bloqueo automático de pantalla, ahorro de energía o funciones de recordatorio

Soporte multilingüe

Plan de implementación de i18n

Bibliotecas comunes:

  • i18next: Admite paquetes de idioma JSON/YAML, cambio dinámico
  • vue-i18n / react-i18next: Integración con frameworks frontend

Estructura de archivos:

locales/
  en.json
  zh.json

Cambio de idioma:

const i18next = require('i18next')
i18next.init({
  lng: 'en',
  resources: {
    en: { translation: require('./locales/en.json') },
    zh: { translation: require('./locales/zh.json') }
  }
})
console.log(i18next.t('hello')) // 输出 hello

Se puede modificar dinámicamentelng, para lograr el cambio de idioma en tiempo real.

Carga dinámica de paquetes de idioma

  • Para proyectos grandes, los paquetes de idioma se pueden cargar según sea necesario:
    async function setLanguage(lang) {
      const resources = await import(`./locales/${lang}.json`)
      i18next.addResources(lang, 'translation', resources.default)
      i18next.changeLanguage(lang)
    }
  • Optimizar el tamaño del paquete, reducir el tiempo de carga de inicio

Protocolos personalizados

Electron admite el registro de protocolos personalizados, lo que permite que la aplicación invoque funciones internas o implemente enlaces profundos (Deep Linking) a través de esquemas de URL específicos.

Registrar protocolos personalizados

  • UsarprotocolMódulo para registrar protocolos personalizados
  • Se puede usar para cargar recursos internos de la aplicación o responder a URLs específicas
const { app, protocol } = require('electron')

app.whenReady().then(() => {
  protocol.registerFileProtocol('myapp', (request, callback) => {
    const url = request.url.substr(7) // 去掉 'myapp://'
    callback({ path: `${__dirname}/${url}` })
  })
})

Descripción:

  • 'myapp': Nombre del protocolo personalizado
  • request.url: URL completa pasada
  • callback({ path }): Apunta a la ruta de archivo local, se puede usar para cargar HTML, imágenes, etc.

Enlaces profundos (Deep Linking)

  • Los enlaces profundos permiten a los usuarios abrir páginas o funciones específicas de la aplicación directamente a través de URL
  • Registrar protocolo del sistema:
    if (!app.isDefaultProtocolClient('myapp')) {
      app.setAsDefaultProtocolClient('myapp')
    }
  • En macOS / Windows, hacer clic enmyapp://note/123puede activar eventos de la aplicación
  • Manejar enlaces profundos:
    app.on('open-url', (event, url) => {
      event.preventDefault()
      console.log('接收到深度链接:', url)
      // 可解析 URL 跳转到应用内部页面
    })
  • Manejo de eventos en Windows:
    app.on('second-instance', (event, argv) => {
      const url = argv.find(arg => arg.startsWith('myapp://'))
      if (url) {
        console.log('接收到深度链接:', url)
      }
    })

Manejo de protocolos

  • Seguridad:

    • Validar el contenido de la URL, evitar la ejecución de operaciones no autorizadas
    • Evitar cargar archivos maliciosos o ejecutar comandos arbitrarios
  • Casos de uso:

    • Abrir notas, documentos o páginas específicas
    • Interactuar con páginas web, invocar funciones locales
    • Comunicación entre aplicaciones o multiplataforma
  • Notas:

    • En macOS se debe configurar en Info.plistCFBundleURLTypes
    • En Windows se debe registrar el protocolo en el registro
    • Se recomienda colocar la lógica de manejo de protocolos en el proceso principal, el proceso de renderizado solo recibe eventos
Otras extensiones