“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
前言
公司需要一款爬取网页数据的插件,因此下面是开发中所遇到的问题。
热更新开发
项目的热更新是开发阶段十分重要的部分,能够减少开发的时间成本。由于使用的是 Vue3 开发项目,因此打包工具 是使用 Vite,这里使用到的一个 Vite 的插件 @crxjs/vite-plugin
vite.config.ts
vite.config.ts 的代码配置
import { defineConfig } from "vite";
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import manifest from './src/manifest.json'
import pkg from './package.json'
const isProd = process.env.NODE_ENV === "production"
manifest.name = isProd ? 'ac简历采集插件' : 'ac简历采集插件测试'
const crxOptions = {
manifest: Object.assign(manifest, {
version: pkg.version,
})
}
export default defineConfig({
build: {
outDir: isProd ? 'dist/build' : 'dist/dev',
},
plugins: [
vue(),
crx(crxOptions)
]
});
遇到问题
在项目中我使用到了 jquery 技术,因此把 jquery 文件放在项目的目录下面,在 npm run dev
时,插件是 copy 了 src的目录,未进行代码的压缩,因此在开发中可以使用 $
, 但是在 npm run build
进行了代码的压缩工作,导致 jquery 文件也进行了一次压缩,因此 build 打出来的包是有问题的。这个时候就需要使用yarn add jquery
就可以使用 import $ from jquery
。
从中学习到了当使用打包 压缩已经被压缩过的技术,或者要使用 import
不能把包放到本地文件上面,应该 npm install
放到 node_modules 。
fetch 的跨域解决
看了 fetch 解决跨域只需要添加 mode: 'cors'。
let myHeaders = new Headers({
'Access-Control-Allow-Origin': '*',
'Content-Type': 'text/plain'
});
fetch(url, {
method: 'GET',
headers: myHeaders,
mode: 'cors'
}) .then((res) => {
// TODO
})
但是不知道为啥项目配置了,接口请求还是发生了跨域的错误。后面的查阅资料, 只需要在 manifest.json
文件配置:
"host_permissions": ["http://*/*", "https://*/*", "<all_urls>"]
就可以解决 chrome 插件调用接口时的跨域错误。
为了开发方便也对 fetch 进行了的分装。
import { ElMessage, ElLoading } from 'element-plus';
let baseUrl = import.meta.env.VITE_APP_API;
export default function request(
method,
url,
body = undefined,
formData = undefined,
headers = {},
) {
method = method.toUpperCase();
if (method === 'GET') {
// fetch的GET不允许有body,参数只能放在url中
body = undefined;
} else if (formData) {
body = formData;
} else {
body = body && JSON.stringify(body);
}
let cookie = undefined;
chrome.storage.local.get(['cookies'], function (res) {
if (res['cookies']) {
cookie = res['cookies'];
}
});
headers.Cookie = cookie;
const loadingInstance = ElLoading.service({
lock: true,
text: '请求中...',
spinner: 'el-icon-loading',
});
// response.json() 能获取 接口返回的值,这个是异步的操作,因此搭配上了 async 和 await
return fetch(baseUrl + url, {
method,
headers,
body,
}).then(async (response) => {
loadingInstance.close();
let res = await response.json();
if (!res.success) {
ElMessage.error(res.message || 'error!');
}
return res;
});
}
注意点: fetch的GET不允许有body,参数只能放在url中
cookies 怎么获取保存
chrome.cookies.getAll(
{ domain: 域名, name: 'uid' },
(cookies) => {
chrome.storage.local.set({ cookies: cookies[0].value });
},
);
根据 domain 获取到对应的数组,然后拿到下面的cookies值。
这个cookies是保存在 chrome,域名下的 cookies,不是保存在 popup里面。
登录的时候拿到 cookies 再进行存储到 chrome.storage.local
. 这里就分装到了前面的 fetch 代码里面。
最后
插件已经给了公司部门同事使用了,在使用的过程中发现有些同事程序无法运行,因为我使用chrome 最新 V3 的版本进行开发。所以当大家开发插件也是 V3 版本,使用者遇到不知名的 bug 可以让他升级下 chrome的版本。