Skip to content

Commit

Permalink
Remove old intances of browser/reload plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
cezaraugusto committed Jul 20, 2024
1 parent 9dd8ef3 commit 3c4b87f
Show file tree
Hide file tree
Showing 14 changed files with 664 additions and 110 deletions.
6 changes: 3 additions & 3 deletions programs/develop/install-scripts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ execute_command() {
# Copy required files to dist directory
copy_files_to_dist() {
local files=(
"tailwind.config.js"
"stylelint.config.js"
"commands/dev/types"
# "tailwind.config.js"
# "stylelint.config.js"
# "commands/dev/types"
"plugin-reload/extensions"
)
for file in "${files[@]}"; do
Expand Down
3 changes: 2 additions & 1 deletion programs/develop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"url": "https://cezaraugusto.com"
},
"scripts": {
"postinstall": "sh ./install-scripts.sh",
"clean": "rm -rf dist",
"watch": "yarn compile --watch",
"compile:types-folder": "node ./scripts/copyTypesFolder.js",
Expand Down Expand Up @@ -97,4 +98,4 @@
"tsup": "^8.0.1",
"typescript": "5.3.3"
}
}
}
25 changes: 0 additions & 25 deletions programs/develop/webpack/_plugin-reload/index.ts

This file was deleted.

72 changes: 72 additions & 0 deletions programs/develop/webpack/plugin-browsers/_package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/cezaraugusto/webpack-run-chromium-extension.git"
},
"engines": {
"node": ">=18"
},
"name": "webpack-run-chromium-extension",
"version": "1.3.0",
"description": "Run your extension on any Chromium-based browser",
"main": "./dist/module.js",
"types": "./dist/module.d.ts",
"author": {
"name": "Cezar Augusto",
"email": "boss@cezaraugusto.net",
"url": "https://cezaraugusto.com"
},
"scripts": {
"clean": "rm -rf dist",
"compile:plugin": "tsup-node ./module.ts ./loaders/* --format cjs --dts --target=node18 --minify && node ./copyExtensions.js",
"compile:web": "tsup-node ./minimum-background-file.ts --format esm --dts --target=node18 --minify --config=tsconfig.web.json",
"compile": "yarn compile:plugin && yarn compile:web",
"lint": "eslint \"./**/*.ts*\"",
"test": "echo \"Note: no test specified\" && exit 0",
"test:fixture": "yarn --cwd=./fixtures/dev-server-no-hmr dev",
"demo": "yarn test:fixture"
},
"files": [
"dist"
],
"keywords": [
"webpack",
"plugin",
"chromium",
"run",
"open",
"plugin",
"browser",
"web",
"extension",
"web-ext",
"webextension"
],
"peerDependencies": {
"webpack": "^5.00.0"
},
"dependencies": {
"@colors/colors": "^1.6.0",
"browser-extension-manifest-fields": "*",
"chromium-location": "^1.2.1",
"content-security-policy-parser": "^0.6.0",
"loader-utils": "^3.3.1",
"prefers-yarn": "^1.0.1",
"progress": "^2.0.3",
"schema-utils": "^4.2.0",
"webpack-target-webextension": "^1.1.2",
"ws": "^8.17.1"
},
"devDependencies": {
"@types/loader-utils": "^2.0.6",
"copy-webpack-plugin": "^12.0.2",
"eslint": "^8.56.0",
"eslint-config-extension-create": "*",
"html-webpack-plugin": "^5.6.0",
"tsconfig": "*",
"tsup": "^8.1.0",
"webpack": "~5.92.0",
"webpack-cli": "^5.1.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @ts-ignore
import ProgressBar from 'progress';

export function addProgressBar(text: string, completionCallback: () => void) {
const contentLength = 128 * 1024;
const bar = new ProgressBar(`${text} [:bar] :percent :etas`, {
complete: '=',
incomplete: ' ',
width: 50,
total: contentLength,
});

const timer = setInterval(() => {
const chunk = Math.random() * 10 * 1024;
bar.tick(chunk);

if (bar.complete) {
clearInterval(timer);
completionCallback();
}
}, 50);
}
29 changes: 29 additions & 0 deletions programs/develop/webpack/plugin-browsers/browser-lib/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { bold, bgWhite, red } from '@colors/colors/safe';

export function watchModeClosed(browser: string, code: number, reason: Buffer) {
const message = reason.toString();
return (
`[😓] ${bgWhite(bold(` ${browser}-browser `))} ${red('✖︎✖︎✖︎')} Watch mode closed (code ${code}). ` +
`${message && '\n\nReason ' + message + '\n'}Exiting...\n`
);
}

export function browserNotFound(browser: string, binaryPath: string) {
const capitalize = (str: string) =>
str.charAt(0).toUpperCase() + str.slice(1);
return `${bgWhite(bold(` ${browser}-browser `))} ${red('✖︎✖︎✖︎')} ${capitalize(browser)} not found at ${binaryPath}`;
}

export function webSocketError(browser: string, error: any) {
error(
`[⛔️] ${bgWhite(bold(` ${browser}-browser `))} ${red('✖︎✖︎✖︎')} WebSocket error`,
error,
);
}

export function parseFileError(browser: string, error: any, filepath: string) {
return (
`[⛔️] ${bgWhite(bold(` ${browser}-browser `))} ${red('✖︎✖︎✖︎')} ` +
`Error parsing file: ${filepath}. Reason: ${error.message}`
);
}
17 changes: 17 additions & 0 deletions programs/develop/webpack/plugin-browsers/browser-lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type Compilation } from 'webpack';
import { type Manifest } from '../../types';

