126 lines
4.7 KiB
TypeScript
126 lines
4.7 KiB
TypeScript
import { Configuration, EntryObject } from 'webpack';
|
|
import path from 'path';
|
|
import TerserPlugin from 'terser-webpack-plugin';
|
|
import { moduleResolutionPlugins } from './plugins/moduleResolutionPlugins';
|
|
import loaders from './loaders';
|
|
import { getBuildPlugins } from './plugins/buildProcessPlugins';
|
|
|
|
export interface Entries {
|
|
content: string[];
|
|
background: string[];
|
|
popup: string[];
|
|
my_calendar: string[];
|
|
// only used in development
|
|
debug?: string[];
|
|
}
|
|
|
|
export type EntryId = keyof Entries;
|
|
|
|
/**
|
|
* This function will generate the webpack configuration for the extension
|
|
* @param mode the mode that webpack is running in (development or production)
|
|
* * @param manifest the manifest.json object for the extension
|
|
* @returns the webpack configuration
|
|
*/
|
|
export default function config(mode: Environment, manifest: chrome.runtime.ManifestV3): Configuration {
|
|
const outDirectory = path.resolve('build');
|
|
|
|
// the entry points for the extension (the files that webpack will start bundling from)
|
|
const entry: Entries = {
|
|
content: [path.resolve('src', 'views')],
|
|
popup: [path.resolve('src', 'views')],
|
|
my_calendar: [path.resolve('src', 'views')],
|
|
background: [path.resolve('src', 'background', 'background')],
|
|
};
|
|
|
|
// the entries that need an html file to be generated
|
|
const htmlEntries: EntryId[] = ['popup', 'my_calendar'];
|
|
|
|
if (mode === 'development') {
|
|
// create an html file for the debug entry
|
|
htmlEntries.push('debug');
|
|
// TODO: add hot reloading script to the debug entry
|
|
entry.debug = [path.resolve('src', 'debug')];
|
|
|
|
// we need to import react-devtools before the react code in development so that it can hook into react
|
|
entry.content = [path.resolve('src', 'debug', 'reactDevtools'), ...entry.content];
|
|
entry.popup = [path.resolve('src', 'debug', 'reactDevtools'), ...entry.popup];
|
|
entry.my_calendar = [path.resolve('src', 'debug', 'reactDevtools'), ...entry.my_calendar];
|
|
}
|
|
|
|
/** @see https://webpack.js.org/configuration for documentation */
|
|
const config: Configuration = {
|
|
mode,
|
|
devtool: mode === 'development' ? 'cheap-module-source-map' : undefined,
|
|
bail: true,
|
|
cache: true,
|
|
// entry and resolve is what webpack uses for figuring out where to start bundling and how to resolve modules
|
|
entry: entry as unknown as EntryObject,
|
|
resolve: {
|
|
modules: ['node_modules'],
|
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
plugins: moduleResolutionPlugins,
|
|
// this is to polyfill some node-only modules
|
|
fallback: {
|
|
crypto: 'crypto-browserify',
|
|
stream: 'stream-browserify',
|
|
buffer: 'buffer',
|
|
fs: false,
|
|
},
|
|
},
|
|
// this is where we define the loaders for different file types
|
|
module: {
|
|
strictExportPresence: true,
|
|
rules: loaders,
|
|
},
|
|
output: {
|
|
clean: true,
|
|
path: outDirectory,
|
|
pathinfo: mode === 'development',
|
|
filename: 'static/js/[name].js',
|
|
publicPath: '/',
|
|
// this is for windows support (which uses backslashes in paths)
|
|
devtoolModuleFilenameTemplate: info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
|
|
// this is to make sure that the global chunk loading function name is unique
|
|
chunkLoadingGlobal: `webpackJsonp${manifest.short_name}`,
|
|
globalObject: 'this',
|
|
},
|
|
stats: {
|
|
errorDetails: true,
|
|
errorsCount: true,
|
|
},
|
|
// this is where we define the plugins that webpack will use
|
|
plugins: getBuildPlugins(mode, htmlEntries, manifest),
|
|
};
|
|
|
|
if (mode === 'production') {
|
|
config.optimization = {
|
|
minimize: true,
|
|
minimizer: [
|
|
new TerserPlugin({
|
|
extractComments: false,
|
|
parallel: false,
|
|
terserOptions: {
|
|
compress: {
|
|
ecma: 2020,
|
|
drop_console: true,
|
|
drop_debugger: true,
|
|
comparisons: false,
|
|
inline: 2,
|
|
},
|
|
keep_classnames: false,
|
|
keep_fnames: false,
|
|
output: {
|
|
ecma: 2020,
|
|
comments: false,
|
|
ascii_only: true,
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
};
|
|
}
|
|
|
|
return config;
|
|
}
|