webpack update + loading prod files

This commit is contained in:
Elio Struyf
2024-09-19 12:57:39 +02:00
parent 0110b7365c
commit b9508df4f8
10 changed files with 167 additions and 57 deletions

83
package-lock.json generated
View File

@@ -32,6 +32,7 @@
"@types/react-datepicker": "^4.8.0",
"@types/react-dom": "17.0.0",
"@types/vscode": "^1.90.0",
"@types/webpack-bundle-analyzer": "^4.7.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vscode/l10n": "^0.0.14",
@@ -96,13 +97,14 @@
"uniforms-bridge-json-schema": "^3.10.2",
"uniforms-unstyled": "^3.10.2",
"url-join-ts": "^1.0.5",
"vscrui": "^0.1.0-beta.1092162",
"vscrui": "^0.1.0-beta.1093954",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.75.0",
"webpack-bundle-analyzer": "^4.7.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-ignore-dynamic-require": "^1.0.0",
"webpack-manifest-plugin": "^5.0.0",
"yaml": "^2.2.1",
"yawn-yaml": "^1.5.0"
},
@@ -2075,6 +2077,26 @@
"source-map": "^0.6.0"
}
},
"node_modules/@types/webpack-bundle-analyzer": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz",
"integrity": "sha512-c5i2ThslSNSG8W891BRvOd/RoCjI2zwph8maD22b1adtSns20j+0azDDMCK06DiVrzTgnwiDl5Ntmu1YRJw8Sg==",
"dev": true,
"dependencies": {
"@types/node": "*",
"tapable": "^2.2.0",
"webpack": "^5"
}
},
"node_modules/@types/webpack-bundle-analyzer/node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@types/webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.3.tgz",
@@ -11015,6 +11037,12 @@
"websocket-driver": "^0.7.4"
}
},
"node_modules/source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
"integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
"dev": true
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -12311,9 +12339,9 @@
}
},
"node_modules/vscrui": {
"version": "0.1.0-beta.1092162",
"resolved": "https://registry.npmjs.org/vscrui/-/vscrui-0.1.0-beta.1092162.tgz",
"integrity": "sha512-fEMEtNbGo96kZX+0mBDMFAFh9qMpzw6yHxEKT5/ujM6GqZ4fpqlW4GWzeA4jsdNJNPpyy/eW7uwjbPaYjXeQQw==",
"version": "0.1.0-beta.1093954",
"resolved": "https://registry.npmjs.org/vscrui/-/vscrui-0.1.0-beta.1093954.tgz",
"integrity": "sha512-ncAOeVL7b48yckb4qqXUTeHMaGmrcZrFo1Yuyq09t1qn4QPDQsWqfYTwuWupVjoEfnCVCWohj9kaGFSHz6xJ8Q==",
"dev": true,
"funding": {
"type": "github",
@@ -12415,9 +12443,9 @@
}
},
"node_modules/webpack-bundle-analyzer": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz",
"integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==",
"version": "4.10.2",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz",
"integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==",
"dev": true,
"dependencies": {
"@discoveryjs/json-ext": "0.5.7",
@@ -12428,7 +12456,6 @@
"escape-string-regexp": "^4.0.0",
"gzip-size": "^6.0.0",
"html-escaper": "^2.0.2",
"is-plain-object": "^5.0.0",
"opener": "^1.5.2",
"picocolors": "^1.0.0",
"sirv": "^2.0.3",
@@ -12653,6 +12680,44 @@
"integrity": "sha512-WeGFPgwDochKPwizAu5XsHcPq3aaQLl2E+n1piD/VPGNUo5HIwrtURWNMfrPDfkHVOx+flkAihXbUiILAv5x4Q==",
"dev": true
},
"node_modules/webpack-manifest-plugin": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-5.0.0.tgz",
"integrity": "sha512-8RQfMAdc5Uw3QbCQ/CBV/AXqOR8mt03B6GJmRbhWopE8GzRfEpn+k0ZuWywxW+5QZsffhmFDY1J6ohqJo+eMuw==",
"dev": true,
"dependencies": {
"tapable": "^2.0.0",
"webpack-sources": "^2.2.0"
},
"engines": {
"node": ">=12.22.0"
},
"peerDependencies": {
"webpack": "^5.47.0"
}
},
"node_modules/webpack-manifest-plugin/node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/webpack-manifest-plugin/node_modules/webpack-sources": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz",
"integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==",
"dev": true,
"dependencies": {
"source-list-map": "^2.0.1",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/webpack-merge": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",

View File

@@ -2853,6 +2853,7 @@
"@types/react-datepicker": "^4.8.0",
"@types/react-dom": "17.0.0",
"@types/vscode": "^1.90.0",
"@types/webpack-bundle-analyzer": "^4.7.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vscode/l10n": "^0.0.14",
@@ -2917,13 +2918,14 @@
"uniforms-bridge-json-schema": "^3.10.2",
"uniforms-unstyled": "^3.10.2",
"url-join-ts": "^1.0.5",
"vscrui": "^0.1.0-beta.1092162",
"vscrui": "^0.1.0-beta.1093954",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.75.0",
"webpack-bundle-analyzer": "^4.7.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-ignore-dynamic-require": "^1.0.0",
"webpack-manifest-plugin": "^5.0.0",
"yaml": "^2.2.1",
"yawn-yaml": "^1.5.0"
},

