make-entry-point-plugin.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import fs from 'node:fs';
  2. import path from 'node:path';
  3. import type { PluginOption } from 'vite';
  4. /**
  5. * make entry point file for content script cache busting
  6. */
  7. export function makeEntryPointPlugin(): PluginOption {
  8. const cleanupTargets = new Set<string>();
  9. const isFirefox = process.env.__FIREFOX__ === 'true';
  10. return {
  11. name: 'make-entry-point-plugin',
  12. generateBundle(options, bundle) {
  13. const outputDir = options.dir;
  14. if (!outputDir) {
  15. throw new Error('Output directory not found');
  16. }
  17. for (const module of Object.values(bundle)) {
  18. const fileName = path.basename(module.fileName);
  19. const newFileName = fileName.replace('.js', '_dev.js');
  20. switch (module.type) {
  21. case 'asset':
  22. if (fileName.endsWith('.map')) {
  23. cleanupTargets.add(path.resolve(outputDir, fileName));
  24. const originalFileName = fileName.replace('.map', '');
  25. const replacedSource = String(module.source).replaceAll(originalFileName, newFileName);
  26. module.source = '';
  27. fs.writeFileSync(path.resolve(outputDir, newFileName), replacedSource);
  28. break;
  29. }
  30. break;
  31. case 'chunk': {
  32. fs.writeFileSync(path.resolve(outputDir, newFileName), module.code);
  33. if (isFirefox) {
  34. const contentDirectory = extractContentDir(outputDir);
  35. module.code = `import(browser.runtime.getURL("${contentDirectory}/${newFileName}"));`;
  36. } else {
  37. module.code = `import('./${newFileName}');`;
  38. }
  39. break;
  40. }
  41. }
  42. }
  43. },
  44. closeBundle() {
  45. cleanupTargets.forEach(target => {
  46. fs.unlinkSync(target);
  47. });
  48. },
  49. };
  50. }
  51. /**
  52. * Extract content directory from output directory for Firefox
  53. * @param outputDir
  54. */
  55. function extractContentDir(outputDir: string) {
  56. const parts = outputDir.split(path.sep);
  57. const distIndex = parts.indexOf('dist');
  58. if (distIndex !== -1 && distIndex < parts.length - 1) {
  59. return parts.slice(distIndex + 1);
  60. }
  61. throw new Error('Output directory does not contain "dist"');
  62. }