diff --git a/CHANGELOG.md b/CHANGELOG.md index 35434156..2256c53e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/package.json b/package.json index 72dd3416..5dd18699 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index a54e89f4..5ae6603a 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -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 ` diff --git a/src/dashboardWebView/components/Media/Item.tsx b/src/dashboardWebView/components/Media/Item.tsx index 3e837db6..22dc9d76 100644 --- a/src/dashboardWebView/components/Media/Item.tsx +++ b/src/dashboardWebView/components/Media/Item.tsx @@ -194,8 +194,6 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi const extension = fileInfo?.pop(); const name = fileInfo?.join('.'); - console.log(viewData?.data) - return ( <>
  • diff --git a/src/explorerView/ExplorerView.ts b/src/explorerView/ExplorerView.ts index e1d9f8f6..ff886207 100644 --- a/src/explorerView/ExplorerView.ts +++ b/src/explorerView/ExplorerView.ts @@ -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 ` - + - Front Matter + Front Matter Panel -
    +
    Daily usage - + `; diff --git a/src/panelWebView/components/Fields/PreviewImageField.tsx b/src/panelWebView/components/Fields/PreviewImageField.tsx index e6b45ecb..11100645 100644 --- a/src/panelWebView/components/Fields/PreviewImageField.tsx +++ b/src/panelWebView/components/Fields/PreviewImageField.tsx @@ -38,8 +38,6 @@ export const PreviewImageField: React.FunctionComponent onChange(newValue); } - console.log(fieldName, value, filePath, parents) - return (
    diff --git a/src/panelWebView/components/Metadata.tsx b/src/panelWebView/components/Metadata.tsx index 8cd1bd03..43f23a34 100644 --- a/src/panelWebView/components/Metadata.tsx +++ b/src/panelWebView/components/Metadata.tsx @@ -243,7 +243,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata, return ( - + { renderFields(contentType?.fields, metadata) } diff --git a/src/panelWebView/index.tsx b/src/panelWebView/index.tsx index 4452e418..360f5120 100644 --- a/src/panelWebView/index.tsx +++ b/src/panelWebView/index.tsx @@ -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: () => { getState: () => T; setState: (data: T) => void; postMessage: (msg: unknown) => void; }; -render(, 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(, elm); +} + +// Webpack HMR +if ((module as any).hot) (module as any).hot.accept(); \ No newline at end of file diff --git a/webpack/dashboard.config.js b/webpack/dashboard.config.js index 17bdd2e1..688ade97 100644 --- a/webpack/dashboard.config.js +++ b/webpack/dashboard.config.js @@ -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; diff --git a/webpack/extension.config.js b/webpack/extension.config.js index 5323f3bc..80b7b250 100644 --- a/webpack/extension.config.js +++ b/webpack/extension.config.js @@ -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; diff --git a/webpack/panel.config.js b/webpack/panel.config.js new file mode 100644 index 00000000..a248ed37 --- /dev/null +++ b/webpack/panel.config.js @@ -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; +}; \ No newline at end of file