VSCode Webview 插件开发的模板的踩坑记录

前言

上周写了个 vscode 的小插件后,突然想整个 webview 的插件。

于是乎开始搜罗相关的资料,开搞!这里记录下几个踩过的坑。

问题

CSP: refused xxxxxx

常见的几类报错(打开开发者工具,在控制台就会自动输出)

  • refused to apply inline style because it violates the following Content Security Policy directive xxxxxx
  • refused to load the script '' because it violates the following Content Security Policy directiv

VSCode webview 对于资源的注入很严格!!

目前的策略是把 web 站点打包成一个index.js和 index.css去注入!

资源链接必须转换成 vscode 允许的资源格式!!!

typescript 复制代码
//path: src/panels/VueBoilerplatePanel.ts
private _getWebviewContent(webview: Webview, extensionUri: Uri) {
// The CSS file from the Vue build output
const stylesUri = getUri(webview, extensionUri, ["webview-ui", "build", "assets", "index.css"]);
// The JS file from the Vue build output
const scriptUri = getUri(webview, extensionUri, ["webview-ui", "build", "assets", "index.js"]);
const nonce = getNonce();

// Tip: Install the es6-string-html VS Code extension to enable code highlighting below
return /*html*/ `
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta http-equiv="Content-Security-Policy" content="default-src 'none';connect-src https:; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} https: data:; script-src 'nonce-${nonce}';">
      <link rel="stylesheet" crossorigin nonce="${nonce}" type="text/css" href="${stylesUri}">
      <script type="module" nonce="${nonce}" src="${scriptUri}"></script>
      <title>Hello World</title>
    </head>
    <body>
      <div id="app"></div>
    </body>
  </html>
`;
}
  1. meta的 csp 策略进行了修改,允许加载部分资源,而不是默认各种卡死,对 web 开发友好
  2. index.htmlscriptlink 标签的 srchref 都进行了转换,还有 hash 防缓存

上面的 csp 设置值的简单介绍

施加策略的目录 允许潜在的源列表 描述
default-src 'none' 默认情况下,禁止所有资源类型的加载。
connect-src https: 仅允许通过 https 协议进行 XMLHttpRequest,Fetch 加载资源等操作。
style-src ${webview.cspSource} 'unsafe-inline' 允许从 webview.cspSource 和内联样式加载样式。
img-src ${webview.cspSource} https: data: 允许从 webview.cspSource、https 协议和 data 协议(即base64 编码的图片)加载图片。
script-src 'nonce-${nonce}' 仅允许加载具有特定 nonce 值的脚本。

如何打包所有文件到一个index.js 和 index.css

  • css和js需要打包成单独文件
typescript 复制代码
// path: webview-ui/vite.config.ts

build: {
modulePreload: false, // 关闭预加载
outDir: "build", // 打包输出目录
emptyOutDir: true, // 打包之前清空build 文件夹
assetsInlineLimit: 99999999999, // 默认是4096
rollupOptions: {
  output: {
    entryFileNames: `assets/[name].js`, // 打包后的入口文件
    chunkFileNames: `assets/[name].js`,
    assetFileNames: `assets/[name].[ext]`,
    manualChunks: (id: string) => { // 打包后的静态资源,自定义策略,全部合并到 index
      return 'index'
    }
  },
},
},
  • png这类静态图片直接打包成base64(参考上面的 assetsInlineLimit)

  • svg 用 vite-svg-loader, 默认转换为 Component

typescript 复制代码
// path: webview-ui/vite.config.ts
svgLoader({ defaultImport: 'component' }),

// 在使用层面可以通过 query(?) 来转换 svg 为内联或者其他
// 具体可以去看这个插件的介绍,挺强大的

开发模式 dev

从项目结构上来看,里面就是两个工程,所以要运行两条命令;

  • 一条是打包 webview 网站输出静态资源
  • 一条是编译插件源码输出插件入口文件

那有什么可以同时运行并输出信息的呢? 我用concurrently来解决了我的这个困扰。

仓库

开源项目名称 vscode-webview-vite-vue-boilerplate
开源项目地址 github.com/crper/vscod...

tips: webview-ui(仓库内)

这是一个基于Vite 5 + Vue3 + TypeScript + UnoCSS + Vue Router + Pinia + Naive UI的项目模板,相关的初始化和配置都有,"五脏俱全",算是一个 mvp demo 项目,有兴趣的可以看看瞅瞅。

webview的 debug

基本绝大多数异常都是在开发者工具里面的控制台看,vscode 本身就是基于 electron 搞的,内核 chromium。 做了一些系统交互接口和更加严格的资源策略模式,类似各种沙盒机制!!但本质上还是"浏览器"!!

结语

有不对之处请留言,谢谢阅读

相关推荐
芯橦20 小时前
【瑞昱RTL8763E】音频
单片机·嵌入式硬件·mcu·物联网·音视频·visual studio code·智能手表
行十万里人生5 天前
信号处理: Block Pending Handler 与 SIGKILL/SIGSTOP 实验
c++·后端·深度学习·ubuntu·serverless·信号处理·visual studio code
奇点 ♡8 天前
【线程】线程安全的单例模式
linux·c语言·c++·安全·单例模式·visual studio code
羊小猪~~9 天前
C/C++语言基础--C++运算符重载以及其重载限制
java·c语言·开发语言·c++·visualstudio·visual studio code
豆包MarsCode11 天前
豆包MarsCode IDE 搭建 VitePress 博客并使用 GitHub 部署
ide·人工智能·python·数据分析·github·visual studio code
奇点 ♡11 天前
【线程】POSIX信号量---基于环形队列的生产消费者模型
linux·运维·服务器·开发语言·c++·算法·visual studio code
自白12 天前
关于我是如何二次开发了 antd-vue 的a-range-picker组件,同时还添加了 vscod智能提示这件事
vue.js·visual studio code·ant design
奇点 ♡16 天前
【线程】线程的控制
linux·运维·c语言·开发语言·c++·visual studio code
羊小猪~~21 天前
C/C++语言基础--从C到C++的不同(上)
linux·c语言·c++·后端·qt·visualstudio·visual studio code
桃子叔叔22 天前
前端工程化3:使用lerna管理多包
前端·前端工程化·lerna