Skip to content

Commit 1109d22

Browse files
committed
Dangerously tweak webpack config
Make the output code cleaner/lighter given browser extensions only work via client client-side
1 parent b20a574 commit 1109d22

File tree

3 files changed

+101
-50
lines changed

3 files changed

+101
-50
lines changed
Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as fs from 'fs'
22
import colors from 'pintor'
3-
import {Compiler} from '@rspack/core'
3+
import {Compiler, DefinePlugin} from '@rspack/core'
44
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'
55
import {EnvPlugin} from './env'
66
import {CleanDistFolderPlugin} from './clean-dist'
@@ -49,51 +49,57 @@ export class CompilationPlugin {
4949
}).apply(compiler)
5050
}
5151

52-
compiler.hooks.done.tapAsync('develop:brand', (stats, done) => {
53-
stats.compilation.name = undefined
54-
55-
// Calculate compilation time
56-
const duration = stats.compilation.endTime! - stats.compilation.startTime!
57-
58-
const manifestName = JSON.parse(
59-
fs.readFileSync(this.manifestPath, 'utf-8')
60-
).name
61-
62-
const hasErrors = stats.hasErrors()
63-
const key = getCompilationKey(manifestName, hasErrors)
64-
const rawLine = messages.boring(manifestName, duration, stats)
65-
if (!rawLine) {
66-
done()
67-
return
68-
}
69-
const line: string = rawLine
70-
71-
// If message repeats, overwrite previous compilation line and append (Nx)
72-
if (key === lastCompilationKey) {
73-
repeatCompilationCount += 1
74-
const suffix = colors.gray(` (${repeatCompilationCount}x) `)
75-
76-
// In TTY, overwrite only from the 3rd time onward to preserve the first blank line after summary
77-
if (process.stdout.isTTY && repeatCompilationCount > 2) {
78-
process.stdout.write('\u001b[1A')
79-
process.stdout.write('\u001b[2K')
80-
process.stdout.write(line + suffix + '\n')
81-
} else {
82-
console.log(line + suffix)
52+
;(new DefinePlugin({
53+
'process.env.NODE_ENV': JSON.stringify(
54+
compiler.options.mode || 'development'
55+
)
56+
}),
57+
compiler.hooks.done.tapAsync('develop:brand', (stats, done) => {
58+
stats.compilation.name = undefined
59+
60+
// Calculate compilation time
61+
const duration =
62+
stats.compilation.endTime! - stats.compilation.startTime!
63+
64+
const manifestName = JSON.parse(
65+
fs.readFileSync(this.manifestPath, 'utf-8')
66+
).name
67+
68+
const hasErrors = stats.hasErrors()
69+
const key = getCompilationKey(manifestName, hasErrors)
70+
const rawLine = messages.boring(manifestName, duration, stats)
71+
if (!rawLine) {
72+
done()
73+
return
8374
}
84-
} else {
85-
// New key: reset counter and print fresh line with newline
86-
lastCompilationKey = key
87-
repeatCompilationCount = 1
88-
89-
// Do not insert extra blank lines; keep messages sequential
90-
if (!printedFirstCompilation) {
91-
printedFirstCompilation = true
75+
const line: string = rawLine
76+
77+
// If message repeats, overwrite previous compilation line and append (Nx)
78+
if (key === lastCompilationKey) {
79+
repeatCompilationCount += 1
80+
const suffix = colors.gray(` (${repeatCompilationCount}x) `)
81+
82+
// In TTY, overwrite only from the 3rd time onward to preserve the first blank line after summary
83+
if (process.stdout.isTTY && repeatCompilationCount > 2) {
84+
process.stdout.write('\u001b[1A')
85+
process.stdout.write('\u001b[2K')
86+
process.stdout.write(line + suffix + '\n')
87+
} else {
88+
console.log(line + suffix)
89+
}
90+
} else {
91+
// New key: reset counter and print fresh line with newline
92+
lastCompilationKey = key
93+
repeatCompilationCount = 1
94+
95+
// Do not insert extra blank lines; keep messages sequential
96+
if (!printedFirstCompilation) {
97+
printedFirstCompilation = true
98+
}
99+
console.log(line)
92100
}
93-
console.log(line)
94-
}
95101

96-
done()
97-
})
102+
done()
103+
}))
98104
}
99105
}

