Closed Tsuk1ko closed 2 years ago
不好意思,没完全懂,可否说一下具体应用场景?
这种是否符合你说的场景呢?
// vite.config.ts
import { defineConfig } from 'vite';
import monkey, { cdn } from 'vite-plugin-monkey';
export default defineConfig(({ command, mode }) => ({
plugins: [
monkey({
build: {
externalGlobals: {
'element-plus': cdn.jsdelivr('ElementPlus'),
'element-plus/dist/index.css': [
'',
(version) => {
const fn = ({ href = '' }) => {
const style = document.createElement('style');
style.innerHTML = `@import '${href}';`;
document.head.appendChild(style);
};
return (
'data:application/javascript,' +
encodeURIComponent(
`;(${fn
.toString()
.replaceAll(/[\s]{2}/g, '')})(${JSON.stringify({
href: `https://unpkg.com/element-plus@${version}/dist/index.css`,
})});`,
)
);
},
],
},
},
}),
],
}));
main.ts
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
console.log(ElementPlus);
dist.user.js
// ==UserScript==
// @name example
// @namespace https://github.com/lisonge
// @version 1.0.1
// @author lisonge
// @description default description zh
// @include /^https:\/\/i\.songe\.li\/.*/
// @match https://i.songe.li/
// @require https://unpkg.com/element-plus@2.2.16/dist/index.full.js
// @require data:application/javascript,%3B((%7B%20href%20%3D%20%22%22%20%7D)%20%3D%3E%20%7B%20const%20style%20%3D%20document.createElement(%22style%22)%3B%20style.innerHTML%20%3D%20%60%40import%20'%24%7Bhref%7D'%3B%60%3B%20document.head.appendChild(style)%3B%20%7D)(%7B%22href%22%3A%22https%3A%2F%2Funpkg.com%2Felement-plus%402.2.16%2Fdist%2Findex.css%22%7D)%3B
// ==/UserScript==
@Tsuk1ko
这种也可以解决你代码里存在的问题
/src/utils/elementPlus.ts#L7-L14
import { defineConfig } from 'vite';
import monkey, { cdn } from 'vite-plugin-monkey';
import elementPlusPkg from 'element-plus/package.json';
export default defineConfig(({ command, mode }) => ({
plugins: [
monkey({
userscript: {
resource:
command == 'build'
? {
'element-plus': `https://unpkg.com/element-plus@${elementPlusPkg.version}/dist/index.css`,
}
: {},
grant: ['GM_addStyle', 'GM_getResourceText'],
},
build: {
externalGlobals: {
'element-plus': [
'ElementPlus',
(version) =>
`https://unpkg.com/element-plus@${version}/dist/index.full.js`,
],
'element-plus/dist/index.css': [
'',
() => {
// @ts-ignore
const fn = () => GM_addStyle(GM_getResourceText('element-plus'));
return (
'data:application/javascript,' +
encodeURIComponent(
`;(${fn.toString().replaceAll(/[\s]{2}/g, '')})();`,
)
);
},
],
},
},
}),
],
}));
主要是为了可以动态获取版本号
代码里可以这样获取版本号
// vite.config.ts
import elementPlusPkg from 'element-plus/package.json';
// elementPlusPkg 在 vscode 中是自动类型提示的
console.log(elementPlusPkg.version);
// @require data:application/javascript
在 greasyfork 里,现在它是已经允许的 cdn url,具体可以看 greasyfork#1084
主要是为了可以动态获取版本号
代码里可以这样获取版本号
// vite.config.ts import elementPlusPkg from 'element-plus/package.json'; // elementPlusPkg 在 vscode 中是自动类型提示的 console.log(elementPlusPkg.version);
对的,其实我是想要这样的效果,感谢思路,我都忘了还能直接导入 package.json 😂
这种也可以解决你代码里存在的问题
我需要将 element-plus 放在 resource 里的原因是他需要依赖 vue,很奇怪的一点是即使我已经确保它的 require 在 vue 后面,但它还是取不到脚本全局作用域里的 vue,不知是否和 vue 的导出方式和 element-plus 的取变量方式有关
所以我只能手动把 vue 挂载 window 上再 eval element-plus(不知道有没有更好的方式)
将 css 写到 externalGlobals 里这个操作学到了,在我这个场景里倒是不是很必要,因为 element-plus 组件我只会在极少数的情况下使用,所以弄成现在这样类似动态导入的效果也挺好的
// @require data:application/javascript
在 greasyfork 里,现在它是已经允许的 cdn url,具体可以看 greasyfork#1084
说起来假如我需要一开始就在 require 里引入 element-plus,貌似可以利用这点去手动在 require vue 和 require element-plus 之间加入一段 js 来执行我上面所说的将 vue 塞到 window 里的操作,不过这就要求插件需要可以自定义 require 和 externalGlobals 内部的顺序,或者是让一个 externalGlobals 可以插入多个 require
我需要将 element-plus 放在 resource 里的原因是他需要依赖 vue,很奇怪的一点是即使我已经确保它的 require 在 vue 后面,但它还是取不到脚本全局作用域里的 vue,不知是否和 vue UMD 的导出方式和 element-plus 的取变量方式有关
解决方法在 issues/5#issuecomment-1229716109
这也正是我发起 greasyfork#1084 的原因
不过这就要求插件需要可以自定义 require 和 externalGlobals 内部的顺序,或者是让一个 externalGlobals 可以插入多个 require
插件 require 排列的顺序就是 externalGlobals 遍历 key 的顺序
当然,如果想自定义顺序,可以直接使用 pluginConfig.format , 输入参数是 string[][] 每项的第一项都是 userscript 的 key 后续项是它的值,对于 resource 这种,有两个后续项
明白了,非常感谢
如果你使用的 cdn 来自 jsdelivr, 它提供了 自动 mini js 的功能 可以把 https://cdn.jsdelivr.net/npm/element-plus@2.2.16/dist/index.full.js 换成 https://cdn.jsdelivr.net/npm/element-plus@2.2.16/dist/index.full.min.js
因为 element-plus 组件我只会在极少数的情况下使用
element-plus 是支持 tree shaking
的,其实可以直接打包进去的,少量使用
不会让 dist.user.js 增加多少大小
使用的时候不要用全量导入
import elementPlus from 'element-plus'
import * as elementPlus2 from 'element-plus'
要用
import { ElButton } from 'element-plus'
具体可以看 https://element-plus.org/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5
嗯,这个我是知道的
其实一开始我就是按需引用的,虽然用的很少,由于不允许缩小化所以还是会让脚本体积大幅增加(大约增加 600KB,虽然如果 gzip 的话也不算很多)
所以想了想索性就放 resource 里吧,而且也能让成品的可读性变高
原来是这样
不过这就要求插件需要可以自定义 require 和 externalGlobals 内部的顺序,或者是让一个 externalGlobals 可以插入多个 require
perf: now externalGlobals
is support Array at v2.4.1
example at playground/ex-vue-demi
我感觉在 resource 里添加 cdn 上的 css 这种使用方式挺常见的,能否让 resource 跟 externalGlobals 一样支持使用 cdn 工具函数
(想了下好像不太对,应该是需要一种新的 cdn 工具函数能直接返回 cdn 地址字符串,主要是为了可以动态获取版本号)