Initial commit: vitepress-exporter plugin
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
node_modules/
|
||||||
|
main.js
|
||||||
|
main.js.map
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
versions.json
|
||||||
134
.obsidian/plugins/vitepress-exporter/new_method.txt
vendored
Normal file
134
.obsidian/plugins/vitepress-exporter/new_method.txt
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
// 尝试捕获 Obsidian 原生 Canvas 渲染(通过临时调整视口大小)
|
||||||
|
async tryNativeCanvasCapture(canvasFile: TFile): Promise<Uint8Array | null> {
|
||||||
|
let uiStyleElement: HTMLStyleElement | null = null;
|
||||||
|
let sizeStyleElement: HTMLStyleElement | null = null;
|
||||||
|
let activeLeaf: any = null;
|
||||||
|
let canvasWrapper: HTMLElement | null = null;
|
||||||
|
let originalScrollLeft = 0;
|
||||||
|
let originalScrollTop = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('🔍 Step 1: Getting active workspace leaf...');
|
||||||
|
|
||||||
|
// 获取当前活动的 leaf(不创建新窗口)
|
||||||
|
activeLeaf = this.app.workspace.activeLeaf;
|
||||||
|
if (!activeLeaf) {
|
||||||
|
console.log('❌ No active leaf found');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 Step 2: Opening canvas file...');
|
||||||
|
await activeLeaf.openFile(canvasFile);
|
||||||
|
|
||||||
|
console.log('⏳ Step 3: Waiting for canvas render...');
|
||||||
|
await this.waitForCanvasRender();
|
||||||
|
|
||||||
|
console.log('🔍 Step 4: Finding canvas DOM...');
|
||||||
|
const canvasDom = this.findCanvasDomElement();
|
||||||
|
if (!canvasDom) {
|
||||||
|
console.log('❌ Could not find canvas DOM element');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ Found canvas DOM:', canvasDom.className, 'Size:', (canvasDom as any).offsetWidth, 'x', (canvasDom as any).offsetHeight);
|
||||||
|
|
||||||
|
console.log('🎨 Step 5: Hiding Canvas UI elements...');
|
||||||
|
uiStyleElement = this.hideCanvasUIElements();
|
||||||
|
|
||||||
|
console.log('📐 Step 6: Calculating canvas content size...');
|
||||||
|
const contentSize = this.getCanvasContentSize(canvasDom);
|
||||||
|
|
||||||
|
// 获取 canvasWrapper
|
||||||
|
if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) {
|
||||||
|
canvasWrapper = canvasDom as HTMLElement;
|
||||||
|
} else {
|
||||||
|
canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canvasWrapper) {
|
||||||
|
console.log('❌ Could not find canvas wrapper');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存原始滚动位置
|
||||||
|
originalScrollLeft = canvasWrapper.scrollLeft;
|
||||||
|
originalScrollTop = canvasWrapper.scrollTop;
|
||||||
|
|
||||||
|
console.log(`📏 Original wrapper size: ${(canvasDom as any).offsetWidth}x${(canvasDom as any).offsetHeight}`);
|
||||||
|
console.log(`📏 Content size: ${contentSize.width}x${contentSize.height}`);
|
||||||
|
|
||||||
|
// 临时调整 canvas wrapper 大小以适应所有内容
|
||||||
|
console.log('🔧 Temporarily resizing canvas wrapper to fit all content...');
|
||||||
|
sizeStyleElement = document.createElement('style');
|
||||||
|
sizeStyleElement.id = 'canvas-export-resize';
|
||||||
|
sizeStyleElement.textContent = `
|
||||||
|
/* 临时调整 canvas wrapper 大小 */
|
||||||
|
.canvas-wrapper {
|
||||||
|
width: ${contentSize.width + 100}px !important;
|
||||||
|
height: ${contentSize.height + 100}px !important;
|
||||||
|
max-width: ${contentSize.width + 100}px !important;
|
||||||
|
max-height: ${contentSize.height + 100}px !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保画布内容区域也扩展 */
|
||||||
|
.canvas-view-content {
|
||||||
|
width: ${contentSize.width + 100}px !important;
|
||||||
|
height: ${contentSize.height + 100}px !important;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(sizeStyleElement);
|
||||||
|
|
||||||
|
// 等待样式应用
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
|
// 重置滚动位置
|
||||||
|
canvasWrapper.scrollLeft = 0;
|
||||||
|
canvasWrapper.scrollTop = 0;
|
||||||
|
|
||||||
|
// 等待布局更新
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200));
|
||||||
|
|
||||||
|
console.log('📸 Step 7: Capturing canvas...');
|
||||||
|
// @ts-ignore
|
||||||
|
const domToImage = require('dom-to-image-more');
|
||||||
|
|
||||||
|
const dataUrl = await domToImage.toPng(canvasDom, {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
quality: 1,
|
||||||
|
width: contentSize.width,
|
||||||
|
height: contentSize.height,
|
||||||
|
cacheBust: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const imageData = this.dataUrlToUint8Array(dataUrl);
|
||||||
|
|
||||||
|
console.log('✅ Capture successful!');
|
||||||
|
|
||||||
|
return imageData;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Native canvas capture failed:', error);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
// 清理临时调整大小的样式
|
||||||
|
if (sizeStyleElement && sizeStyleElement.parentNode) {
|
||||||
|
sizeStyleElement.parentNode.removeChild(sizeStyleElement);
|
||||||
|
console.log('🧹 Removed temporary resize styles');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uiStyleElement && uiStyleElement.parentNode) {
|
||||||
|
uiStyleElement.parentNode.removeChild(uiStyleElement);
|
||||||
|
console.log('🧹 Cleaned up UI hiding styles');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复滚动位置
|
||||||
|
if (canvasWrapper) {
|
||||||
|
canvasWrapper.scrollLeft = originalScrollLeft;
|
||||||
|
canvasWrapper.scrollTop = originalScrollTop;
|
||||||
|
console.log('🔄 Restored original scroll position');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🧹 Cleanup complete');
|
||||||
|
}
|
||||||
|
}
|
||||||
84
README.md
Normal file
84
README.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# VitePress Exporter - Obsidian Plugin
|
||||||
|
|
||||||
|
## 功能
|
||||||
|
|
||||||
|
这个 Obsidian 插件用于自动化发布 Obsidian 笔记到 VitePress 网站:
|
||||||
|
|
||||||
|
- ✅ 将当前 markdown 文件导出到 `docs/` 目录
|
||||||
|
- ✅ 自动复制引用的资源文件到 `docs/assets/` 目录
|
||||||
|
- ✅ 更新 markdown 中的资源路径
|
||||||
|
- 🚧 Canvas 文件渲染(待实现)
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
插件已经安装在这个项目的 `.obsidian/plugins/vitepress-exporter/` 目录下。
|
||||||
|
|
||||||
|
1. 在 Obsidian 中打开这个项目
|
||||||
|
2. 进入设置 → 第三方插件
|
||||||
|
3. 启用 "VitePress Exporter" 插件
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
### 方式 1:命令面板
|
||||||
|
1. 打开一个 markdown 文件
|
||||||
|
2. 按 `Ctrl+P` (或 `Cmd+P`) 打开命令面板
|
||||||
|
3. 输入 "Export to VitePress"
|
||||||
|
4. 选择 "Export current note to VitePress"
|
||||||
|
|
||||||
|
### 方式 2:功能区按钮
|
||||||
|
- 点击左侧功能区栏的上传图标按钮
|
||||||
|
|
||||||
|
### 方式 3:快捷键
|
||||||
|
- 可以在 Obsidian 的快捷键设置中为导出命令设置快捷键
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
在插件设置中可以配置:
|
||||||
|
|
||||||
|
- **Docs path**: 导出的 markdown 文件存放目录(默认:`docs`)
|
||||||
|
- **Assets path**: 资源文件存放目录(默认:`docs/assets`)
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
1. 用户在 Obsidian 中编写笔记
|
||||||
|
2. 笔记中引用的资源(图片、PDF 等)可以放在任意位置
|
||||||
|
3. 点击导出按钮
|
||||||
|
4. 插件自动:
|
||||||
|
- 将 markdown 文件复制到 `docs/` 目录
|
||||||
|
- 扫描并复制所有引用的资源到 `docs/assets/` 目录
|
||||||
|
- 更新 markdown 中的资源路径
|
||||||
|
|
||||||
|
## 当前状态
|
||||||
|
|
||||||
|
- ✅ 基础插件框架
|
||||||
|
- ✅ 文件导出功能
|
||||||
|
- ✅ 资源文件自动复制
|
||||||
|
- 🚧 Canvas 文件渲染(开发中)
|
||||||
|
|
||||||
|
## Canvas 渲染计划
|
||||||
|
|
||||||
|
对于 `.canvas` 文件,计划实现的方案:
|
||||||
|
|
||||||
|
1. **方案 A(优先)**:基于 Obsidian 自己的渲染(探索中)
|
||||||
|
2. **方案 B(备选)**:使用 Headless Browser 手动渲染 JSON Canvas
|
||||||
|
|
||||||
|
## 开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd .obsidian/plugins/vitepress-exporter
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 开发模式(自动重新编译)
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# 生产构建
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 确保项目中有 `docs/` 目录
|
||||||
|
- 资源文件会被复制,不会移动原文件
|
||||||
|
- 如果目标文件已存在,会被覆盖
|
||||||
19
docs/.vuepress/config.ts
Normal file
19
docs/.vuepress/config.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { defaultTheme } from '@vuepress/theme-default';
|
||||||
|
import type { DefaultThemeOptions } from '@vuepress/theme-default';
|
||||||
|
import type { PluginOptions } from 'vuepress';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'VitePress Demo',
|
||||||
|
description: 'Demo for VitePress with Canvas Viewer',
|
||||||
|
|
||||||
|
theme: defaultTheme<DefaultThemeOptions>({
|
||||||
|
navbar: [
|
||||||
|
{
|
||||||
|
text: 'Home',
|
||||||
|
link: '/',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
clientConfigFile: 'index.ts',
|
||||||
|
} satisfies PluginOptions;
|
||||||
8
docs/index.ts
Normal file
8
docs/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineClientConfig } from '@vuepress/client';
|
||||||
|
import { CanvasViewerPlugin } from './plugins/canvas-viewer';
|
||||||
|
|
||||||
|
export default defineClientConfig({
|
||||||
|
enhance({ app, router }) {
|
||||||
|
app.use(CanvasViewerPlugin);
|
||||||
|
}
|
||||||
|
});
|
||||||
7
docs/plugins/canvas-viewer.ts
Normal file
7
docs/plugins/canvas-viewer.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { Plugin } from 'vue';
|
||||||
|
|
||||||
|
export const CanvasViewerPlugin: Plugin = {
|
||||||
|
install(app) {
|
||||||
|
app.component('CanvasViewer', () => import('./components/CanvasViewer.vue'));
|
||||||
|
}
|
||||||
|
};
|
||||||
76
esbuild.config.mjs
Normal file
76
esbuild.config.mjs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import esbuild from "esbuild";
|
||||||
|
import process from "process";
|
||||||
|
import builtins from "builtin-modules";
|
||||||
|
|
||||||
|
const banner =
|
||||||
|
`/*
|
||||||
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||||
|
if you want to view the source, please visit the github repository of this plugin
|
||||||
|
*/
|
||||||
|
`;
|
||||||
|
|
||||||
|
const prod = (process.argv[2] === 'production');
|
||||||
|
|
||||||
|
if (prod) {
|
||||||
|
console.log('Building production bundle...');
|
||||||
|
await esbuild.build({
|
||||||
|
banner: {
|
||||||
|
js: banner,
|
||||||
|
},
|
||||||
|
entryPoints: ['main.ts'],
|
||||||
|
bundle: true,
|
||||||
|
external: [
|
||||||
|
'obsidian',
|
||||||
|
'electron',
|
||||||
|
'@codemirror/autocomplete',
|
||||||
|
'@codemirror/collab',
|
||||||
|
'@codemirror/commands',
|
||||||
|
'@codemirror/language',
|
||||||
|
'@codemirror/lint',
|
||||||
|
'@codemirror/search',
|
||||||
|
'@codemirror/state',
|
||||||
|
'@codemirror/view',
|
||||||
|
'@lezer/common',
|
||||||
|
'@lezer/highlight',
|
||||||
|
'@lezer/lr',
|
||||||
|
...builtins],
|
||||||
|
format: 'cjs',
|
||||||
|
target: 'es2018',
|
||||||
|
logLevel: "info",
|
||||||
|
sourcemap: false,
|
||||||
|
treeShaking: true,
|
||||||
|
outfile: 'main.js',
|
||||||
|
});
|
||||||
|
console.log('Production bundle built successfully!');
|
||||||
|
} else {
|
||||||
|
const ctx = await esbuild.context({
|
||||||
|
banner: {
|
||||||
|
js: banner,
|
||||||
|
},
|
||||||
|
entryPoints: ['main.ts'],
|
||||||
|
bundle: true,
|
||||||
|
external: [
|
||||||
|
'obsidian',
|
||||||
|
'electron',
|
||||||
|
'@codemirror/autocomplete',
|
||||||
|
'@codemirror/collab',
|
||||||
|
'@codemirror/commands',
|
||||||
|
'@codemirror/language',
|
||||||
|
'@codemirror/lint',
|
||||||
|
'@codemirror/search',
|
||||||
|
'@codemirror/state',
|
||||||
|
'@codemirror/view',
|
||||||
|
'@lezer/common',
|
||||||
|
'@lezer/highlight',
|
||||||
|
'@lezer/lr',
|
||||||
|
...builtins],
|
||||||
|
format: 'cjs',
|
||||||
|
target: 'es2018',
|
||||||
|
logLevel: "info",
|
||||||
|
sourcemap: 'inline',
|
||||||
|
treeShaking: true,
|
||||||
|
outfile: 'main.js',
|
||||||
|
});
|
||||||
|
|
||||||
|
await ctx.watch();
|
||||||
|
}
|
||||||
1145
main.ts.backup
Normal file
1145
main.ts.backup
Normal file
File diff suppressed because it is too large
Load Diff
10
manifest.json
Normal file
10
manifest.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"id": "vitepress-exporter",
|
||||||
|
"name": "VitePress Exporter",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"minAppVersion": "0.15.0",
|
||||||
|
"description": "Export Obsidian notes to VitePress with asset management",
|
||||||
|
"author": "Your Name",
|
||||||
|
"authorUrl": "https://github.com/yourusername",
|
||||||
|
"isDesktopOnly": false
|
||||||
|
}
|
||||||
2466
package-lock.json
generated
Normal file
2466
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
32
package.json
Normal file
32
package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "vitepress-exporter",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Export Obsidian notes to VitePress",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node esbuild.config.mjs",
|
||||||
|
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||||
|
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"obsidian",
|
||||||
|
"vitepress",
|
||||||
|
"export"
|
||||||
|
],
|
||||||
|
"author": "Your Name",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^16.11.6",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||||
|
"@typescript-eslint/parser": "5.29.0",
|
||||||
|
"builtin-modules": "3.3.0",
|
||||||
|
"dom-to-image-more": "^3.7.2",
|
||||||
|
"esbuild": "0.17.3",
|
||||||
|
"obsidian": "latest",
|
||||||
|
"tslib": "2.4.0",
|
||||||
|
"typescript": "4.7.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dom-to-image-more": "^3.7.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
1443
pnpm-lock.yaml
generated
Normal file
1443
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
92
puppeteer_version.txt
Normal file
92
puppeteer_version.txt
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// 尝试使用 Puppeteer 截图 Canvas(保留完整样式)
|
||||||
|
async tryNativeCanvasCapture(canvasFile: TFile): Promise<Uint8Array | null> {
|
||||||
|
let newWindowLeaf: any = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('🔍 Step 1: Opening canvas in new window...');
|
||||||
|
|
||||||
|
// 创建新窗口
|
||||||
|
newWindowLeaf = this.app.workspace.getLeaf('window');
|
||||||
|
if (!newWindowLeaf) {
|
||||||
|
console.log('❌ Failed to create new window');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ New window created, opening canvas file...');
|
||||||
|
await newWindowLeaf.openFile(canvasFile);
|
||||||
|
|
||||||
|
console.log('⏳ Step 2: Waiting for canvas render...');
|
||||||
|
// 等待 Canvas 渲染
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||||
|
|
||||||
|
console.log('📸 Step 3: Capturing with Puppeteer...');
|
||||||
|
// @ts-ignore
|
||||||
|
const puppeteer = require('puppeteer');
|
||||||
|
|
||||||
|
// 启动 Puppeteer
|
||||||
|
const browser = await puppeteer.launch({
|
||||||
|
headless: true,
|
||||||
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
// 获取新窗口的 HTML 内容
|
||||||
|
const container = newWindowLeaf.containerEl;
|
||||||
|
const canvasWrapper = container.querySelector('.canvas-wrapper');
|
||||||
|
|
||||||
|
if (!canvasWrapper) {
|
||||||
|
console.log('❌ Could not find canvas wrapper');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整的 HTML,包括所有样式
|
||||||
|
const htmlContent = canvasWrapper.outerHTML;
|
||||||
|
|
||||||
|
// 设置 HTML 内容
|
||||||
|
await page.setContent(htmlContent, {
|
||||||
|
waitUntil: 'networkidle0',
|
||||||
|
timeout: 10000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算内容尺寸
|
||||||
|
const contentSize = this.getCanvasContentSize(canvasWrapper);
|
||||||
|
const viewportWidth = Math.ceil(contentSize.width);
|
||||||
|
const viewportHeight = Math.ceil(contentSize.height);
|
||||||
|
|
||||||
|
console.log(`📸 Screenshot size: ${viewportWidth}x${viewportHeight}`);
|
||||||
|
|
||||||
|
// 截图
|
||||||
|
const screenshot = await page.screenshot({
|
||||||
|
type: 'png',
|
||||||
|
clip: {
|
||||||
|
x: contentSize.offsetX,
|
||||||
|
y: contentSize.offsetY,
|
||||||
|
width: contentSize.width,
|
||||||
|
height: contentSize.height
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('✅ Capture successful!');
|
||||||
|
return new Uint8Array(screenshot);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Puppeteer capture failed:', error);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
// 关闭新窗口
|
||||||
|
if (newWindowLeaf) {
|
||||||
|
try {
|
||||||
|
newWindowLeaf.detach();
|
||||||
|
console.log('🧹 Closed new window');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('⚠️ Could not close new window:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
tsconfig.json
Normal file
29
tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"inlineSourceMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"target": "ES6",
|
||||||
|
"allowJs": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"importHelpers": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"lib": [
|
||||||
|
"DOM",
|
||||||
|
"ES5",
|
||||||
|
"ES6",
|
||||||
|
"ES7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"docs",
|
||||||
|
"**/*.vue"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user