export function getManifestContent(
compilation: Compilation,
manifestPath: string,
): Manifest {
if (
compilation.getAsset('manifest.json') ||
compilation.assets['manifest.json']
) {
const manifest = compilation.assets['manifest.json'].source().toString();
return JSON.parse(manifest || '{}');
}

return require(manifestPath);
}
158 changes: 79 additions & 79 deletions programs/develop/webpack/plugin-browsers/index.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,93 @@
// ██████╗ ███████╗██╗ ██╗███████╗██╗ ██████╗ ██████╗
// ██╔══██╗██╔════╝██║ ██║██╔════╝██║ ██╔═══██╗██╔══██╗
// ██║ ██║█████╗ ██║ ██║█████╗ ██║ ██║ ██║██████╔╝
// ██║ ██║██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║ ██║ ██║██╔═══╝
// ██████╔╝███████╗ ╚████╔╝ ███████╗███████╗╚██████╔╝██║
// ╚═════╝ ╚══════╝ ╚═══╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝
import os from 'os';
import path from 'path';
import { type Compiler } from 'webpack';
import { type PluginInterface } from './types';
import { RunChromiumPlugin } from './run-chromium';
// import { RunFirefoxPlugin } from './run-firefox';

import path from 'path'
import os from 'os'
import type webpack from 'webpack'
import RunChromeExtension from 'webpack-run-chrome-extension'
import RunEdgeExtension from 'webpack-run-edge-extension'
import RunFirefoxAddon from 'webpack-run-firefox-addon'
import {type DevOptions} from '../../extensionDev'
import {getManifestPath, getOutputPath} from '../config/getPath'
/**
* RunChromiumPlugin works by creating a WebSockets server
* that listens to changes triggered by the user extension
* via webpack. When a change is detected, the server sends
* a message to an extension called reload-extension, which
* is injected into the browser. This extension is responsible
* for sending messages to the user extension. We do that by
* injecting a script into the background page that listens
* to messages from the reload-extension.
*
* Features supported:
* - Service worker - Full extension reload (chrome.runtime.reload)
* - manifest.json - Full extension reload (chrome.runtime.reload)
*/
export class BrowsersPlugin {
public readonly extension: string | string[];
public readonly browser: string;
public readonly browserFlags: string[];
public readonly userDataDir?: string;
public readonly profile: string;
public readonly preferences: string;
public readonly startingUrl: string;

function getProfilePath(devOptions: DevOptions) {
if (devOptions?.userDataDir) {
return devOptions.userDataDir
constructor(options: PluginInterface) {
this.extension = options.extension;
this.browser = options.browser || 'chrome';
this.browserFlags = options.browserFlags || [];
this.userDataDir = options.userDataDir;
this.profile = options.profile || '';
this.preferences = options.preferences || '';
this.startingUrl = options.startingUrl || '';
}

// Ensure `start` runs in a fresh profile by default.
if (devOptions.mode === 'production') {
return path.join(
os.tmpdir(),
'extension-js',
devOptions.browser!,
'profile'
)
}

return devOptions?.userDataDir
}
private getProfilePath(
compiler: Compiler,
browser: string,
profile: string | undefined,
) {
if (profile) {
return profile;
}

export default function browserPlugins(
projectPath: string,
devOptions: DevOptions
) {
if (!devOptions?.mode || process.env.NODE_ENV === 'test') {
return {
constructor: {name: 'BrowserPlugin'},
apply: () => {}
// Ensure `start` runs in a fresh profile by default.
if (compiler.options.mode === 'production') {
return path.join(os.tmpdir(), 'extension-js', browser, 'profile');
}
}

const chromeConfig = {
port: 8000,
manifestPath: getManifestPath(projectPath),
// The final folder where the extension manifest file is located.
// This is used to load the extension into the browser.
extensionPath: getOutputPath(projectPath, devOptions.browser),
autoReload: true,
browserFlags: ['--enable-benchmarking'],
userDataDir: getProfilePath(devOptions),
stats: true
return path.resolve(__dirname, `run-${browser}-profile`);
}

const edgeConfig = {
...chromeConfig,
port: 8001,
stats: true
}
apply(compiler: Compiler) {
const config = {
stats: true,
extension: this.extension,
browser: this.browser,
browserFlags: this.browserFlags || [],
userDataDir: this.getProfilePath(
compiler,
this.browser || 'chrome',
this.userDataDir || this.profile,
),
};

const firefoxConfig = {
...chromeConfig,
port: 8002,
// If all browsers are being used, we don't need to show the stats
// for each browser. This is because the stats will be the same for
// each browser.
// Note that a comma means that more than once browser is selected,
// so we show the user extension manifest output only once.
stats: true
}
// 1 - Bundle the reloader and manager extensions. The reloader extension
// is injected into the browser and is responsible for sending reload
// requests to the user extension. The manager extension is responsible
// for everything else, for now opening the chrome://extension page on startup.
// It starts a new browser instance with the user extension loaded.
switch (this.browser) {
case 'chrome': {
new RunChromiumPlugin({ ...config, browser: 'chrome' }).apply(compiler);
break;
}

return {
constructor: {name: 'BrowserPlugin'},
apply: (compiler: webpack.Compiler) => {
switch (devOptions.browser) {
case 'chrome':
new RunChromeExtension(chromeConfig).apply(compiler)
break
case 'edge':
new RunEdgeExtension(edgeConfig).apply(compiler)
break
case 'firefox':
new RunFirefoxAddon(firefoxConfig).apply(compiler)
break
default:
new RunChromeExtension(chromeConfig).apply(compiler)
break
// case 'edge':
// new RunChromiumPlugin({ ...config, browser: 'edge' }).apply(compiler);
// break;
// case 'firefox':
// new RunFirefoxPlugin({...config, browser: 'firefox'}).apply(compiler);
// break;
default: {
new RunChromiumPlugin({ ...config, browser: 'chrome' }).apply(compiler);
break;
}
}
}
Expand Down
Loading

0 comments on commit 3c4b87f

Please sign in to comment.