using my boilerplate yuh

This commit is contained in:
Sriram Hariharan
2023-02-22 22:51:38 -06:00
parent 21d7056aae
commit bce2717088
91 changed files with 32400 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
import path from 'path';
import dotenv from 'dotenv';
import webpack, { WebpackPluginInstance } from 'webpack';
import { EntryId } from 'webpack/webpack.config';
import CreateFileWebpack from 'create-file-webpack';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import WebpackBuildNotifierPlugin from 'webpack-build-notifier';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import HTMLWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import TypeErrorNotifierPlugin from './custom/TypeErrorNotifierPlugin';
/**
* Gets the plugins that are used in the build process
* @param mode the environment that the build is running in
* @param htmlEntries the entry points that need an html file
* @param manifest the manifest.json file
* @returns an array of webpack plugins
*/
export function getBuildPlugins(mode: Environment, htmlEntries: EntryId[], manifest: chrome.runtime.ManifestV3) {
let plugins: WebpackPluginInstance[] = [];
// show the progress of the build
plugins.push(new webpack.ProgressPlugin());
// make sure that the paths are case sensitive
plugins.push(new CaseSensitivePathsPlugin());
// specify how the outputed css files should be named
plugins.push(
new MiniCssExtractPlugin({
filename: 'static/css/[name].css',
chunkFilename: 'static/css/[name].chunk.css',
})
);
// create an html file for each entry point that needs one
for (const entryId of htmlEntries) {
// if (!entries[entryId]) return;
plugins.push(
new HTMLWebpackPlugin({
hash: false,
filename: `${entryId}.html`,
chunks: [entryId],
title: `${manifest.short_name} ${entryId} `,
template: path.resolve('webpack', 'plugins', 'template.html'),
})
);
}
// write the manifest.json file to the build directory
plugins.push(
new CreateFileWebpack({
path: path.resolve('build'),
fileName: 'manifest.json',
content: JSON.stringify(manifest, null, 2),
})
);
// copy the public directory to the build directory, but only copy the icons for the current mode
plugins.push(
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve('public'),
filter: path => (path.includes('icons') ? path.includes(mode) : true),
},
],
})
);
// run the typescript checker in a separate process
plugins.push(
new ForkTsCheckerWebpackPlugin({
async: false,
})
);
// notify the developer of build events when in development mode
if (mode === 'development') {
plugins.push(
new WebpackBuildNotifierPlugin({
title: `${manifest.short_name} v${manifest.version} ${mode}`,
logo: path.resolve('public', 'icons', 'icon_production_128.png'),
failureSound: 'Ping',
showDuration: true,
suppressWarning: true,
})
);
}
// notify the developer of type errors
plugins.push(new TypeErrorNotifierPlugin());
// define the environment variables that are available within the extension code
plugins.push(
new webpack.DefinePlugin({
'process.env': JSON.stringify({
SEMANTIC_VERSION: process.env.SEMANTIC_VERSION,
NODE_ENV: mode,
...dotenv.config({ path: `.env.${mode}` }).parsed,
} satisfies typeof process.env),
})
);
// provide some global nodejs variables so that nodejs libraries can be used
plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
})
);
return plugins;
}

View File

@@ -0,0 +1,84 @@
import { Compiler } from 'webpack';
import path from 'path';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import WebpackBuildNotifierPlugin from 'webpack-build-notifier';
import { Issue, IssueLocation } from 'fork-ts-checker-webpack-plugin/lib/issue';
interface Resource {
path: string;
location: IssueLocation;
}
/**
* This plugin hooks into the fork-ts-checker-webpack-plugin and
* notifies the developer of type errors using the webpack-build-notifier plugin.
*/
export default class TypeErrorNotifierPlugin {
apply(compiler: Compiler) {
// hook into the fork-ts-checker-webpack-plugin
const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
hooks.issues.tap('MyPlugin', issues => {
const errors = issues.filter(issue => issue.severity === 'error');
if (!errors?.[0]?.message) {
return errors;
}
let error = errors[0];
let resource = getErrorResource(error);
try {
notifyTypeError(resource, error.message, errors);
} catch (e) {
console.error(e);
}
return errors;
});
}
}
function notifyTypeError(resource: Resource, message: string, errors: Issue[]) {
const { line, column } = resource.location.start;
const buildNotifier = new WebpackBuildNotifierPlugin({
logo: path.resolve('public', 'icons', 'icon_production_128.png'),
compilationSound: 'Pop',
failureSound: 'Sosumi',
title: `TS: ${errors.length} errors`,
notifyOptions: {
open: `vscode://file/${resource.path}:${line}:${column}`,
},
});
const fakeInput = {
hasErrors: () => true,
compilation: {
children: null,
errors: [
{
message,
module: {
resource: resource.path,
},
},
],
},
};
// @ts-ignore - private method
buildNotifier.onCompilationDone(fakeInput);
}
function getErrorResource(error: Issue): Resource {
return {
path: error.file ?? '',
location: error.location ?? {
end: {
column: 0,
line: 0,
},
start: {
column: 0,
line: 0,
},
},
};
}

View File

@@ -0,0 +1,36 @@
import { Server } from 'socket.io';
import { Compiler } from 'webpack';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
// Name of the plugin
const PLUGIN_NAME = 'HotReloadServer';
// How long to wait before reloading the browser after a successful build
const RELOAD_LOCKOUT = 2000;
// we want to cache all the "reload requests" here so we don't have to keep re-compiling the app while typing
const reloads: NodeJS.Timeout[] = [];
let io: Server;
export function initializeHotReloading(port: number, compiler: Compiler) {
io = new Server(port);
const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
hooks.issues.tap(PLUGIN_NAME, (issues, compilation) => {
const typeErrors = issues.filter(issue => issue.severity === 'error');
const buildErrors = compilation?.errors ?? [];
// if no errors (thus successful build), lets queue up a reload for the browser
if (typeErrors.length === 0 && buildErrors.length === 0) {
reloads.push(setTimeout(() => io.emit('reload'), RELOAD_LOCKOUT));
}
return typeErrors;
});
// if a recompile is triggered, we want to clear out all the queue'd reloads
// (so we don't spam-reload the extension while we are still typing
compiler.hooks.compile.tap(PLUGIN_NAME, () => {
reloads.forEach(reload => clearTimeout(reload));
reloads.length = 0;
});
}

View File

@@ -0,0 +1,12 @@
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import path from 'path';
import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin';
export const moduleResolutionPlugins = [
// this will make sure that webpack uses the tsconfig path aliases
new TsconfigPathsPlugin({
configFile: path.resolve('src', 'tsconfig.json'),
}),
// this will make sure that we don't import anything outside of the src directory from the src directory
new ModuleScopePlugin(path.resolve('src'), path.resolve('package.json')),
];

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
--></body>
</html>