Closed YunFeng0817 closed 1 year ago
Nope, dev mode and HMR is the last TODO before v2 can be released, but I haven't had time to work on it lately. Right now V2 just doesn't have any dev mode logic in it.
https://github.com/aklinker1/vite-plugin-web-extension/pull/44
If you want to use vite dev
, you'll need to use the latest stable version, 1.4.4:
https://www.npmjs.com/package/vite-plugin-web-extension
Or use watch mode:
vite build --watch
Thanks, I'm using v2 because it supports esm bundling. Is there a way to configue it in v1.4.4?
I'll hide the HMR stuff from the V2 docs for now.
What do you mean by esm bundling? Just set the output format to ESM for everything? Could you share your config, then I can give a recommendation
Sure, here's my config for v1
import { defineConfig } from 'vite';
import webExtension, { readJsonFile } from 'vite-plugin-web-extension';
import zip from 'vite-plugin-zip';
import * as path from 'path';
import type { PackageJson } from 'type-fest';
import react from '@vitejs/plugin-react';
export default defineConfig({
root: 'src',
// Configure our outputs - nothing special, this is normal vite config
build: {
outDir: path.resolve(
__dirname,
'dist',
process.env.TARGET_BROWSER as string,
),
emptyOutDir: true,
},
// Add the webExtension plugin
plugins: [
react(),
webExtension({
// A function to generate manifest file dynamically.
manifest: () => {
const packageJson = readJsonFile('package.json') as PackageJson;
const isProduction = process.env.NODE_ENV === 'production';
type ManifestBase = {
common: Record<string, unknown>;
chrome: Record<string, unknown>;
firefox: Record<string, unknown>;
};
const originalManifest = readJsonFile('./src/manifest.json') as {
common: Record<string, unknown>;
v2: ManifestBase;
v3: ManifestBase;
};
const ManifestVersion =
process.env.TARGET_BROWSER === 'chrome' && isProduction ? 'v3' : 'v2';
const BrowserName =
process.env.TARGET_BROWSER === 'chrome' ? 'chrome' : 'firefox';
const commonManifest = originalManifest.common;
const manifest = {
version: packageJson.version,
author: packageJson.author,
version_name: packageJson.dependencies?.rrweb?.replace('^', ''),
...commonManifest,
};
Object.assign(
manifest,
originalManifest[ManifestVersion].common,
originalManifest[ManifestVersion][BrowserName],
);
return manifest;
},
assets: 'assets',
browser: process.env.TARGET_BROWSER,
webExtConfig: {
startUrl: ['github.com/rrweb-io/rrweb'],
watchIgnored: ['*.md', '*.log'],
},
additionalInputs: ['pages/index.html', 'content/inject.ts'],
}),
process.env.ZIP === 'true' &&
zip({
dir: 'dist',
outputName: process.env.TARGET_BROWSER,
}),
],
});
The output files are in UMD format. I want to inject an output js file into web pages. But UMD format causes a problem on some pages like Facebook. The page has a predefined AMD system and causes the execution of my output js to fail.
I see, so you want the inject.ts
file to be built in ESM so you can inject it onto the page via a script
element or something like that? So that file runs on in the page's context, not in the content-script context.
I've done this in the past by using a separate build command, but if you want to do it all in a single build step... You could write a custom plugin that changes the format to ESM if the input's name is injector.ts
. Since TS files in the additionalInputs
are bundled individually, something like this will adjust the format of that one file:
import { defineConfig, PluginOption } from "vite";
import webExtension from "vite-plugin-web-extension";
import path from "node:path";
function useEsmFormat(entriesToUseEsm: string[]): PluginOption {
return {
name: "use-esm-format",
config(config) {
const shouldUseEsm = entriesToUseEsm.includes(config.build?.lib?.entry);
if (shouldUseEsm) {
config.build ??= {};
// @ts-expect-error: lib needs to be an object, forcing it.
config.build.lib ||= {};
// @ts-expect-error: lib is an object
config.build.lib.formats = ["es"];
}
},
};
}
export default defineConfig({
root: "src",
build: {
outDir: "dist",
},
plugins: [
webExtension({
manifest: "src/manifest.json",
assets: "assets",
additionalInputs: ["injected.ts"],
}),
useEsmFormat([path.resolve(__dirname, "injected.ts")]),
],
});
@aklinker1 Exactly, thanks for your suggestion and it works well.
Thanks for this great Vite plugin. I'm currently using v2.0.0-alpha5 with Vite v3.1.8 It went well for building packages but in the dev mode, there's a warning in the console at the end of the process like this:
And the browser (web-ext) wasn't started.
Is this a bug or did I configure something wrong?