章节内容
历史介绍
开发环境
代码封装
函数式
获取小说命令行版(上)
获取小说命令行版(中)
获取小说命令行版(下)
嵌入到应用中
插件机制
文字转语音
设置与信号中断
插件商店
下载与删除(上)
下载与删除(下)
通知栏程序
播放功能
美化界面
数据可视化(上)
数据可视化(中)
数据可视化(下)
嵌入到应用中
打包应用

假如主进程使用了打包机制,假如动态导入就会有问题,所以上一节我们才暂时抛弃了 require , 现在我们想要把这些爬取规则放到用户的目录下面,这样假如用户想要下载某些规则,把它下载下来即可,并且了我们添加一个正则匹配,这样就可以自动赛选,选用哪一个爬取规则,为了实现则以功能肯定要扫描目录,我们使用同步的 readdirSync 因为文件并不多,所以使用同步就好了

# 载入插件

这里我们需要安装一个插件,require-fool-webpack 它可以解决 require 被转义的问题。添加定义文件 require-fool-webpack.d.ts 。

declare module 'require-fool-webpack' {
  const load: (...args: any[]) => any
  export default load
}

创建 loadPlugins.ts 文件,关于我是如何找到的可以参考代码注释里面的两个链接。插件的目录在用户的主目录下面的 .reader-app-scripts 文件夹下面。

import { app } from 'electron'
import { resolve } from 'path'
import { readdirSync } from 'fs-extra'
import requireFoolWebpack from 'require-fool-webpack'

const userHome = app.getPath('home')
const pluginsPath = resolve(userHome, '.reader-app-scripts') // 默认插件陌路

// 具体 require 有啥问题,可以参考以下链接
// https://github.com/webpack/webpack/issues/196
// https://github.com/sindresorhus/require-fool-webpack

export default () => {
  let files = readdirSync(pluginsPath)
  return files.map(
    filename =>
      requireFoolWebpack(resolve(pluginsPath, filename))(requireFoolWebpack) // 载入爬取规则
  )
}

# 自动化插件

修改 index.ts

import loadPlugins from './loadPlugins'
import log from './statusLog'

let plugins: any[]

async function ready() {
  mainWindow = createMainWindow()
  plugins = loadPlugins() // 载入插件
  on('download').subscribe(({ event, args }) => {
    const plugin = plugins.find(plugin => plugin.regexp.test(args.url)) // 通过网址匹配寻找合适的插件
    if (!plugin) {
      return log({ type: 'plugin', message: 'not support' }) // 没有找到插件
    }
    download(args.url, plugin, { path: './' })
  })
}

现在我们就简单的完成了插件机制。

我在插件文件夹里面存放了一个 www.ybdu.com.js 文件,内容如下。

module.exports = load => {
  const join = load('url-join')
  return {
    regexp: /www\.ybdu\.com/gi, // 匹配正则
    opts: {
      charset: 'gbk'
    },
    chapter($, url) {
      const datas = []
      $('.mulu_list li').each(function(i, ele) {
        const self = $(this)
        const title = self.text().replace(/\s/g, '')
        const chapter_url = self.find('a').attr('href')
        datas.push({
          title,
          url: join(url, chapter_url)
        })
      })
      return datas
    },
    text($) {
      const trim = sourceString => {
        const dels = [
          '加入书签',
          '加入书架',
          '推荐投票',
          '返回书页',
          '上一页',
          '返回目录',
          '下一页',
          /\s+/gi,
          /(\-)*/gi
        ]
        dels.forEach(delString => {
          // 纯函数
          sourceString = sourceString.replace(delString, '')
        })
        return sourceString
      }
      const sourceString = $('#htmlContent').text()
      return trim(sourceString)
    }
  }
}