我創建了一個使用Webview的 VS Code 擴展。在 Webview 中,我有一個指向檔案node_modules夾中檔案的鏈接,我按照各種來源(例如vscode-codicons-sample)的建議將其添加到 html 中:
const codiconsUri = webview.asWebviewUri(
Uri.joinPath(this.context.extensionUri, 'node_modules', '@vscode/codicons', 'dist', 'codicon.css')
);
并在 html 中:
<link href="${codiconsUri}" rel="stylesheet" />
現在我想使用 webpack 進行捆綁。我按照這里的Visual Studio Code 的說明進行操作。
在.vscodeignore檔案中,我node_modules按照說明排除了檔案夾。(這是捆綁的主要原因)
當然,當我現在打包專案時,node_modules.vsix 檔案中不存在 ,因此 Uri 無效。
你會怎么解決呢?(我使用這種方法插入了除代碼之外的更多鏈接)
提前致謝!
uj5u.com熱心網友回復:
我決定采納@MikeLischke 的建議,并將所需檔案復制到dist打包的檔案夾中。但我不想手動完成,所以我做了以下作業。
節點模塊訪問器
首先,我創建了一個類,它在檔案node_modules夾中的檔案和打包dist檔案夾中的目標之間進行映射。
import { NodeModulesKeys } from './nodeModulesKeys';
import { NodeModulesValue } from './nodeModulesValue';
export class NodeModulesAccessor {
static readonly outputPath = 'dist';
private static readonly pathMapping = new Map<NodeModulesKeys, NodeModulesValue>([
[
NodeModulesKeys.ffmpegMinJs,
{
sourcePath: ['node_modules', '@ffmpeg', 'ffmpeg', 'dist'],
destinationPath: ['libs', '@ffmpeg', 'ffmpeg', 'dist'],
fileName: 'ffmpeg.min.js',
},
],
[
NodeModulesKeys.ffmpegCoreJs,
{
sourcePath: ['node_modules', '@ffmpeg', 'core', 'dist'],
destinationPath: ['libs', '@ffmpeg', 'core', 'dist'],
fileName: 'ffmpeg-core.js',
includeFolder: true,
},
],
[
NodeModulesKeys.codiconCss,
{
sourcePath: ['node_modules', '@vscode', 'codicons', 'dist'],
destinationPath: ['libs', '@vscode', 'codicons', 'dist'],
fileName: 'codicon.css',
includeFolder: true,
},
],
]);
static getPathToOutputFile(key: NodeModulesKeys): string[] {
const path = this.getMappedValue(key);
return [this.outputPath, ...path.destinationPath, path.fileName];
}
static getPathToNodeModulesFile(key: NodeModulesKeys): NodeModulesValue {
return this.getMappedValue(key);
}
private static getMappedValue(key: NodeModulesKeys): NodeModulesValue {
const value = this.pathMapping.get(key);
if (!value) {
throw Error(`Path to "${key}" is not mapped.`);
}
return value;
}
}
NodeModulesKeys 是我要使用的所有檔案的簡單列舉:
export enum NodeModulesKeys {
ffmpegMinJs,
ffmpegCoreJs,
codiconCss,
}
并且NodeModulesValue是一個介面:
export interface NodeModulesValue {
sourcePath: string[];
destinationPath: string[];
fileName: string;
includeFolder?: boolean;
}
一些庫(例如代碼檔案)需要檔案夾內的多個檔案。這就是為什么NodeModulesValue有一個可選欄位includeFolder。
webpack.config.ts
這就是魔法發生的地方(別擔心,沒那么復雜)。
您可以使用CopyWebpackPlugin在打包時復制檔案:
import * as path from 'path';
import { NodeModulesAccessor } from './src/node-modules-accessor/nodeModulesAccessor';
import { NodeModulesKeys } from './src/node-modules-accessor/nodeModulesKeys';
import { Configuration } from 'webpack';
import CopyPlugin = require('copy-webpack-plugin');
const config: Configuration = {
// omitted, nothing special here
plugins: [copyNodeModulesFiles()],
};
function copyNodeModulesFiles(): CopyPlugin {
const files: NodeModulesKeys[] = Object.keys(NodeModulesKeys)
.filter((key) => !isNaN(Number(key)))
.map((key) => Number(key));
const copies: CopyPlugin.ObjectPattern[] = files.map((file) => {
const value = NodeModulesAccessor.getPathToNodeModulesFile(file);
let sourcePath;
let destinationPath;
if (value.includeFolder) {
sourcePath = path.join(...value.sourcePath);
destinationPath = path.join(...value.destinationPath);
} else {
sourcePath = path.join(...value.sourcePath, value.fileName);
destinationPath = path.join(...value.destinationPath, value.fileName);
}
return {
from: sourcePath,
to: destinationPath,
};
});
return new CopyPlugin({
patterns: copies,
});
}
module.exports = config;
在這里,我們遍歷NodeModulesKeys列舉的所有值。(如何迭代列舉值)并為每個值添加復制指令。
如果需要,我們也可以復制整個檔案夾。
網路視圖集成
為了獲取 Uris 并在 webview html 中使用它們,我們NodeModulesAccessor再次使用。
const codiconsUri = webview.asWebviewUri(
Uri.joinPath(this.context.extensionUri, ...NodeModulesAccessor.getPathToOutputFile(NodeModulesKeys.codiconCss))
);
重要的
為了讓 webview 能夠訪問該dist/libs目錄,您localResourceRoot在創建 webview 時已將目錄定義為 a :
this.viewPanel = window.createWebviewPanel('sampleId', 'Sample Webview', ViewColumn.Beside, {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [
Uri.joinPath(this.context.extensionUri, NodeModulesAccessor.outputPath, 'libs'), // <--- Important
Uri.joinPath(this.context.extensionUri, 'media'),
],
});
我希望這對其他人有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/364652.html
