mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-05-06 13:32:30 +02:00
HMR support for panel development
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### 🎨 Enhancements
|
||||
|
||||
- Added default field value for content type fields
|
||||
- HMR support for panel webview development
|
||||
- [#197](https://github.com/estruyf/vscode-front-matter/issues/197): Support for multi-dimensional content type fields on content creation and editing.
|
||||
|
||||
## [5.10.0] - 2022-01-10
|
||||
|
||||
@@ -1185,10 +1185,13 @@
|
||||
"build:ext": "npm run clean && npm-run-all --parallel dev:build:*",
|
||||
"watch:ext": "webpack --mode development --watch --config ./webpack/extension.config.js",
|
||||
"watch:dashboard": "webpack serve --mode development --config ./webpack/dashboard.config.js",
|
||||
"watch:panel": "webpack serve --mode development --config ./webpack/panel.config.js",
|
||||
"dev:build:ext": "webpack --mode development --config ./webpack/extension.config.js",
|
||||
"dev:build:dashboard": "webpack --mode development --config ./webpack/dashboard.config.js",
|
||||
"dev:build:panel": "webpack --mode development --config ./webpack/panel.config.js",
|
||||
"prod:ext": "webpack --mode production --config ./webpack/extension.config.js",
|
||||
"prod:dashboard": "webpack --mode production --config ./webpack/dashboard.config.js",
|
||||
"prod:panel": "webpack --mode production --config ./webpack/panel.config.js",
|
||||
"test-compile": "tsc -p ./",
|
||||
"clean": "rimraf dist",
|
||||
"start:site": "cd ./docs && npm run dev"
|
||||
|
||||
@@ -175,14 +175,15 @@ export class Dashboard {
|
||||
*/
|
||||
private static getWebviewContent(webView: Webview, extensionPath: Uri): string {
|
||||
const dashboardFile = "dashboardWebView.js";
|
||||
const localServerUrl = "http://localhost:9000";
|
||||
const localPort = `9000`;
|
||||
const localServerUrl = `localhost:${localPort}`;
|
||||
|
||||
let scriptUri = "";
|
||||
const isProd = Extension.getInstance().isProductionMode;
|
||||
if (isProd) {
|
||||
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
|
||||
} else {
|
||||
scriptUri = `${localServerUrl}/${dashboardFile}`;
|
||||
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
|
||||
}
|
||||
|
||||
const nonce = WebviewHelper.getNonce();
|
||||
@@ -194,10 +195,10 @@ export class Dashboard {
|
||||
const csp = [
|
||||
`default-src 'none';`,
|
||||
`img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'`,
|
||||
`script-src ${isProd ? `'nonce-${nonce}'` : "http://localhost:9000 http://0.0.0.0:9000"}`,
|
||||
`script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`}`,
|
||||
`style-src ${webView.cspSource} 'self' 'unsafe-inline'`,
|
||||
`font-src ${webView.cspSource}`,
|
||||
`connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : "ws://localhost:9000 ws://0.0.0.0:9000 http://localhost:9000 http://0.0.0.0:9000"}`
|
||||
`connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`
|
||||
];
|
||||
|
||||
return `
|
||||
|
||||
@@ -194,8 +194,6 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
|
||||
const extension = fileInfo?.pop();
|
||||
const name = fileInfo?.join('.');
|
||||
|
||||
console.log(viewData?.data)
|
||||
|
||||
return (
|
||||
<>
|
||||
<li className="group relative bg-gray-50 dark:bg-vulcan-200 hover:shadow-xl dark:hover:bg-vulcan-100 border border-gray-100 dark:border-vulcan-50">
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Command } from "../panelWebView/Command";
|
||||
import { CommandToCode } from '../panelWebView/CommandToCode';
|
||||
import { Article } from '../commands';
|
||||
import { TagType } from '../panelWebView/TagType';
|
||||
import { ContentType, CustomTaxonomyData, DraftField, Field, ScriptType, TaxonomyType } from '../models';
|
||||
import { CustomTaxonomyData, DraftField, Field, ScriptType, TaxonomyType } from '../models';
|
||||
import { exec } from 'child_process';
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown';
|
||||
import { Content } from 'mdast';
|
||||
@@ -737,35 +737,56 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
* @param webView
|
||||
*/
|
||||
private getWebviewContent(webView: Webview): string {
|
||||
const ext = Extension.getInstance();
|
||||
const dashboardFile = "panelWebView.js";
|
||||
const localPort = `9001`;
|
||||
const localServerUrl = `localhost:${localPort}`;
|
||||
const extensionPath = ext.extensionPath;
|
||||
|
||||
const styleVSCodeUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'vscode.css'));
|
||||
const styleResetUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'reset.css'));
|
||||
const stylesUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'styles.css'));
|
||||
const scriptUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'dist', 'panelWebView.js'));
|
||||
|
||||
const nonce = WebviewHelper.getNonce();
|
||||
|
||||
const ext = Extension.getInstance();
|
||||
const version = ext.getVersion();
|
||||
const isBeta = ext.isBetaVersion();
|
||||
|
||||
let scriptUri = "";
|
||||
const isProd = Extension.getInstance().isProductionMode;
|
||||
if (isProd) {
|
||||
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
|
||||
} else {
|
||||
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
|
||||
}
|
||||
|
||||
const csp = [
|
||||
`default-src 'none';`,
|
||||
`img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'`,
|
||||
`script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`}`,
|
||||
`style-src ${webView.cspSource} 'self' 'unsafe-inline'`,
|
||||
`font-src ${webView.cspSource}`,
|
||||
`connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`
|
||||
];
|
||||
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'; script-src 'nonce-${nonce}'; style-src ${webView.cspSource} 'self' 'unsafe-inline'; font-src ${webView.cspSource}; connect-src https://o1022172.ingest.sentry.io">
|
||||
<meta http-equiv="Content-Security-Policy" content="${csp.join('; ')}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="${styleResetUri}" rel="stylesheet">
|
||||
<link href="${styleVSCodeUri}" rel="stylesheet">
|
||||
<link href="${stylesUri}" rel="stylesheet">
|
||||
|
||||
<title>Front Matter</title>
|
||||
<title>Front Matter Panel</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" data-environment="${isBeta ? "BETA" : "main"}" data-version="${version.usedVersion}" ></div>
|
||||
<div id="app" data-isProd="${isProd}" data-environment="${isBeta ? "BETA" : "main"}" data-version="${version.usedVersion}" ></div>
|
||||
|
||||
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`panel-${version.installedVersion}`}" alt="Daily usage" />
|
||||
|
||||
<script nonce="${nonce}" src="${scriptUri}"></script>
|
||||
<script ${isProd ? `nonce="${nonce}"` : ""} src="${scriptUri}"></script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
@@ -38,8 +38,6 @@ export const PreviewImageField: React.FunctionComponent<IPreviewImageFieldProps>
|
||||
onChange(newValue);
|
||||
}
|
||||
|
||||
console.log(fieldName, value, filePath, parents)
|
||||
|
||||
return (
|
||||
<div className={`metadata_field`}>
|
||||
<VsLabel>
|
||||
|
||||
@@ -243,7 +243,7 @@ const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, metadata,
|
||||
|
||||
return (
|
||||
<Collapsible id={`tags`} title="Metadata" className={`inherit z-20`}>
|
||||
|
||||
|
||||
{
|
||||
renderFields(contentType?.fields, metadata)
|
||||
}
|
||||
|
||||
@@ -18,23 +18,32 @@ import '@bendera/vscode-webview-elements/dist/vscode-checkbox.js';
|
||||
|
||||
// import '@vscode/webview-ui-toolkit/dist/esm/checkbox';
|
||||
|
||||
const elm = document.querySelector("#app");
|
||||
const version = elm?.getAttribute("data-version");
|
||||
const environment = elm?.getAttribute("data-environment");
|
||||
|
||||
Sentry.init({
|
||||
dsn: SENTRY_LINK,
|
||||
integrations: [new Integrations.BrowserTracing()],
|
||||
tracesSampleRate: 0, // No performance tracing required
|
||||
release: version || "",
|
||||
environment: environment || "",
|
||||
ignoreErrors: ['ResizeObserver loop limit exceeded']
|
||||
});
|
||||
|
||||
declare const acquireVsCodeApi: <T = unknown>() => {
|
||||
getState: () => T;
|
||||
setState: (data: T) => void;
|
||||
postMessage: (msg: unknown) => void;
|
||||
};
|
||||
|
||||
render(<ViewPanel />, elm);
|
||||
const elm = document.querySelector("#app");
|
||||
|
||||
if (elm) {
|
||||
const version = elm?.getAttribute("data-version");
|
||||
const environment = elm?.getAttribute("data-environment");
|
||||
const isProd = elm?.getAttribute("data-isProd");
|
||||
|
||||
if (isProd === "true") {
|
||||
Sentry.init({
|
||||
dsn: SENTRY_LINK,
|
||||
integrations: [new Integrations.BrowserTracing()],
|
||||
tracesSampleRate: 0, // No performance tracing required
|
||||
release: version || "",
|
||||
environment: environment || "",
|
||||
ignoreErrors: ['ResizeObserver loop limit exceeded']
|
||||
});
|
||||
}
|
||||
|
||||
render(<ViewPanel />, elm);
|
||||
}
|
||||
|
||||
// Webpack HMR
|
||||
if ((module as any).hot) (module as any).hot.accept();
|
||||
@@ -38,13 +38,7 @@ const config = [
|
||||
maxEntrypointSize: 400000,
|
||||
maxAssetSize: 400000
|
||||
},
|
||||
plugins: [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "dashboard.html",
|
||||
openAnalyzer: false
|
||||
})
|
||||
],
|
||||
plugins: [],
|
||||
devServer: {
|
||||
compress: true,
|
||||
port: 9000,
|
||||
@@ -60,6 +54,14 @@ const config = [
|
||||
module.exports = (env, argv) => {
|
||||
for (const configItem of config) {
|
||||
configItem.mode = argv.mode;
|
||||
|
||||
if (argv.mode === 'production') {
|
||||
configItem.plugins.push(new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "dashboard.html",
|
||||
openAnalyzer: false
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
@@ -56,78 +56,21 @@ const config = [
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "extension.html",
|
||||
openAnalyzer: false
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'panelWebView',
|
||||
target: 'web',
|
||||
entry: './src/panelWebView/index.tsx',
|
||||
output: {
|
||||
filename: 'panelWebView.js',
|
||||
path: path.resolve(__dirname, '../dist')
|
||||
},
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
loader: 'ts-loader'
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 400000,
|
||||
maxAssetSize: 400000
|
||||
},
|
||||
// optimization: {
|
||||
// splitChunks: {
|
||||
// cacheGroups: {
|
||||
// vendors: {
|
||||
// test: /node_modules/,
|
||||
// chunks: 'initial',
|
||||
// filename: 'vendors.[contenthash].js',
|
||||
// priority: 1,
|
||||
// maxInitialRequests: 2, // create only one vendor file
|
||||
// minChunks: 1,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
plugins: [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "viewpanel.html",
|
||||
openAnalyzer: false
|
||||
})
|
||||
]
|
||||
plugins: []
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
for (const configItem of config) {
|
||||
configItem.mode = argv.mode;
|
||||
|
||||
if (argv.mode === 'production') {
|
||||
configItem.plugins.push(new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "extension.html",
|
||||
openAnalyzer: false
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
72
webpack/panel.config.js
Normal file
72
webpack/panel.config.js
Normal file
@@ -0,0 +1,72 @@
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
|
||||
const config = [{
|
||||
name: 'panel',
|
||||
target: 'web',
|
||||
entry: './src/panelWebView/index.tsx',
|
||||
output: {
|
||||
filename: 'panelWebView.js',
|
||||
path: path.resolve(__dirname, '../dist')
|
||||
},
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', '.tsx', '.jsx'],
|
||||
fallback: { "path": require.resolve("path-browserify") }
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
loader: 'ts-loader'
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 400000,
|
||||
maxAssetSize: 400000
|
||||
},
|
||||
plugins: [],
|
||||
devServer: {
|
||||
compress: true,
|
||||
port: 9001,
|
||||
hot: true,
|
||||
allowedHosts: "all",
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
for (const configItem of config) {
|
||||
configItem.mode = argv.mode;
|
||||
|
||||
if (argv.mode === 'production') {
|
||||
configItem.plugins.push(new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
reportFilename: "viewpanel.html",
|
||||
openAnalyzer: false
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
Reference in New Issue
Block a user