借助今年特殊五一假期的空闲,把一个chrome插件小项目升级了下组件。
前端库版本升级(花费1天):
- vue cli /webpack -> vite
- vue2 -> vue 3
- echart 4 -> echarts 5
- bootstrap 4 -> bootstrap 5
- 更换vue3版的codemirror插件
chrome编译工具升级(花费2天):
- chrome插件编译热加载
webpack-extension-reloader
更换为@samrum/vite-plugin-web-extension
- 尝试升级manifest v3 放弃
vue的构建系统升级
从webpack到vite 感觉轻快了不少
1、全局引入jquery和bootstrap
在main.js中
import 'jquery'
import 'bootstrap'
在使用的地方也要引入
import $ from 'jquery'
import * as bootstrap from 'bootstrap'
vue2到3
这个过程还好,感觉还比较平滑,可见:vue2到3的迁移概述
1、入口html文件中不用再引入css了,编译时会自动引入;script 引入中多了type=''module"
<script type="module" src="./main.js"></script>
2、引入*.vue需要带上后缀
import App from './App.vue'
3、$set
、$delete
被移除,基于代理的变化检测已经不再需要
this.$set(obj, newAttr, value)
// 直接使用
obj.newAttr = value
<template>
<p>{{ accountBalance | currencyUSD }}</p>
</template>
<script>
export default {
data: {
accountBalance: 100
},
filters: {
currencyUSD(value) {
return '$' + value
}
}
}
</script>
可以直接使用method替代,也可以使用计算属性或者全局属性
<template>
<p>{{ currencyUSD(accountBalance) }}</p>
</template>
<script>
export default {
data: {
accountBalance: 100
},
methods: {
currencyUSD(value) {
return '$' + value
}
}
}
</script>
5、新增emits选项,可以指定组件触发事件
6、v-model已升级,默认指modelValue
<intpu type="text" v-model="val" />
<!-- 简单修改为以下 -->
<intpu type="text" v-model:value="val" />
7、vue3使用this
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const _this= instance.appContext.config.globalProperties
bootstrap4到5
一路跟着bootstrap3/4/5 套路基本适应了;不过这次比较大的改动是去掉了jquery依赖。
1、依赖变化
-
popperjs升级1.x到@popperjs/core@2.x
-
移除了jquery依赖
2、表单部分升级了
form-group -> input-group
去掉了form-inline,只能用row+col来完成水平布局了
3、间距左、右都改为开始、结束
s
- (start) for classes that setmargin-left
orpadding-left
in LTR,margin-right
orpadding-right
in RTLe
- (end) for classes that setmargin-right
orpadding-right
in LTR,margin-left
orpadding-left
in RTL
例如:
ml -> ms
mr -> me
3、*-success
的配色更暗了,*-info
的配色更亮了;
4、组件由于去掉了jquery,使用boostrap自身API
以Modal举例:
// 之前
$('#modal').modal('show')
// 现在
var el = document.getElementById('modal')
var modal = bootstrap.Modal.getOrCreateInstance(el)
modal.show()
如果在在show动画完成之后在一次性回调一个方法
$('#modal').modal('show').one('shown.bs.modal', callback)
// 现在
let el = bootstrap.Modal.getOrCreateInstance(this.$refs.modal)
let handle = e => {
callback(e)
el.removeEventListener('shown.bs.modal', handle, false)
}
el.addEventListener('shown.bs.modal', handle)
el.show()
echarts4到5
echarts的升级还算较平滑,但是vue-echarts 从4到6的升级遇到问题花费了大量时间
1、尝试使用vue-echarts 6x示例推荐的composition api方式
2、尝试使用按使用组件导入而非全局导入echarts
组合函数
我理解composition api 是进一步分离的数据和视图的逻辑,把响应式变量、响应式更改和监控单独分离出来。这样前端的数据层变成独立的数据事件驱动,而视图层绑定到数据层暴露的变量上,渲染出最后用户视图。以及把用户操作转化为事件发送给数据层,数据层执行处理逻辑后,变更数据即可。最后变化数据自动刷新和渲染用户视图。
这个设计和vuex一样,引入了较多概念,门槛略高,对小型项目意义不大。
对ref
的理解可能花了太多时间,这里有个注意点:
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个
.value
property,指向该内部值。
setup() {
const chartOptions = ref({
loadAverage: {},
diskFree:{}
})
const getMonitorData = async () => {
let r = await axios.get('/xxxx')
// 引用对象的值在value属性上
chartOptions.value.loadAverage = getLoadAverage(r.data)
chartOptions.value.diskFree = getDiskFree(r.data)
}
return { chartOptions, getMonitorData }
}
按使用组件导入
非全局导入非常的不友好,它需要细致了解echarts的组件构成
仅仅是画个饼图,要使用以下组件导入和初始化:
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { PieChart } from "echarts/charts";
import {
TitleComponent,
TooltipComponent,
LegendComponent
} from "echarts/components";
import VChart, { THEME_KEY } from "vue-echarts";
use([
CanvasRenderer,
PieChart,
TitleComponent,
TooltipComponent,
LegendComponent
]);
vue的codemirror插件
这个可选余地不大,从vue-codemirror 到 codemirror-editor-vue3
chrome编译插件
在尝试过一圈 vite-plugin-chrome-extension、rollup-plugin-chrome-extension 、vite-plugin-vue-crx3之类的插件失败后。
插件 @samrum/vite-plugin-web-extension 是目前找到可以同时支持Manifest V2、Manifest V3,以下简称(MV2、MV3)。
思路都是直接生成最终的manifest.json
import manifest from './src/manifest.json'
import { defineConfig } from "vite";
import webExtension from "@samrum/vite-plugin-web-extension";
export default defineConfig({
root: './src',
base: '/',
build: {
outDir: resolve('./dist'),
assetsDir: './',
}
plugins: [
webExtension({
manifest: {
...manifest,
name: pkg.name,
description: pkg.description,
version: pkg.version,
},
}),
],
});
但是目前好像热更新和dev的编译模式支持不太好,我看dev也是用build,只不过加了个watch。
"scripts": {
"dev": "vite build --watch",
"build": "vite build"
},
参考: chrome extension v3 示例 感觉不用插件,修改roll也可以达到目前自动编译
chrome Manifest v2 升级到v3
这个尝试以失败告终了,有一下2点问题:
1、eval方式的热更新支持不了了
新的CSP下, 没法热更新,之前的webpack-extension-reloader插件不能用了
In addition, Manifest V3 disallows certain CSP modifications for
extension_pages
that were permitted in Manifest V2. Thescript-src,
object-src
, andworker-src
directives may only have the following values:
self
none
- Any localhost source, (
http://localhost
,http://127.0.0.1
, or any port on those domains)CSP modifications for
sandbox
have no such new restrictions.
2、chrome://favicon 访问被移除且无替代方案
官方说好马上会加入新的favicon访问API
- New favicon API: this new JavaScript API replaces “chrome://favicons” and gives developers a way to retrieve websites’ favicons.
但是大半年都过去,见 Stackoverflow上的贴, 说好的New API 迟迟没来 chrome dev issues#1541 众多使用了站点图标的插件只好都停步于MV2了,但官方计划2023年就不支持MV2版本插件了。这一点开发者有点无语。