@tamagui/build 2.1.0 → 2.2.0-1781044625560
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-test$colon$web.log +20 -18
- package/__tests__/fixtures/js-main-package/.turbo/turbo-build.log +1 -1
- package/__tests__/fixtures/simple-package/.turbo/turbo-build.log +1 -1
- package/__tests__/fixtures/simple-package/package.json +1 -0
- package/__tests__/fixtures/simple-package/src/index.ts +22 -0
- package/__tests__/fixtures/simple-package/src/nativeOnly.ts +3 -0
- package/__tests__/fixtures/watch-package/.turbo/turbo-build.log +1 -1
- package/__tests__/integration.test.ts +28 -5
- package/package.json +4 -2
- package/tamagui-build.js +186 -7
|
@@ -9,39 +9,41 @@ $ node ../../../tamagui-build.js --skip-mjs
|
|
|
9
9
|
$ node ../../../tamagui-build.js --skip-sourcemaps
|
|
10
10
|
$ node ../../../tamagui-build.js --ignore-base-url
|
|
11
11
|
stdout | __tests__/integration.test.ts > tamagui-build integration test > should rebuild the package on file change when --watch is used
|
|
12
|
-
Watch process output: built tamagui-build-test-watch-package in
|
|
12
|
+
Watch process output: built tamagui-build-test-watch-package in 79 ms
|
|
13
13
|
|
|
14
14
|
Initial build complete, modifying file...
|
|
15
15
|
|
|
16
16
|
stdout | __tests__/integration.test.ts > tamagui-build integration test > should rebuild the package on file change when --watch is used
|
|
17
|
-
Watch process output: built tamagui-build-test-watch-package in
|
|
17
|
+
Watch process output: built tamagui-build-test-watch-package in 356 ms
|
|
18
18
|
|
|
19
19
|
Rebuild after file modification complete
|
|
20
20
|
|
|
21
21
|
$ node ../../../tamagui-build.js
|
|
22
22
|
$ node ../../../tamagui-build.js
|
|
23
23
|
$ node ../../../tamagui-build.js
|
|
24
|
+
$ node ../../../tamagui-build.js
|
|
24
25
|
$ MINIFY=true node ../../../tamagui-build.js
|
|
25
26
|
$ node ../../../tamagui-build.js
|
|
26
27
|
$ node ../../../tamagui-build.js
|
|
27
28
|
$ node ../../../tamagui-build.js
|
|
28
29
|
$ node ../../../tamagui-build.js
|
|
29
|
-
✓ __tests__/integration.test.ts (
|
|
30
|
-
✓ should build the package correctly
|
|
31
|
-
✓ should bundle the package correctly
|
|
32
|
-
✓ should skip mjs files when --skip-mjs is used
|
|
33
|
-
✓ should skip sourcemaps when --skip-sourcemaps is used
|
|
34
|
-
✓ should ignore base URL when --ignore-base-url is used
|
|
35
|
-
✓ should rebuild the package on file change when --watch is used
|
|
36
|
-
✓ should generate correct platform-specific output
|
|
37
|
-
✓ should
|
|
38
|
-
✓ should
|
|
39
|
-
✓ should
|
|
40
|
-
✓ should
|
|
41
|
-
✓ should keep
|
|
30
|
+
✓ __tests__/integration.test.ts (13 tests) 10843ms
|
|
31
|
+
✓ should build the package correctly 662ms
|
|
32
|
+
✓ should bundle the package correctly 598ms
|
|
33
|
+
✓ should skip mjs files when --skip-mjs is used 654ms
|
|
34
|
+
✓ should skip sourcemaps when --skip-sourcemaps is used 670ms
|
|
35
|
+
✓ should ignore base URL when --ignore-base-url is used 680ms
|
|
36
|
+
✓ should rebuild the package on file change when --watch is used 781ms
|
|
37
|
+
✓ should generate correct platform-specific output 678ms
|
|
38
|
+
✓ should prune imports left unused after platform DCE 724ms
|
|
39
|
+
✓ should keep side-effectful native statements outside dev-only guards 730ms
|
|
40
|
+
✓ should minify the output when MINIFY=true is set 1462ms
|
|
41
|
+
✓ should clean stale outputs before building 1336ms
|
|
42
|
+
✓ should keep only the required js aliases after postprocessing 679ms
|
|
43
|
+
✓ should keep explicit cjs .js mains as final output 1154ms
|
|
42
44
|
|
|
43
45
|
Test Files 1 passed (1)
|
|
44
|
-
Tests
|
|
45
|
-
Start at
|
|
46
|
-
Duration 10.
|
|
46
|
+
Tests 13 passed (13)
|
|
47
|
+
Start at 17:38:08
|
|
48
|
+
Duration 10.96s (transform 41ms, setup 0ms, collect 48ms, tests 10.84s, environment 0ms, prepare 2ms)
|
|
47
49
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ node ../../../tamagui-build.js
|
|
2
|
-
built tamagui-build-test-js-main-package in
|
|
2
|
+
built tamagui-build-test-js-main-package in 1531 ms
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ node ../../../tamagui-build.js
|
|
2
|
-
built tamagui-build-test-simple-tpackage in
|
|
2
|
+
built tamagui-build-test-simple-tpackage in 941 ms
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getNativeOnlyMarker } from './nativeOnly'
|
|
2
|
+
|
|
1
3
|
export { nestedHello } from './nested'
|
|
2
4
|
|
|
3
5
|
export const greet = (name: string): string => {
|
|
@@ -29,6 +31,26 @@ export function getPlatformMarker() {
|
|
|
29
31
|
return process.env.TAMAGUI_TARGET === 'native' ? 'native-only-marker' : 'web-only-marker'
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
export function getNativeImportMarker() {
|
|
35
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
36
|
+
return getNativeOnlyMarker()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return 'web-import-marker'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getNodeEnvMarker() {
|
|
43
|
+
if (process.env.NODE_ENV === 'test') {
|
|
44
|
+
return 'test-env-marker'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (process.env.NODE_ENV === 'development') {
|
|
48
|
+
return 'development-env-marker'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return 'runtime-env-marker'
|
|
52
|
+
}
|
|
53
|
+
|
|
32
54
|
export function applyNativeLogicalMarker(items: string[]) {
|
|
33
55
|
process.env.TAMAGUI_TARGET === 'native' && items.push('native-logical-marker')
|
|
34
56
|
process.env.TAMAGUI_TARGET !== 'native' && items.push('web-logical-marker')
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ node ../../../tamagui-build.js
|
|
2
|
-
built tamagui-build-test-watch-package in
|
|
2
|
+
built tamagui-build-test-watch-package in 548 ms
|
|
@@ -30,7 +30,7 @@ describe('tamagui-build integration test', () => {
|
|
|
30
30
|
beforeAll(() => {
|
|
31
31
|
// Clean up dist directory before starting
|
|
32
32
|
execSync('rm -rf dist && rm -rf types', { cwd: simplePackagePath })
|
|
33
|
-
execSync('rm -rf dist
|
|
33
|
+
execSync('rm -rf dist', { cwd: jsMainPackagePath })
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
it('should build the package correctly', () => {
|
|
@@ -117,10 +117,11 @@ describe('tamagui-build integration test', () => {
|
|
|
117
117
|
await new Promise<void>((resolve, reject) => {
|
|
118
118
|
const timeout = setTimeout(() => {
|
|
119
119
|
reject(new Error('Timeout waiting for build to complete'))
|
|
120
|
-
}, 15000)
|
|
120
|
+
}, 15000)
|
|
121
121
|
|
|
122
122
|
let initialBuildComplete = false
|
|
123
123
|
let fileModified = false
|
|
124
|
+
const replacementGreeting = originalContent.includes('Hi,') ? 'Hey' : 'Hi'
|
|
124
125
|
|
|
125
126
|
watchProcess.stdout.on('data', (data) => {
|
|
126
127
|
console.log('Watch process output:', data.toString())
|
|
@@ -130,7 +131,7 @@ describe('tamagui-build integration test', () => {
|
|
|
130
131
|
console.log('Initial build complete, modifying file...')
|
|
131
132
|
// Modify the source file
|
|
132
133
|
const newContent = `export const greet = (name: string): string => {
|
|
133
|
-
return
|
|
134
|
+
return \`${replacementGreeting}, \${name}!\`;
|
|
134
135
|
};`
|
|
135
136
|
writeFileSync(watchSrcFilePath, newContent)
|
|
136
137
|
fileModified = true
|
|
@@ -138,7 +139,7 @@ describe('tamagui-build integration test', () => {
|
|
|
138
139
|
console.log('Rebuild after file modification complete')
|
|
139
140
|
// Check the updated content of the output file
|
|
140
141
|
const output = readFileSync(watchDistCjsFilePath, 'utf-8')
|
|
141
|
-
expect(output).toContain(
|
|
142
|
+
expect(output).toContain(`${replacementGreeting},`)
|
|
142
143
|
|
|
143
144
|
// Change content back to original
|
|
144
145
|
writeFileSync(watchSrcFilePath, originalContent)
|
|
@@ -150,6 +151,7 @@ describe('tamagui-build integration test', () => {
|
|
|
150
151
|
})
|
|
151
152
|
})
|
|
152
153
|
} finally {
|
|
154
|
+
writeFileSync(watchSrcFilePath, originalContent)
|
|
153
155
|
watchProcess.kill()
|
|
154
156
|
}
|
|
155
157
|
}, 15000)
|
|
@@ -183,6 +185,27 @@ describe('tamagui-build integration test', () => {
|
|
|
183
185
|
expect(nativeOutput).toContain('greet:')
|
|
184
186
|
})
|
|
185
187
|
|
|
188
|
+
it('should prune imports left unused after platform DCE', async () => {
|
|
189
|
+
execSync('bun run build', { cwd: simplePackagePath })
|
|
190
|
+
|
|
191
|
+
const webOutput = await readFile(join(distPath, 'esm', 'index.mjs'), 'utf-8')
|
|
192
|
+
const nativeOutput = await readFile(join(distPath, 'esm', 'index.native.js'), 'utf-8')
|
|
193
|
+
const nativeOnlyOutput = await readFile(
|
|
194
|
+
join(distPath, 'esm', 'nativeOnly.native.js'),
|
|
195
|
+
'utf-8'
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
expect(webOutput).toContain('web-import-marker')
|
|
199
|
+
expect(webOutput).not.toContain('native-import-marker')
|
|
200
|
+
expect(webOutput).not.toContain('getNativeOnlyMarker')
|
|
201
|
+
expect(webOutput).not.toContain('./nativeOnly')
|
|
202
|
+
expect(webOutput).toContain('process.env.NODE_ENV === "test"')
|
|
203
|
+
expect(webOutput).toContain('process.env.NODE_ENV === "development"')
|
|
204
|
+
|
|
205
|
+
expect(nativeOutput).toContain('getNativeOnlyMarker')
|
|
206
|
+
expect(nativeOnlyOutput).toContain('native-import-marker')
|
|
207
|
+
})
|
|
208
|
+
|
|
186
209
|
it('should keep side-effectful native statements outside dev-only guards', async () => {
|
|
187
210
|
execSync('bun run build', { cwd: simplePackagePath })
|
|
188
211
|
|
|
@@ -292,6 +315,6 @@ describe('tamagui-build integration test', () => {
|
|
|
292
315
|
afterAll(() => {
|
|
293
316
|
// Clean up dist directory after tests
|
|
294
317
|
execSync('rm -rf dist && rm -rf types', { cwd: simplePackagePath })
|
|
295
|
-
execSync('rm -rf dist
|
|
318
|
+
execSync('rm -rf dist', { cwd: jsMainPackagePath })
|
|
296
319
|
})
|
|
297
320
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/build",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-1781044625560",
|
|
4
4
|
"gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
|
|
5
5
|
"bin": {
|
|
6
6
|
"tamagui-build": "tamagui-build.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@babel/core": "^7.25.2",
|
|
18
18
|
"@babel/preset-typescript": "^7.26.0",
|
|
19
19
|
"@swc/core": "^1.14.0",
|
|
20
|
-
"@tamagui/babel-plugin-fully-specified": "2.
|
|
20
|
+
"@tamagui/babel-plugin-fully-specified": "2.2.0-1781044625560",
|
|
21
21
|
"@types/fs-extra": "^9.0.13",
|
|
22
22
|
"baseline-browser-mapping": "^2.9.15",
|
|
23
23
|
"chokidar": "^3.5.2",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"fs-extra": "^11.2.0",
|
|
29
29
|
"lodash.debounce": "^4.0.8",
|
|
30
30
|
"oxc-transform": "^0.112.0",
|
|
31
|
+
"picomatch": "4.0.3",
|
|
32
|
+
"rolldown": "1.0.1",
|
|
31
33
|
"typescript": "~5.9.2"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
package/tamagui-build.js
CHANGED
|
@@ -27,6 +27,8 @@ const { transform } = require('@babel/core')
|
|
|
27
27
|
const FSE = require('fs-extra')
|
|
28
28
|
const esbuild = require('esbuild')
|
|
29
29
|
const fastGlob = require('fast-glob')
|
|
30
|
+
const picomatch = require('picomatch')
|
|
31
|
+
const { rolldown } = require('rolldown')
|
|
30
32
|
const createExternalPlugin = require('./externalNodePlugin')
|
|
31
33
|
const debounce = require('lodash.debounce')
|
|
32
34
|
const { basename, dirname } = require('node:path')
|
|
@@ -91,6 +93,183 @@ function dceTamaguiTarget(contents, { format, jsx, platform }) {
|
|
|
91
93
|
return result.code || contents
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
const sideEffectsMatchersCache = new Map()
|
|
97
|
+
const packageSideEffectsCache = new Map()
|
|
98
|
+
const sideEffectsExtensionCandidates = ['.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx']
|
|
99
|
+
|
|
100
|
+
function normalizeSideEffectsSpecifier(specifier) {
|
|
101
|
+
return specifier
|
|
102
|
+
.replace(/[?#].*$/, '')
|
|
103
|
+
.replace(/^\.\/+/, '')
|
|
104
|
+
.replace(/^\/+/, '')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getSideEffectsSpecifierCandidates(specifier) {
|
|
108
|
+
const normalized = normalizeSideEffectsSpecifier(specifier)
|
|
109
|
+
if (!normalized) return []
|
|
110
|
+
|
|
111
|
+
const candidates = [normalized]
|
|
112
|
+
const lastSegment = normalized.split('/').pop() || ''
|
|
113
|
+
const hasKnownExtension = /\.(?:[cm]?js|jsx|tsx?|css|json)$/.test(lastSegment)
|
|
114
|
+
|
|
115
|
+
if (!hasKnownExtension) {
|
|
116
|
+
for (const extension of sideEffectsExtensionCandidates) {
|
|
117
|
+
candidates.push(`${normalized}${extension}`)
|
|
118
|
+
}
|
|
119
|
+
for (const extension of sideEffectsExtensionCandidates) {
|
|
120
|
+
candidates.push(`${normalized}/index${extension}`)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return candidates
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function sideEffectsMatch(sideEffects, specifier) {
|
|
128
|
+
if (sideEffects === true || sideEffects === undefined) return true
|
|
129
|
+
if (sideEffects === false) return false
|
|
130
|
+
if (!Array.isArray(sideEffects)) return true
|
|
131
|
+
|
|
132
|
+
const candidates = getSideEffectsSpecifierCandidates(specifier)
|
|
133
|
+
if (!candidates.length) return false
|
|
134
|
+
|
|
135
|
+
const cacheKey = JSON.stringify(sideEffects)
|
|
136
|
+
let matcher = sideEffectsMatchersCache.get(cacheKey)
|
|
137
|
+
if (!matcher) {
|
|
138
|
+
matcher = picomatch(sideEffects, { dot: true })
|
|
139
|
+
sideEffectsMatchersCache.set(cacheKey, matcher)
|
|
140
|
+
}
|
|
141
|
+
return candidates.some((candidate) => matcher(candidate))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function getPackageNameFromSpecifier(specifier) {
|
|
145
|
+
if (!specifier || specifier.startsWith('.') || specifier.startsWith('/')) return null
|
|
146
|
+
if (specifier.startsWith('node:')) return null
|
|
147
|
+
const parts = specifier.split('/')
|
|
148
|
+
return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function findPackageJsonFromResolvedFile(filePath, packageName) {
|
|
152
|
+
let current = dirname(filePath)
|
|
153
|
+
while (current && current !== dirname(current)) {
|
|
154
|
+
const packageJsonPath = path.join(current, 'package.json')
|
|
155
|
+
if (FSE.existsSync(packageJsonPath)) {
|
|
156
|
+
try {
|
|
157
|
+
const json = FSE.readJSONSync(packageJsonPath)
|
|
158
|
+
if (!packageName || json.name === packageName) {
|
|
159
|
+
return { path: packageJsonPath, json }
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
return null
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
current = dirname(current)
|
|
166
|
+
}
|
|
167
|
+
return null
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function getPackageSideEffects(packageName) {
|
|
171
|
+
if (packageSideEffectsCache.has(packageName)) {
|
|
172
|
+
return packageSideEffectsCache.get(packageName)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let found = null
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
|
|
179
|
+
paths: [process.cwd()],
|
|
180
|
+
})
|
|
181
|
+
found = {
|
|
182
|
+
path: packageJsonPath,
|
|
183
|
+
json: FSE.readJSONSync(packageJsonPath),
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
try {
|
|
187
|
+
const resolved = require.resolve(packageName, {
|
|
188
|
+
paths: [process.cwd()],
|
|
189
|
+
})
|
|
190
|
+
found = findPackageJsonFromResolvedFile(resolved, packageName)
|
|
191
|
+
} catch {
|
|
192
|
+
found = null
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const value = found
|
|
197
|
+
? {
|
|
198
|
+
sideEffects: found.json.sideEffects,
|
|
199
|
+
}
|
|
200
|
+
: null
|
|
201
|
+
|
|
202
|
+
packageSideEffectsCache.set(packageName, value)
|
|
203
|
+
return value
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function moduleHasSideEffects(id) {
|
|
207
|
+
if (id.startsWith('.') || id.startsWith('/')) {
|
|
208
|
+
return sideEffectsMatch(pkg.sideEffects, id)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const packageName = getPackageNameFromSpecifier(id)
|
|
212
|
+
if (!packageName) return true
|
|
213
|
+
|
|
214
|
+
const packageInfo = getPackageSideEffects(packageName)
|
|
215
|
+
if (!packageInfo) return true
|
|
216
|
+
|
|
217
|
+
const subpath = normalizeSideEffectsSpecifier(id.slice(packageName.length))
|
|
218
|
+
return sideEffectsMatch(packageInfo.sideEffects, subpath)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function stripRolldownRegionComments(contents) {
|
|
222
|
+
return contents
|
|
223
|
+
.replace(/^\/\/#region[^\n]*(?:\n|$)/gm, '')
|
|
224
|
+
.replace(/^\/\/#endregion[^\n]*(?:\n|$)/gm, '')
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function pruneUnusedImports(contents, filePath) {
|
|
228
|
+
if (!contents.includes('import')) {
|
|
229
|
+
return contents
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const entryId = `${path.resolve(filePath)}?tamagui-build-prune`
|
|
233
|
+
|
|
234
|
+
const bundle = await rolldown({
|
|
235
|
+
input: entryId,
|
|
236
|
+
external: (id) => id !== entryId,
|
|
237
|
+
platform: 'neutral',
|
|
238
|
+
plugins: [
|
|
239
|
+
{
|
|
240
|
+
name: 'tamagui-build-prune-entry',
|
|
241
|
+
resolveId(id) {
|
|
242
|
+
if (id === entryId) return id
|
|
243
|
+
},
|
|
244
|
+
load(id) {
|
|
245
|
+
if (id === entryId) {
|
|
246
|
+
return {
|
|
247
|
+
code: contents,
|
|
248
|
+
moduleSideEffects: true,
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
treeshake: {
|
|
255
|
+
moduleSideEffects: (id) => moduleHasSideEffects(id),
|
|
256
|
+
},
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
const result = await bundle.generate({
|
|
261
|
+
format: 'esm',
|
|
262
|
+
sourcemap: false,
|
|
263
|
+
comments: false,
|
|
264
|
+
minify: false,
|
|
265
|
+
})
|
|
266
|
+
const chunk = result.output.find((item) => item.type === 'chunk')
|
|
267
|
+
return chunk?.code ? stripRolldownRegionComments(chunk.code) : contents
|
|
268
|
+
} finally {
|
|
269
|
+
await bundle.close?.()
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
94
273
|
function hasFlag(flag) {
|
|
95
274
|
return process.argv.includes(flag)
|
|
96
275
|
}
|
|
@@ -1065,21 +1244,22 @@ async function esbuildWriteIfChanged(
|
|
|
1065
1244
|
}
|
|
1066
1245
|
|
|
1067
1246
|
if (!isMap && path.endsWith('.js')) {
|
|
1247
|
+
const hadTamaguiTarget = contents.includes('process.env.TAMAGUI_TARGET')
|
|
1068
1248
|
contents = dceTamaguiTarget(contents, {
|
|
1069
1249
|
format: opts.format,
|
|
1070
1250
|
jsx: opts.jsx,
|
|
1071
1251
|
platform,
|
|
1072
1252
|
})
|
|
1253
|
+
|
|
1254
|
+
if (isESM && hadTamaguiTarget) {
|
|
1255
|
+
contents = await pruneUnusedImports(contents, path)
|
|
1256
|
+
}
|
|
1073
1257
|
}
|
|
1074
1258
|
|
|
1075
1259
|
if (isESM && pkg.sideEffects !== true && pkg.sideEffects !== undefined) {
|
|
1076
1260
|
const sideEffects = pkg.sideEffects
|
|
1077
1261
|
// sideEffects: false means nothing has side effects, strip all bare imports
|
|
1078
1262
|
// sideEffects: ["*.css", ...] means only matching files have side effects
|
|
1079
|
-
const picomatch = require('picomatch')
|
|
1080
|
-
const matchers = sideEffects === false
|
|
1081
|
-
? null // strip everything
|
|
1082
|
-
: (Array.isArray(sideEffects) ? sideEffects : []).map((p) => picomatch(p))
|
|
1083
1263
|
|
|
1084
1264
|
const result = []
|
|
1085
1265
|
const lines = contents.split('\n')
|
|
@@ -1090,14 +1270,13 @@ async function esbuildWriteIfChanged(
|
|
|
1090
1270
|
result.push(line)
|
|
1091
1271
|
continue
|
|
1092
1272
|
}
|
|
1093
|
-
const specifier = match[1].replace(/^\.\//, '')
|
|
1094
1273
|
// sideEffects: false → strip all bare imports
|
|
1095
|
-
if (
|
|
1274
|
+
if (sideEffects === false) {
|
|
1096
1275
|
result.push('')
|
|
1097
1276
|
continue
|
|
1098
1277
|
}
|
|
1099
1278
|
// sideEffects: [...] → keep if specifier matches any pattern
|
|
1100
|
-
const hasSideEffect =
|
|
1279
|
+
const hasSideEffect = sideEffectsMatch(sideEffects, match[1])
|
|
1101
1280
|
result.push(hasSideEffect ? line : '')
|
|
1102
1281
|
}
|
|
1103
1282
|
|