View File

@@ -6,6 +6,7 @@ import { WebviewHelper } from '@estruyf/vscode';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { getWebviewJsFiles } from '../utils';
export class Chatbot {
/**
@@ -56,7 +57,7 @@ export class Chatbot {
}
});
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
@@ -66,7 +67,6 @@ export class Chatbot {
const isProd = ext.isProductionMode;
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
@@ -82,13 +82,11 @@ export class Chatbot {
}`
];
let scriptUri = '';
let scriptUris = [];
if (isProd) {
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView.webview);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
// By default, the chatbot is seen as experimental
@@ -111,7 +109,11 @@ export class Chatbot {
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`chatbot-${version.installedVersion}`}" alt="Daily usage" />
</body>
</html>
`;

View File

@@ -30,7 +30,7 @@ import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { DashboardMessage } from '../dashboardWebView/DashboardMessage';
import { NavigationType } from '../dashboardWebView/models';
import { getExtensibilityScripts, ignoreMsgCommand } from '../utils';
import { getExtensibilityScripts, getWebviewJsFiles, ignoreMsgCommand } from '../utils';
export class Dashboard {
private static webview: WebviewPanel | null = null;
@@ -274,18 +274,17 @@ export class Dashboard {
* @param webView
*/
private static async getWebviewContent(webView: Webview, extensionPath: Uri): Promise<string> {
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
let scriptUri = '';
const isProd = Extension.getInstance().isProductionMode;
let scriptUris = [];
if (isProd) {
scriptUri = webView
.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
const nonce = WebviewHelper.getNonce();
@@ -351,7 +350,9 @@ export class Dashboard {
})
.join('')}
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`dashboard-${version.installedVersion}`}" alt="Daily usage" />
</body>

View File

