-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.js
145 lines (140 loc) · 5.28 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// SPDX-FileCopyrightText: Alexander zur Bonsen <[email protected]>
// SPDX-FileCopyrightText: Copyright (c) Abhijith Vijayan <[email protected]> (https://abhijithvijayan.in)
//
// SPDX-License-Identifier: MIT AND Apache-2.0
const {
WebextensionPlugin,
} = require('@webextension-toolbox/webpack-webextension-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const FileManagerPlugin = require('filemanager-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const JSON5 = require('json5');
const fs = require('fs');
const packageJSON = require('./package.json');
const tsConfigString = fs.readFileSync('./tsconfig.json', 'utf8');
const tsConfig = JSON5.parse(tsConfigString);
const sourcePath = path.join(__dirname, tsConfig.compilerOptions.rootDir);
const outputPath = path.join(__dirname, tsConfig.compilerOptions.outDir);
const description = packageJSON.description;
const version = packageJSON.version;
function getZipFileName(browser) {
return `${packageJSON.name}_${browser}.zip`;
}
module.exports = (env) => {
return {
mode: env.mode,
// WebextensionPlugin assumes that manifest.json is top level in context
// https://github.com/webextension-toolbox/webpack-webextension-plugin/blob/ff770e789f9d4e8ad20009ab244ff466905ea92b/src/plugin/index.ts#L373
context: sourcePath,
entry: {
background: path.join(sourcePath, 'background-script', 'main.ts'),
content: path.join(sourcePath, 'content-script', 'main.ts'),
popup: path.join(sourcePath, 'popup', 'index.tsx'),
},
output: {
path: path.join(outputPath, env.browser),
filename: 'js/[name].bundle.js',
},
// TODO I saw examples were node modules were excluded, need to understand why
module: {
rules: [
// all files with a `.ts`, `.cts`, `.mts` or `.tsx` extension will be handled by `ts-loader`
{ test: /\.([cm]?ts|tsx)$/, loader: 'ts-loader' },
],
},
resolve: {
// resolve extensions in order, enables users to leave off the extension when importing
// webpack will resolve the one with the extension listed first in the array and skip the rest
extensions: ['.tsx', '.ts', '.js', '.json'],
// Add support for TypeScripts fully qualified ESM imports.
extensionAlias: {
'.js': ['.js', '.ts'],
'.cjs': ['.cjs', '.cts'],
'.mjs': ['.mjs', '.mts'],
},
},
// include source maps in bundle
// "Even if it is not the best recommendation from the Webpack documentation, only the “inline” type works on Firefox."
// https://medium.com/@Morikko/developing-your-web-extension-with-the-best-tools-213207c2b6b5
devtool: 'inline-source-map',
plugins: [
new WebextensionPlugin({
vendor: env.browser,
manifestDefaults: {
description,
version,
},
autoreload: env.mode === 'development' ? true : false,
}),
// following plugins are adapted from
// https://github.com/abhijithvijayan/web-extension-starter/blob/react-typescript/webpack.config.js
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
path.join(`${outputPath}`, `${env.browser}`),
path.join(`${outputPath}`, `${getZipFileName(env.browser)}`),
],
cleanStaleWebpackAssets: false,
verbose: true,
}),
new CopyWebpackPlugin({
patterns: [{ from: `${sourcePath}/assets`, to: 'assets' }],
}),
// TODO not sure about this config yet
new HtmlWebpackPlugin({
template: path.join(sourcePath, 'popup', 'popup.html'),
inject: 'body',
chunks: ['popup'],
hash: true,
filename: 'popup.html',
}),
],
// mostly copied from https://github.com/abhijithvijayan/web-extension-starter/blob/react-typescript/webpack.config.js
optimization: {
splitChunks: {
chunks: 'all',
maxSize: 1500000, // Mozilla Add On platform allows for file size of max. 4MB, this combination gave me chunks within size limits (note that maxSize is a hint, not a guarantee, see https://webpack.js.org/plugins/split-chunks-plugin/#splitchunksmaxsize)
minSize: 500000,
},
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
new FileManagerPlugin({
events: {
onEnd: {
archive: [
{
format: 'zip',
source: path.join(outputPath, env.browser),
destination: `${path.join(outputPath, getZipFileName(env.browser))}`,
options: { zlib: { level: 6 } },
},
],
},
},
}),
],
},
};
};