addons/vscode/vite.config.mtsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {Plugin, PluginOption} from 'vite';
b69ab319
b69ab3110import react from '@vitejs/plugin-react';
b69ab3111import fs, {existsSync} from 'node:fs';
b69ab3112import path from 'node:path';
b69ab3113import {defineConfig} from 'vite';
b69ab3114import styleX from 'vite-plugin-stylex';
b69ab3115import viteTsconfigPaths from 'vite-tsconfig-paths';
b69ab3116
b69ab3117// Normalize `c:\foo\index.html` to `c:/foo/index.html`.
b69ab3118// This affects Rollup's `facadeModuleId` (which expects the `c:/foo/bar` format),
b69ab3119// and is important for Vite to replace the script tags in HTML files.
b69ab3120// See https://github.com/vitejs/vite/blob/7440191715b07a50992fcf8c90d07600dffc375e/packages/vite/src/node/plugins/html.ts#L804
b69ab3121// Without this, building on Windows might produce HTML entry points with
b69ab3122// missing `<script>` tags, resulting in a blank page.
b69ab3123function normalizeInputPath(inputPath: string) {
b69ab3124 return process.platform === 'win32' ? path.resolve(inputPath).replace(/\\/g, '/') : inputPath;
b69ab3125}
b69ab3126
b69ab3127const isInternal = existsSync(path.resolve(__dirname, 'facebook/README.facebook.md'));
b69ab3128
b69ab3129const input = [normalizeInputPath('webview.html')];
b69ab3130if (isInternal) {
b69ab3131 // Currently, the inline comment webview is not used in OSS
b69ab3132 input.push(normalizeInputPath('inlineCommentWebview.html'));
b69ab3133 input.push(normalizeInputPath('DiffCommentPanelWebview.html'));
b69ab3134 input.push(normalizeInputPath('InlineCommentPanelWebview.html'));
b69ab3135}
b69ab3136
b69ab3137console.log(isInternal ? 'Building internal version' : 'Building OSS version');
b69ab3138
b69ab3139// vite-plugin-stylex doesn't support renaming the output CSS file, so we have to do that ourselves.
b69ab3140function moveStylexFilenamePlugin(): Plugin {
b69ab3141 return {
b69ab3142 name: 'move-stylex-filename',
b69ab3143 writeBundle(options, bundle) {
b69ab3144 for (const name in bundle) {
b69ab3145 const chunk = bundle[name];
b69ab3146 // Check if this is the stylex output cssfile
b69ab3147 if (chunk.type === 'asset' && /assets[/\\]stylex\.[a-f0-9]+\.css/.test(chunk.fileName)) {
b69ab3148 // Rename the file, move it from "assets" to "res" where the rest of our assets are
b69ab3149 const newName = 'res/stylex.css';
b69ab3150 if (options.dir == null) {
b69ab3151 this.error('Could not replace StyleX output, dir must be set');
b69ab3152 }
b69ab3153 const dir = options.dir as string;
b69ab3154 const oldPath = path.resolve(dir, chunk.fileName);
b69ab3155 const newPath = path.resolve(dir, newName);
b69ab3156 this.info(`Replacing StyleX output file ${chunk.fileName} with ${newName}`);
b69ab3157 fs.renameSync(oldPath, newPath);
b69ab3158 // Update the bundle object
b69ab3159 chunk.fileName = newName;
b69ab3160 bundle[newName] = chunk;
b69ab3161 delete bundle[name];
b69ab3162 }
b69ab3163 }
b69ab3164 },
b69ab3165 };
b69ab3166}
b69ab3167
b69ab3168const replaceFiles = (
b69ab3169 replacements?: Array<{
b69ab3170 file: string;
b69ab3171 replacement: string;
b69ab3172 }>,
b69ab3173): PluginOption => {
b69ab3174 const projectRoot = process.cwd();
b69ab3175 replacements = replacements?.map(x => ({
b69ab3176 file: path.join(projectRoot, x.file),
b69ab3177 replacement: path.join(projectRoot, x.replacement),
b69ab3178 }));
b69ab3179
b69ab3180 return {
b69ab3181 name: 'vite-plugin-replace-files',
b69ab3182 enforce: 'pre',
b69ab3183 async resolveId(source: string, importer: string | undefined, options: any) {
b69ab3184 const resolvedFile = await this.resolve(source, importer, {
b69ab3185 ...options,
b69ab3186 ...{skipSelf: true},
b69ab3187 });
b69ab3188
b69ab3189 const foundReplacementFile = replacements?.find(
b69ab3190 replacement => replacement.file == resolvedFile?.id,
b69ab3191 );
b69ab3192
b69ab3193 if (foundReplacementFile) {
b69ab3194 return {
b69ab3195 id: foundReplacementFile.replacement,
b69ab3196 };
b69ab3197 }
b69ab3198 return null;
b69ab3199 },
b69ab31100 };
b69ab31101};
b69ab31102
b69ab31103export default defineConfig(({mode}) => ({
b69ab31104 base: '',
b69ab31105 plugins: [
b69ab31106 replaceFiles([
b69ab31107 {
b69ab31108 file: '../isl/src/platform.ts',
b69ab31109 replacement: './webview/vscodeWebviewPlatform.tsx',
b69ab31110 },
b69ab31111 ]),
b69ab31112 react({
b69ab31113 babel: {
b69ab31114 plugins: [
b69ab31115 [
b69ab31116 'jotai/babel/plugin-debug-label',
b69ab31117 {
b69ab31118 customAtomNames: [
b69ab31119 'atomFamilyWeak',
b69ab31120 'atomLoadableWithRefresh',
b69ab31121 'atomWithOnChange',
b69ab31122 'atomWithRefresh',
b69ab31123 'configBackedAtom',
b69ab31124 'jotaiAtom',
b69ab31125 'lazyAtom',
b69ab31126 'localStorageBackedAtom',
b69ab31127 ],
b69ab31128 },
b69ab31129 ],
b69ab31130 ],
b69ab31131 },
b69ab31132 }),
b69ab31133 styleX(),
b69ab31134 viteTsconfigPaths(),
b69ab31135 moveStylexFilenamePlugin(),
b69ab31136 ],
b69ab31137 build: {
b69ab31138 outDir: 'dist/webview',
b69ab31139 manifest: true,
b69ab31140 // FIXME: This means that all webviews will use the same css file.
b69ab31141 // This is too bloated for the inline comment webview and marginally slows down startup time.
b69ab31142 // Ideally, we'd load all the relevant css files in the webview, but our current approach
b69ab31143 // with our own manual copy of html in htmlForWebview does not support this.
b69ab31144 cssCodeSplit: false,
b69ab31145 rollupOptions: {
b69ab31146 input,
b69ab31147 output: {
b69ab31148 // Don't use hashed names, so ISL webview panel can pre-define what filename to load
b69ab31149 entryFileNames: '[name].js',
b69ab31150 chunkFileNames: '[name].js',
b69ab31151 assetFileNames: 'res/[name].[ext]',
b69ab31152 },
b69ab31153 },
b69ab31154 copyPublicDir: true,
b69ab31155 // No need for source maps in production. We can always build them locally to understand a wild stack trace.
b69ab31156 sourcemap: mode === 'development',
b69ab31157 },
b69ab31158 worker: {
b69ab31159 rollupOptions: {
b69ab31160 output: {
b69ab31161 // Don't use hashed names, so ISL webview panel can pre-define what filename to load
b69ab31162 entryFileNames: 'worker/[name].js',
b69ab31163 chunkFileNames: 'worker/[name].js',
b69ab31164 assetFileNames: 'worker/[name].[ext]',
b69ab31165 },
b69ab31166 },
b69ab31167 },
b69ab31168 publicDir: '../isl/public',
b69ab31169 server: {
b69ab31170 // No need to open the browser, we run inside vscode and don't really connect to the server.
b69ab31171 open: false,
b69ab31172 port: 3015,
b69ab31173 cors: {
b69ab31174 origin: /^vscode-webview:\/\/.*/,
b69ab31175 },
b69ab31176 },
b69ab31177}));