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

载入插件

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

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

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

  1. import { app } from 'electron'
  2. import { resolve } from 'path'
  3. import { readdirSync } from 'fs-extra'
  4. import requireFoolWebpack from 'require-fool-webpack'
  5. const userHome = app.getPath('home')
  6. const pluginsPath = resolve(userHome, '.reader-app-scripts') // 默认插件陌路
  7. // 具体 require 有啥问题,可以参考以下链接
  8. // https://github.com/webpack/webpack/issues/196
  9. // https://github.com/sindresorhus/require-fool-webpack
  10. export default () => {
  11. let files = readdirSync(pluginsPath)
  12. return files.map(
  13. filename =>
  14. requireFoolWebpack(resolve(pluginsPath, filename))(requireFoolWebpack) // 载入爬取规则
  15. )
  16. }

自动化插件

修改 index.ts

  1. import loadPlugins from './loadPlugins'
  2. import log from './statusLog'
  3. let plugins: any[]
  4. async function ready() {
  5. mainWindow = createMainWindow()
  6. plugins = loadPlugins() // 载入插件
  7. on('download').subscribe(({ event, args }) => {
  8. const plugin = plugins.find(plugin => plugin.regexp.test(args.url)) // 通过网址匹配寻找合适的插件
  9. if (!plugin) {
  10. return log({ type: 'plugin', message: 'not support' }) // 没有找到插件
  11. }
  12. download(args.url, plugin, { path: './' })
  13. })
  14. }

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

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

  1. module.exports = load => {
  2. const join = load('url-join')
  3. return {
  4. regexp: /www\.ybdu\.com/gi, // 匹配正则
  5. opts: {
  6. charset: 'gbk'
  7. },
  8. chapter($, url) {
  9. const datas = []
  10. $('.mulu_list li').each(function(i, ele) {
  11. const self = $(this)
  12. const title = self.text().replace(/\s/g, '')
  13. const chapter_url = self.find('a').attr('href')
  14. datas.push({
  15. title,
  16. url: join(url, chapter_url)
  17. })
  18. })
  19. return datas
  20. },
  21. text($) {
  22. const trim = sourceString => {
  23. const dels = [
  24. '加入书签',
  25. '加入书架',
  26. '推荐投票',
  27. '返回书页',
  28. '上一页',
  29. '返回目录',
  30. '下一页',
  31. /\s+/gi,
  32. /(\-)*/gi
  33. ]
  34. dels.forEach(delString => {
  35. // 纯函数
  36. sourceString = sourceString.replace(delString, '')
  37. })
  38. return sourceString
  39. }
  40. const sourceString = $('#htmlContent').text()
  41. return trim(sourceString)
  42. }
  43. }
  44. }