@crxjs/vite-plugin 2.0.0-beta.17 → 2.0.0-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -17,6 +17,14 @@ interface WebAccessibleResourceById {
17
17
  resources: string[];
18
18
  use_dynamic_url?: boolean;
19
19
  }
20
+ interface ChromeManifestBackground {
21
+ service_worker: string;
22
+ type?: 'module';
23
+ }
24
+ interface FirefoxManifestBackground {
25
+ scripts: string[];
26
+ persistent?: false;
27
+ }
20
28
  interface ManifestV3 {
21
29
  manifest_version: number;
22
30
  name: string;
@@ -26,10 +34,7 @@ interface ManifestV3 {
26
34
  icons?: chrome.runtime.ManifestIcons | undefined;
27
35
  action?: chrome.runtime.ManifestAction | undefined;
28
36
  author?: string | undefined;
29
- background?: {
30
- service_worker: string;
31
- type?: 'module';
32
- } | undefined;
37
+ background?: ChromeManifestBackground | FirefoxManifestBackground | undefined;
33
38
  chrome_settings_overrides?: {
34
39
  homepage?: string | undefined;
35
40
  search_provider?: chrome.runtime.SearchProvider | undefined;
@@ -166,6 +171,9 @@ interface ManifestV3 {
166
171
  pages: string[];
167
172
  content_security_policy?: string | undefined;
168
173
  } | undefined;
174
+ side_panel?: {
175
+ default_path?: string | undefined;
176
+ } | undefined;
169
177
  short_name?: string | undefined;
170
178
  spellcheck?: {
171
179
  dictionary_language?: string | undefined;
@@ -229,9 +237,15 @@ declare type CrxDevScriptId = {
229
237
  type: 'module' | 'iife';
230
238
  };
231
239
  interface CrxPlugin extends Plugin {
232
- /** Runs during the transform hook for the manifest. Filenames use input filenames. */
240
+ /**
241
+ * Runs during the transform hook for the manifest. Filenames use input
242
+ * filenames.
243
+ */
233
244
  transformCrxManifest?: (this: PluginContext, manifest: ManifestV3) => Promise<ManifestV3 | null | undefined> | ManifestV3 | null | undefined;
234
- /** Runs during generateBundle, before manifest output. Filenames use output filenames. */
245
+ /**
246
+ * Runs during generateBundle, before manifest output. Filenames use output
247
+ * filenames.
248
+ */
235
249
  renderCrxManifest?: (this: PluginContext, manifest: ManifestV3, bundle: OutputBundle) => Promise<ManifestV3 | null | undefined> | ManifestV3 | null | undefined;
236
250
  /**
237
251
  * Runs in the file writer on content scripts during development. `script.id`
@@ -246,7 +260,13 @@ interface CrxOptions {
246
260
  injectCss?: boolean;
247
261
  };
248
262
  fastGlobOptions?: Options;
263
+ /**
264
+ * The browser that this extension is targeting, can be "firefox" or "chrome".
265
+ * Default is "chrome".
266
+ */
267
+ browser?: Browser;
249
268
  }
269
+ declare type Browser = 'firefox' | 'chrome';
250
270
 
251
271
  /** Resolves when all existing files in scriptFiles are written. */
252
272
  declare function allFilesReady(): Promise<void>;
package/dist/index.mjs CHANGED
@@ -275,6 +275,7 @@ const workerClientId = "/@crx/client-worker";
275
275
 
276
276
  const pluginBackground = () => {
277
277
  let config;
278
+ let browser;
278
279
  return [
279
280
  {
280
281
  name: "crx:background-client",
@@ -297,23 +298,37 @@ const pluginBackground = () => {
297
298
  name: "crx:background-loader-file",
298
299
  // this should happen after other plugins; the loader file is an implementation detail
299
300
  enforce: "post",
301
+ async config(config2) {
302
+ const opts = await getOptions(config2);
303
+ browser = opts.browser || "chrome";
304
+ },
300
305
  configResolved(_config) {
301
306
  config = _config;
302
307
  },
303
308
  renderCrxManifest(manifest) {
304
- const worker = manifest.background?.service_worker;
309
+ const worker = browser === "firefox" ? manifest.background?.scripts[0] : manifest.background?.service_worker;
305
310
  let loader;
306
311
  if (config.command === "serve") {
307
312
  const port = config.server.port?.toString();
308
313
  if (typeof port === "undefined")
309
314
  throw new Error("server port is undefined in watch mode");
310
- loader = `import 'http://localhost:${port}/@vite/env';
315
+ if (browser === "firefox") {
316
+ loader = `import('http://localhost:${port}/@vite/env');
317
+ `;
318
+ loader += `import('http://localhost:${port}${workerClientId}');
319
+ `;
320
+ if (worker)
321
+ loader += `import('http://localhost:${port}/${worker}');
311
322
  `;
312
- loader += `import 'http://localhost:${port}${workerClientId}';
323
+ } else {
324
+ loader = `import 'http://localhost:${port}/@vite/env';
325
+ `;
326
+ loader += `import 'http://localhost:${port}${workerClientId}';
313
327
  `;
314
- if (worker)
315
- loader += `import 'http://localhost:${port}/${worker}';
328
+ if (worker)
329
+ loader += `import 'http://localhost:${port}/${worker}';
316
330
  `;
331
+ }
317
332
  } else if (worker) {
318
333
  loader = `import './${worker}';
319
334
  `;
@@ -326,10 +341,16 @@ const pluginBackground = () => {
326
341
  fileName: getFileName({ type: "loader", id: "service-worker" }),
327
342
  source: loader
328
343
  });
329
- manifest.background = {
330
- service_worker: this.getFileName(refId),
331
- type: "module"
332
- };
344
+ if (browser !== "firefox") {
345
+ manifest.background = {
346
+ service_worker: this.getFileName(refId),
347
+ type: "module"
348
+ };
349
+ } else {
350
+ manifest.background = {
351
+ scripts: [this.getFileName(refId)]
352
+ };
353
+ }
333
354
  return manifest;
334
355
  }
335
356
  }
@@ -977,7 +998,9 @@ async function manifestFiles(manifest, options = {}) {
977
998
  ) ?? [];
978
999
  const contentScripts = manifest.content_scripts?.flatMap(({ js }) => js) ?? [];
979
1000
  const contentStyles = manifest.content_scripts?.flatMap(({ css }) => css);
980
- const serviceWorker = manifest.background?.service_worker;
1001
+ const serviceWorker = manifest.background && "service_worker" in manifest.background ? manifest.background.service_worker : void 0;
1002
+ const backgroundScripts = manifest.background && "scripts" in manifest.background ? manifest.background.scripts : void 0;
1003
+ const background = serviceWorker ? [serviceWorker].filter(isString) : backgroundScripts ? backgroundScripts.filter(isString) : [];
981
1004
  const htmlPages = htmlFiles(manifest);
982
1005
  const icons = [
983
1006
  Object.values(
@@ -1007,7 +1030,7 @@ async function manifestFiles(manifest, options = {}) {
1007
1030
  icons: [...new Set(icons)].filter(isString),
1008
1031
  locales: [...new Set(locales)].filter(isString),
1009
1032
  rulesets: [...new Set(rulesets)].filter(isString),
1010
- background: [serviceWorker].filter(isString),
1033
+ background,
1011
1034
  webAccessibleResources
1012
1035
  };
1013
1036
  }
@@ -1022,7 +1045,8 @@ function htmlFiles(manifest) {
1022
1045
  manifest.devtools_page,
1023
1046
  manifest.options_page,
1024
1047
  manifest.options_ui?.page,
1025
- manifest.sandbox?.pages
1048
+ manifest.sandbox?.pages,
1049
+ manifest.side_panel?.default_path
1026
1050
  ].flat().filter(isString).map((s) => s.split("#")[0]).sort();
1027
1051
  return [...new Set(files)];
1028
1052
  }
@@ -1566,7 +1590,7 @@ const pluginManifest = () => {
1566
1590
  })
1567
1591
  );
1568
1592
  }
1569
- if (manifest2.background?.service_worker) {
1593
+ if (manifest2.background && "service_worker" in manifest2.background) {
1570
1594
  const file = manifest2.background.service_worker;
1571
1595
  const id2 = join(config.root, file);
1572
1596
  const refId2 = this.emitFile({
@@ -1600,7 +1624,7 @@ const pluginManifest = () => {
1600
1624
  );
1601
1625
  }
1602
1626
  } else {
1603
- if (manifest2.background?.service_worker) {
1627
+ if (manifest2.background && "service_worker" in manifest2.background) {
1604
1628
  const ref = manifest2.background.service_worker;
1605
1629
  const name = this.getFileName(ref);
1606
1630
  manifest2.background.service_worker = name;
@@ -1712,7 +1736,11 @@ function compileFileResources(fileName, {
1712
1736
  assets: /* @__PURE__ */ new Set(),
1713
1737
  css: /* @__PURE__ */ new Set(),
1714
1738
  imports: /* @__PURE__ */ new Set()
1715
- }) {
1739
+ }, processedFiles = /* @__PURE__ */ new Set()) {
1740
+ if (processedFiles.has(fileName)) {
1741
+ return resources;
1742
+ }
1743
+ processedFiles.add(fileName);
1716
1744
  const chunk = chunks.get(fileName);
1717
1745
  if (chunk) {
1718
1746
  const { modules, facadeModuleId, imports, dynamicImports } = chunk;
@@ -1721,7 +1749,7 @@ function compileFileResources(fileName, {
1721
1749
  for (const x of dynamicImports)
1722
1750
  resources.imports.add(x);
1723
1751
  for (const x of [...imports, ...dynamicImports])
1724
- compileFileResources(x, { chunks, files, config }, resources);
1752
+ compileFileResources(x, { chunks, files, config }, resources, processedFiles);
1725
1753
  for (const m of Object.keys(modules))
1726
1754
  if (m !== facadeModuleId) {
1727
1755
  const key = prefix$1("/", relative(config.root, m.split("?")[0]));
@@ -1734,7 +1762,8 @@ function compileFileResources(fileName, {
1734
1762
  compileFileResources(
1735
1763
  script.fileName,
1736
1764
  { chunks, files, config },
1737
- resources
1765
+ resources,
1766
+ processedFiles
1738
1767
  );
1739
1768
  }
1740
1769
  }
@@ -1765,25 +1794,34 @@ _debug("web-acc-res");
1765
1794
  const pluginWebAccessibleResources = () => {
1766
1795
  let config;
1767
1796
  let injectCss;
1797
+ let browser;
1768
1798
  return [
1769
1799
  {
1770
1800
  name: "crx:web-accessible-resources",
1771
1801
  apply: "serve",
1772
1802
  enforce: "post",
1803
+ async config(config2) {
1804
+ const opts = await getOptions(config2);
1805
+ browser = opts.browser || "chrome";
1806
+ },
1773
1807
  renderCrxManifest(manifest) {
1774
1808
  manifest.web_accessible_resources = manifest.web_accessible_resources ?? [];
1775
1809
  manifest.web_accessible_resources = manifest.web_accessible_resources.map(({ resources, ...rest }) => ({
1776
1810
  resources: resources.filter((r) => r !== DYNAMIC_RESOURCE),
1777
1811
  ...rest
1778
1812
  })).filter(({ resources }) => resources.length);
1779
- manifest.web_accessible_resources.push({
1780
- // change the extension origin on every reload
1781
- use_dynamic_url: true,
1813
+ const war = {
1782
1814
  // all web origins can access
1783
1815
  matches: ["<all_urls>"],
1784
1816
  // all resources are web accessible
1785
- resources: ["**/*", "*"]
1786
- });
1817
+ resources: ["**/*", "*"],
1818
+ // change the extension origin on every reload
1819
+ use_dynamic_url: true
1820
+ };
1821
+ if (browser === "firefox") {
1822
+ delete war.use_dynamic_url;
1823
+ }
1824
+ manifest.web_accessible_resources.push(war);
1787
1825
  return manifest;
1788
1826
  }
1789
1827
  },
@@ -1792,7 +1830,9 @@ const pluginWebAccessibleResources = () => {
1792
1830
  apply: "build",
1793
1831
  enforce: "post",
1794
1832
  async config({ build, ...config2 }, { command }) {
1795
- const { contentScripts: contentScripts2 = {} } = await getOptions(config2);
1833
+ const opts = await getOptions(config2);
1834
+ const contentScripts2 = opts.contentScripts || {};
1835
+ browser = opts.browser || "chrome";
1796
1836
  injectCss = contentScripts2.injectCss ?? true;
1797
1837
  return { ...config2, build: { ...build, manifest: command === "build" } };
1798
1838
  },
@@ -1900,6 +1940,11 @@ const pluginWebAccessibleResources = () => {
1900
1940
  use_dynamic_url
1901
1941
  });
1902
1942
  }
1943
+ if (browser === "firefox") {
1944
+ for (const war of combinedResources) {
1945
+ delete war.use_dynamic_url;
1946
+ }
1947
+ }
1903
1948
  if (combinedResources.length === 0)
1904
1949
  delete manifest.web_accessible_resources;
1905
1950
  else
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crxjs/vite-plugin",
3
- "version": "2.0.0-beta.17",
3
+ "version": "2.0.0-beta.19",
4
4
  "description": "Build Chrome Extensions with this Vite plugin.",
5
5
  "keywords": [
6
6
  "rollup-plugin",
@@ -26,7 +26,7 @@
26
26
  "type": "module",
27
27
  "exports": {
28
28
  ".": {
29
- "require": "./index.cjs",
29
+ "require": "./dist/index.cjs",
30
30
  "import": "./dist/index.mjs",
31
31
  "types": "./dist/index.d.ts"
32
32
  },
@@ -83,13 +83,13 @@
83
83
  "devDependencies": {
84
84
  "@extend-chrome/messages": "1.2.2",
85
85
  "@extend-chrome/storage": "1.5.0",
86
- "@rollup/plugin-alias": "4.0.2",
86
+ "@rollup/plugin-alias": "4.0.4",
87
87
  "@rollup/plugin-commonjs": "21.1.0",
88
88
  "@rollup/plugin-json": "^5.0.0",
89
89
  "@rollup/plugin-node-resolve": "13.2.0",
90
- "@sveltejs/vite-plugin-svelte": "1.1.0",
90
+ "@sveltejs/vite-plugin-svelte": "1.4.0",
91
91
  "@types/acorn": "4.0.6",
92
- "@types/chrome": "0.0.209",
92
+ "@types/chrome": "0.0.237",
93
93
  "@types/convert-source-map": "^2.0.0",
94
94
  "@types/debug": "4.1.7",
95
95
  "@types/fs-extra": "9.0.13",
@@ -105,7 +105,7 @@
105
105
  "chokidar": "^3.5.3",
106
106
  "esbuild": "0.17.14",
107
107
  "esbuild-runner": "2.2.2",
108
- "eslint": "8.39.0",
108
+ "eslint": "8.43.0",
109
109
  "eslint-plugin-react": "^7.29.4",
110
110
  "jest-image-snapshot": "^5.2.0",
111
111
  "npm-run-all": "^4.1.5",
@@ -114,7 +114,7 @@
114
114
  "react-dom": "17.0.2",
115
115
  "rimraf": "3.0.2",
116
116
  "rollup-plugin-dts": "^4.2.0",
117
- "rollup-plugin-esbuild": "4.10.1",
117
+ "rollup-plugin-esbuild": "4.10.3",
118
118
  "svelte": "^3.48.0",
119
119
  "typescript": "^4.6.4",
120
120
  "vite": "^3.1.7",