@@ -29,7 +29,7 @@ import { ParsedFrontMatter } from '../parsers';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { getTitleField, joinUrl } from '../utils';
import { getTitleField, getWebviewJsFiles, joinUrl } from '../utils';
import { i18n } from './i18n';
export class Preview {
@@ -134,7 +134,7 @@ export class Preview {
}
});
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
@@ -144,7 +144,6 @@ export class Preview {
const isProd = ext.isProductionMode;
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
@@ -161,13 +160,11 @@ export class Preview {
`frame-src ${localhostUrl} ${cspSource} http: https:;`
];
let scriptUri = '';
let scriptUris = [];
if (isProd) {
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView.webview);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
// Get experimental setting
@@ -193,7 +190,11 @@ export class Preview {
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`preview-${version.installedVersion}`}" alt="Daily usage" />
</body>
</html>
`;

View File

@@ -28,7 +28,7 @@ import { Extension } from '../helpers/Extension';
import { Telemetry } from '../helpers/Telemetry';
import { GitListener, ModeListener } from '../listeners/general';
import { basename } from 'path';
import { getExtensibilityScripts, ignoreMsgCommand } from '../utils';
import { getExtensibilityScripts, getWebviewJsFiles, ignoreMsgCommand } from '../utils';
export class PanelProvider implements WebviewViewProvider, Disposable {
public static readonly viewType = 'frontMatter.explorer';
@@ -89,7 +89,7 @@ export class PanelProvider implements WebviewViewProvider, Disposable {
enableCommandUris: true
};
webviewView.webview.html = this.getWebviewContent(webviewView.webview);
webviewView.webview.html = await this.getWebviewContent(webviewView.webview);
this.disposable = Disposable.from(
webviewView.onDidDispose(() => {
@@ -206,12 +206,11 @@ export class PanelProvider implements WebviewViewProvider, Disposable {
* Retrieve the webview HTML contents
* @param webView
*/
private getWebviewContent(webView: Webview): string {
private async getWebviewContent(webView: Webview): Promise<string> {
const ext = Extension.getInstance();
const dashboardFile = 'panelWebView.js';
const webviewFile = 'panel.main.js';
const localPort = `9001`;
const localServerUrl = `localhost:${localPort}`;
const extensionPath = ext.extensionPath;
const styleVSCodeUri = webView.asWebviewUri(
Uri.joinPath(this.extPath, 'assets/media', 'vscode.css')
@@ -228,14 +227,12 @@ export class PanelProvider implements WebviewViewProvider, Disposable {
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
let scriptUri = '';
const isProd = Extension.getInstance().isProductionMode;
let scriptUris = [];
if (isProd) {
scriptUri = webView
.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('panel', webView);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
// Get experimental setting
@@ -252,7 +249,7 @@ export class PanelProvider implements WebviewViewProvider, Disposable {
isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`
}`,
`style-src ${webView.cspSource} 'self' 'unsafe-inline' https://*`,
`font-src ${webView.cspSource}`,
`font-src ${webView.cspSource} data:;`,
`connect-src https://o1022172.ingest.sentry.io https://* ${
isProd
? ``
@@ -285,7 +282,9 @@ export class PanelProvider implements WebviewViewProvider, Disposable {
})
.join('')}
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<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" />
</body>

View File

@@ -0,0 +1,17 @@
import { readFileAsync } from './readFileAsync';
import { Uri, Webview } from 'vscode';
import { Extension } from '../helpers';
export const getWebviewJsFiles = async (name: string, webview: Webview) => {
const context = Extension.getInstance();
const extensionPath = context.extensionPath;
const webviewFolder = Uri.joinPath(extensionPath, 'dist');
const manifestPath = Uri.joinPath(webviewFolder, `${name}.manifest.json`);
const manifest = await readFileAsync(manifestPath.fsPath, 'utf8');
const manifestJson = JSON.parse(manifest);
const entries = Object.entries<string>(manifestJson).filter(([key]) => key.endsWith('.js'));
const files = entries.map(([_, value]) =>
webview.asWebviewUri(Uri.joinPath(webviewFolder, value)).toString()
);
return files;
};

View File

@@ -9,6 +9,7 @@ export * from './getDescriptionField';
export * from './getExtensibilityScripts';
export * from './getLocalizationFile';
export * from './getTitleField';
export * from './getWebviewJsFiles';
export * from './ignoreMsgCommand';
export * from './isWindows';
export * from './joinUrl';

View File

@@ -1,5 +1,3 @@
//@ts-check
'use strict';
const path = require('path');
@@ -7,13 +5,15 @@ const {
ProvidePlugin
} = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const WebpackManifestPlugin = require('webpack-manifest-plugin').WebpackManifestPlugin;
const config = [{
name: 'dashboard',
target: 'web',
entry: './src/dashboardWebView/index.tsx',
output: {
filename: 'dashboardWebView.js',
filename: 'dashboard.[name].js',
chunkFilename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist')
},
devtool: 'source-map',
@@ -81,6 +81,17 @@ module.exports = (env, argv) => {
reportFilename: "dashboard.html",
openAnalyzer: false
}));
configItem.plugins.push(new WebpackManifestPlugin({
publicPath: "",
fileName: "dashboard.manifest.json"
}));
configItem.optimization = {
splitChunks: {
chunks: 'all',
},
};
}
}

View File

@@ -1,22 +1,22 @@
//@ts-check
'use strict';
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const WebpackManifestPlugin = require('webpack-manifest-plugin').WebpackManifestPlugin;
const config = [{
name: 'panel',
target: 'web',
entry: './src/panelWebView/index.tsx',
output: {
filename: 'panelWebView.js',
filename: 'panel.[name].js',
chunkFilename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist')
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.tsx', '.jsx'],
fallback: {
fallback: {
"path": require.resolve("path-browserify")
}
},
@@ -73,7 +73,7 @@ const config = [{
if (error.message === "ResizeObserver loop limit exceeded") {
return false;
}
return true;
}
}
@@ -87,12 +87,23 @@ module.exports = (env, argv) => {
if (argv.mode === 'production') {
configItem.devtool = "hidden-source-map";
configItem.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: "viewpanel.html",
openAnalyzer: false
}));
configItem.plugins.push(new WebpackManifestPlugin({
publicPath: "",
fileName: "panel.manifest.json"
}));
configItem.optimization = {
splitChunks: {
chunks: 'all',
},
};
}
}