blob: 8f55a27a6f40f69c2629c03785c50c383d6c79e4 [file] [log] [blame]
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +02001const webpack = require('webpack');
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02002const path = require('path');
3const json5 = require('json5');
4const CopyWebpackPlugin = require('copy-webpack-plugin');
Adrià Vilanova Martínez39f48f82024-09-29 17:55:04 +02005const HtmlWebpackPlugin = require('html-webpack-plugin');
Adrià Vilanova Martínezddd30042023-11-01 22:54:17 +01006const MiniCssExtractPlugin = require('mini-css-extract-plugin');
Adrià Vilanova Martínez6b560432022-10-23 20:26:17 +02007const TerserPlugin = require('terser-webpack-plugin');
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +02008const WebpackShellPluginNext = require('webpack-shell-plugin-next');
9
Adrià Vilanova Martínez43d0a7b2021-08-28 01:21:17 +020010// Pontoon uses their own locale set. This array lets us convert those locales
11// to the ones accepted by Chrome, Firefox, etc.
12const localeOverrides = [
13 {
14 pontoonLocale: 'pt-rBR',
Adrià Vilanova Martínez7f9540d2022-02-17 22:05:14 +010015 webExtLocale: 'pt_BR',
16 },
17 {
18 pontoonLocale: 'pt-rBR',
19 webExtLocale: 'pt_PT',
Adrià Vilanova Martínez43d0a7b2021-08-28 01:21:17 +020020 },
21];
22
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020023module.exports = (env, args) => {
Adrià Vilanova Martínez2df2f242022-03-01 22:25:27 +010024 // NOTE: When adding an entry, add the corresponding source map file to
25 // web_accessible_resources in //templates/manifest.gjson.
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +010026 const entry = {
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020027 // Content scripts
Adrià Vilanova Martínez39f48f82024-09-29 17:55:04 +020028 communityConsoleMain:
Adrià Vilanova Martínezf92172f2024-10-19 15:55:15 +020029 './src/entryPoints/communityConsole/contentScripts/main.ts',
Adrià Vilanova Martínez39f48f82024-09-29 17:55:04 +020030 communityConsoleStart:
Adrià Vilanova Martínezf92172f2024-10-19 15:55:15 +020031 './src/entryPoints/communityConsole/contentScripts/start.ts',
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020032 publicForum: './src/contentScripts/publicForum.js',
33 publicThread: './src/contentScripts/publicThread.js',
Adrià Vilanova Martínez80f6c9f2024-11-10 01:09:48 +010034 publicThreadStart: './src/entryPoints/twBasic/thread/start.ts',
Adrià Vilanova Martínez04ae1032024-02-07 23:42:25 +010035 publicGuide: './src/contentScripts/publicGuide.js',
36 publicGuideStart: './src/contentScripts/publicGuideStart.js',
avm9996337601bc2022-02-21 10:36:45 +010037 publicProfile: './src/contentScripts/publicProfile.js',
38 publicProfileStart: './src/contentScripts/publicProfileStart.js',
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020039 profileIndicator: './src/contentScripts/profileIndicator.js',
40
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +020041 // Programatically injected content scripts
42 handleInstall: './src/contentScripts/communityConsole/handleInstall.js',
43 handleUpdate: './src/contentScripts/communityConsole/handleUpdate.js',
44
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020045 // Injected JS
46 profileIndicatorInject: './src/injections/profileIndicator.js',
47 batchLockInject: './src/injections/batchLock.js',
Adrià Vilanova Martínezc9a3df12025-02-08 23:16:12 +010048 xhrInterceptorInject:
49 './src/entryPoints/communityConsole/injections/xhrProxy.ts',
Adrià Vilanova Martínez4f56d562022-01-26 00:23:27 +010050 extraInfoInject: './src/injections/extraInfo.js',
Adrià Vilanova Martínez2d9be8d2022-12-28 00:50:14 +010051 litComponentsInject: './src/injections/litComponentsInject.js',
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +020052 updateHandlerLitComponents:
53 './src/injections/updateHandlerLitComponents.js',
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020054
55 // Options page
Adrià Vilanova Martínez09f35be2021-09-06 19:50:09 +020056 optionsCommon: './src/options/optionsCommon.js',
avm999632485a3e2021-09-08 22:18:38 +020057
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020058 // Workflow manager
Adrià Vilanova Martínezc78c3ad2024-05-18 00:35:51 +020059 workflowManager: './src/features/workflows/core/manager/index.js',
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020060
avm999632485a3e2021-09-08 22:18:38 +020061 // Common CSS
62 mdcStyles: './src/mdc/index.js',
Adrià Vilanova Martínezddd30042023-11-01 22:54:17 +010063
64 // Compiled Sass
Adrià Vilanova Martínez917797e2024-05-25 22:41:25 +020065 ccDarkTheme: './src/features/ccDarkTheme/core/styles/main.scss?asCSSFile',
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +010066
67 // Background script (or service worker for MV3)
68 bg: './src/bg.js',
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +020069 };
70
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +010071 // NOTE: When adding an entry, add the corresponding source map file to
72 // web_accessible_resources in //templates/manifest.gjson.
73 const styles = [
74 {
75 origin: './src/features/enhancedAnnouncementsDot/ui/styles.css',
76 destination: 'css/enhanced_announcements_dot.css',
77 },
78 {
79 origin: './src/features/fixedToolbar/ui/styles.css',
80 destination: 'css/fixed_toolbar.css',
81 },
82 {
83 origin: './src/features/imageMaxHeight/ui/styles.css',
84 destination: 'css/image_max_height.css',
85 },
86 {
87 origin: './src/features/increaseContrast/ui/styles.css',
88 destination: 'css/increase_contrast.css',
89 },
90 {
91 origin: './src/features/repositionExpandThread/ui/styles.css',
92 destination: 'css/reposition_expand_thread.css',
93 },
94 {
95 origin: './src/features/stickySidebarHeaders/ui/styles.css',
96 destination: 'css/sticky_sidebar_headers.css',
97 },
Adrià Vilanova Martínezc9a3df12025-02-08 23:16:12 +010098 {
99 origin: './src/features/bulkReportReplies/ui/styles.css',
100 destination: 'css/bulk_report_replies.css',
101 },
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +0100102 ];
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200103
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +0100104 const outputPath = path.join(__dirname, 'dist', env.browser_target);
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200105
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +0100106 const overridenLocalePaths =
Adrià Vilanova Martínez43d0a7b2021-08-28 01:21:17 +0200107 localeOverrides.map(l => '**/_locales/' + l.pontoonLocale);
108
Adrià Vilanova Martínez6c9280e2025-04-06 00:45:03 +0200109 const preprocessorLoader = {
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +0100110 loader: 'webpack-preprocessor-loader',
111 options: {
112 params: {
113 browser_target: env.browser_target,
114 production: args.mode == 'production',
Adrià Vilanova Martínez0335b512022-01-21 13:34:59 +0100115 canary: !!env.canary
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +0100116 },
117 },
118 };
119
Adrià Vilanova Martínez6c9280e2025-04-06 00:45:03 +0200120 const sassLoaderOptions = {
121 // Prefer `dart-sass`
122 implementation: require('sass'),
123 sassOptions: {
124 quietDeps: true,
125 },
126 };
127
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200128 return {
129 entry,
130 output: {
131 filename: '[name].bundle.js',
132 path: outputPath,
Adrià Vilanova Martínez85424b62021-07-11 21:52:00 +0200133 clean: true,
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200134 },
135 plugins: [
Adrià Vilanova Martínezddd30042023-11-01 22:54:17 +0100136 new MiniCssExtractPlugin({
137 filename: '[name].bundle.css',
138 }),
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200139 new WebpackShellPluginNext({
Adrià Vilanova Martíneza03d03a2023-03-11 23:30:07 +0100140 onBuildStart: {
141 scripts: ['make lit_localize_build'],
142 blocking: true,
143 },
Adrià Vilanova Martínezc792c7e2025-02-08 23:16:12 +0100144 }),
145 new WebpackShellPluginNext({
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200146 onBuildEnd: {
147 scripts:
avm99963efce2102021-03-23 23:23:26 +0100148 ['genmanifest -template templates/manifest.gjson -dest ' +
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200149 path.join(outputPath, 'manifest.json') + ' ' +
150 env.browser_target]
Adrià Vilanova Martínezc792c7e2025-02-08 23:16:12 +0100151 },
152 // This makes this command run multiple times when building on watch
153 // mode.
154 dev: false,
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200155 }),
156 new CopyWebpackPlugin({
157 patterns: [
158 {
Adrià Vilanova Martínez9aa29312022-01-16 02:42:46 +0100159 from: path.join(
160 __dirname, 'src/icons', env.canary ? 'canary' : 'regular'),
161 to: path.join(outputPath, 'icons'),
162 },
Adrià Vilanova Martínez9aa29312022-01-16 02:42:46 +0100163 {
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200164 from: path.join(__dirname, 'src/static'),
165 to: outputPath,
166 globOptions: {
Adrià Vilanova Martínez43d0a7b2021-08-28 01:21:17 +0200167 ignore: ['**/OWNERS', '**.md', ...overridenLocalePaths],
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200168 }
169 },
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +0100170 ...getStylesCopyPatterns(styles),
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200171 ]
172 }),
Adrià Vilanova Martínez39f48f82024-09-29 17:55:04 +0200173 new HtmlWebpackPlugin({
174 filename: 'workflows.html',
Adrià Vilanova Martínezed1aba32024-10-26 21:23:12 +0200175 template:
176 'src/features/workflows/presentation/templates/workflows.html.ejs',
Adrià Vilanova Martínez39f48f82024-09-29 17:55:04 +0200177 chunks: ['workflowManager'],
178 }),
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +0200179 new webpack.DefinePlugin({
180 'PRODUCTION': args.mode == 'production',
181 }),
Adrià Vilanova Martínez43d0a7b2021-08-28 01:21:17 +0200182 ...getCopyPluginsForOverridenLocales(outputPath),
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200183 ],
Adrià Vilanova Martínez2df2f242022-03-01 22:25:27 +0100184 devtool: (args.mode == 'production' ? 'source-map' : 'inline-source-map'),
Adrià Vilanova Martínezbbc8d7c2024-04-21 16:28:05 +0200185 resolve: {
186 extensions: ['.tsx', '.ts', '.js', '.json', '.wasm'],
187 },
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200188 module: {
189 rules: [
190 {
Adrià Vilanova Martínezbbc8d7c2024-04-21 16:28:05 +0200191 test: /\.js$/i,
192 use: [
193 preprocessorLoader,
194 ],
195 },
196 {
197 test: /\.tsx?$/,
198 use: [
199 'ts-loader',
200 preprocessorLoader,
201 ],
202 exclude: /node_modules/,
203 },
204 {
avm999632485a3e2021-09-08 22:18:38 +0200205 test: /\.json5$/i,
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200206 type: 'json',
207 parser: {
208 parse: json5.parse,
209 },
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +0100210 use: [
211 preprocessorLoader,
212 ],
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200213 },
avm999632485a3e2021-09-08 22:18:38 +0200214 {
215 test: /\.s[ac]ss$/i,
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +0200216 oneOf: [
avm999632485a3e2021-09-08 22:18:38 +0200217 {
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +0200218 resourceQuery: /string/,
219 use: [
220 'css-loader',
221 {
222 loader: 'sass-loader',
Adrià Vilanova Martínez6c9280e2025-04-06 00:45:03 +0200223 options: sassLoaderOptions,
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +0200224 },
225 ],
226 },
227 {
Adrià Vilanova Martínezddd30042023-11-01 22:54:17 +0100228 resourceQuery: /asCSSFile/,
229 use: [
230 MiniCssExtractPlugin.loader,
231 'css-loader',
232 {
233 loader: 'sass-loader',
Adrià Vilanova Martínez6c9280e2025-04-06 00:45:03 +0200234 options: sassLoaderOptions,
Adrià Vilanova Martínezddd30042023-11-01 22:54:17 +0100235 },
236 ],
237 },
238 {
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +0200239 use: [
240 'style-loader',
241 'css-loader',
242 {
243 loader: 'sass-loader',
Adrià Vilanova Martínez6c9280e2025-04-06 00:45:03 +0200244 options: sassLoaderOptions,
Adrià Vilanova Martínez5f5b3e02023-07-23 00:08:17 +0200245 },
246 ],
avm999632485a3e2021-09-08 22:18:38 +0200247 },
248 ],
249 },
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200250 ]
251 },
Adrià Vilanova Martínez6b560432022-10-23 20:26:17 +0200252 optimization: {
253 minimizer: [
254 new TerserPlugin({
255 terserOptions: {
256 format: {
Adrià Vilanova Martíneza03d03a2023-03-11 23:30:07 +0100257 ascii_only:
258 true, // Due to https://iavm.xyz/b/twpowertools/145#c1
Adrià Vilanova Martínez6b560432022-10-23 20:26:17 +0200259 },
260 },
261 }),
262 ],
263 },
Adrià Vilanova Martínez3465e772021-07-11 19:18:41 +0200264 };
265};
Adrià Vilanova Martínez3b585fd2024-11-10 19:17:31 +0100266
267const getCopyPluginsForOverridenLocales = outputPath => {
268 return localeOverrides.map(l => {
269 return new CopyWebpackPlugin({
270 patterns: [
271 {
272 from: path.join(__dirname, 'src/static/_locales/' + l.pontoonLocale),
273 to: path.join(outputPath, '_locales/' + l.webExtLocale),
274 globOptions: {
275 ignore: ['**/OWNERS', '**.md'],
276 }
277 },
278 ]
279 });
280 });
281};
282
283const getStylesCopyPatterns = styles => {
284 return styles.map(s => {
285 return {
286 from: path.join(__dirname, s.origin),
287 to: s.destination,
288 };
289 });
290}