programs/develop/webpack/plugin-js-frameworks/index.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as path from 'path'
2+
import * as fs from 'fs'
23
import {type Compiler} from '@rspack/core'
34
import {PluginInterface} from '../webpack-types'
45
import {maybeUseBabel} from './js-tools/babel'
@@ -31,6 +32,30 @@ export class JsFrameworksPlugin {
3132
const maybeInstallVue = await maybeUseVue(projectPath)
3233
const maybeInstallSvelte = await maybeUseSvelte(projectPath, mode as any)
3334

35+
// Derive transpile targets from extension manifest for leaner output
36+
let targets: string[] = ['chrome >= 100']
37+
38+
try {
39+
const manifest = JSON.parse(fs.readFileSync(this.manifestPath, 'utf-8'))
40+
if (manifest?.minimum_chrome_version) {
41+
targets = [`chrome >= ${manifest.minimum_chrome_version}`]
42+
}
43+
44+
const geckoMin =
45+
manifest?.browser_specific_settings?.gecko?.strict_min_version ||
46+
manifest?.applications?.gecko?.strict_min_version
47+
48+
if (geckoMin) {
49+
const major = parseInt(String(geckoMin).split('.')[0], 10)
50+
51+
if (!Number.isNaN(major)) {
52+
targets.push(`firefox >= ${major}`)
53+
}
54+
}
55+
} catch {
56+
// Fail silently
57+
}
58+
3459
compiler.options.resolve.alias = {
3560
...(maybeInstallBabel?.alias || {}),
3661
...(maybeInstallReact?.alias || {}),
@@ -55,7 +80,7 @@ export class JsFrameworksPlugin {
5580
minify: mode === 'production',
5681
isModule: true,
5782
sourceMap: this.mode === 'development',
58-
env: {targets: ['chrome >= 100']},
83+
env: {targets},
5984
jsc: {
6085
parser: {
6186
syntax: isUsingTypeScript(projectPath)

programs/develop/webpack/webpack-config.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ export default function webpackConfig(
8080
// about requiring a callback when watch is enabled.
8181
watch: false,
8282
devtool:
83-
manifest.manifest_version === 3
84-
? 'cheap-source-map'
85-
: 'eval-cheap-source-map',
83+
(devOptions.mode || 'development') === 'production'
84+
? false
85+
: manifest.manifest_version === 3
86+
? 'cheap-source-map'
87+
: 'eval-cheap-source-map',
8688
output: {
8789
clean: devOptions.output?.clean,
8890
path: userExtensionOutputPath,
@@ -118,7 +120,11 @@ export default function webpackConfig(
118120
'.json',
119121
'.wasm',
120122
'.svelte'
121-
]
123+
],
124+
// Prefer browser fields and conditions; avoid Node-targeted builds
125+
mainFields: ['browser', 'module', 'main'],
126+
conditionNames: ['browser', 'import', 'module', 'default'],
127+
aliasFields: ['browser']
122128
},
123129
watchOptions: {
124130
ignored: /node_modules|dist|extension-js\/profiles/
@@ -230,7 +236,21 @@ export default function webpackConfig(
230236
maxEntrypointSize: 999000
231237
},
232238
optimization: {
233-
minimize: devOptions.mode === 'production'
239+
// Minify only in production to reduce bundle size
240+
minimize: devOptions.mode === 'production',
241+
// Honor package.json sideEffects for better tree-shaking
242+
sideEffects: true,
243+
// Mark used exports globally to help dead-code elimination
244+
usedExports: 'global',
245+
// Merge small modules for smaller, faster bundles
246+
concatenateModules: true,
247+
// Keep a single file per entry (extensions expect static file names)
248+
splitChunks: false,
249+
// Do not extract runtime into a separate chunk (keep runtime inline)
250+
runtimeChunk: false,
251+
// Stable ids for reproducible builds and better caching
252+
moduleIds: 'deterministic',
253+
chunkIds: 'deterministic'
234254
},
235255
experiments: {
236256
// Enable native CSS support by default

0 commit comments

Comments
 (0)