假如主进程使用了打包机制,假如动态导入就会有问题,所以上一节我们才暂时抛弃了 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)
}
}
}