@tamagui/build 1.0.0-beta.8 → 1.0.1-beta.100

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.
@@ -1 +1 @@
1
- @tamagui/build:build: cache hit, replaying output 3f5beff4d742f14f
1
+ @tamagui/build:build: cache hit, replaying output a900829022675b0c
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/build",
3
- "version": "1.0.0-beta.8",
3
+ "version": "1.0.1-beta.100",
4
4
  "bin": {
5
5
  "tamagui-build": "tamagui-build.js"
6
6
  },
@@ -13,12 +13,12 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "chokidar": "^3.5.2",
16
- "esbuild": "^0.14.36",
16
+ "esbuild": "^0.14.48",
17
17
  "execa": "^5.0.0",
18
- "fast-glob": "^3.2.7",
19
- "fs-extra": "^9.1.0",
20
- "json5": "^2.2.0",
21
- "typescript": "^4.5.2"
18
+ "fast-glob": "^3.2.11",
19
+ "fs-extra": "^10.1.0",
20
+ "lodash.debounce": "^4.0.8",
21
+ "typescript": "^4.7.4"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/fs-extra": "^9.0.13"
package/tamagui-build.js CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  const exec = require('execa')
4
4
  const fs = require('fs-extra')
5
- const json5 = require('json5')
6
5
  const esbuild = require('esbuild')
7
6
  const fg = require('fast-glob')
8
7
  const createExternalPlugin = require('./externalNodePlugin')
8
+ const debounce = require('lodash.debounce')
9
+ const { dirname } = require('path')
9
10
 
10
11
  const jsOnly = !!process.env.JS_ONLY
11
12
  const skipJS = !!(process.env.SKIP_JS || false)
@@ -15,181 +16,201 @@ const shouldCleanBuildOnly = !!process.argv.includes('clean:build')
15
16
  const shouldWatch = process.argv.includes('--watch')
16
17
 
17
18
  const pkg = fs.readJSONSync('./package.json')
19
+ let shouldSkipInitialTypes = !!process.env.SKIP_TYPES_INITIAL
20
+ const pkgMain = pkg.main
21
+ const pkgModule = pkg.module
22
+ const pkgModuleJSX = pkg['module:jsx']
18
23
 
19
- if (shouldClean || shouldCleanBuildOnly) {
20
- ;(async () => {
21
- try {
22
- await Promise.allSettled([fs.remove('.turbo'), fs.remove('types'), fs.remove('dist')])
23
- } catch {}
24
- if (shouldCleanBuildOnly) {
25
- console.log( cleaned', pkg.name)
26
- process.exit(0)
27
- }
28
- try {
29
- await Promise.allSettled([fs.remove('node_modules')])
30
- } catch {}
24
+ const flatOut = [pkgMain, pkgModule, pkgModuleJSX].filter(Boolean).length === 1
25
+
26
+ async function clean() {
27
+ try {
28
+ await Promise.allSettled([fs.remove('.turbo'), fs.remove('types'), fs.remove('dist')])
29
+ } catch {}
30
+ if (shouldCleanBuildOnly) {
31
31
  console.log('» cleaned', pkg.name)
32
32
  process.exit(0)
33
- })()
34
- } else {
35
- let shouldSkipInitialTypes = !!process.env.SKIP_TYPES_INITIAL
33
+ }
34
+ try {
35
+ await Promise.allSettled([fs.remove('node_modules')])
36
+ } catch {}
37
+ console.log('» cleaned', pkg.name)
38
+ process.exit(0)
39
+ }
36
40
 
37
- const pkgMain = pkg.main
38
- const pkgModule = pkg.module
41
+ if (shouldClean || shouldCleanBuildOnly) {
42
+ clean().then(() => {
43
+ process.exit(0)
44
+ })
45
+ return
46
+ }
39
47
 
40
- async function build() {
41
- console.log('»', pkg.name)
42
- const x = Date.now()
43
- let files = (await fg(['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.css'])).filter(
44
- (x) => !x.includes('.d.ts')
45
- )
48
+ if (shouldWatch) {
49
+ process.env.IS_WATCHING = true
50
+ process.env.DISABLE_AUTORUN = true
51
+ build().then(() => {
52
+ const rebuild = debounce(build, 100)
53
+ const chokidar = require('chokidar')
54
+ chokidar
55
+ // prevent infinite loop but cause race condition if you just build directly
56
+ .watch('src', {
57
+ persistent: true,
58
+ alwaysStat: true,
59
+ ignoreInitial: true,
60
+ })
61
+ .on('change', rebuild)
62
+ .on('add', rebuild)
63
+ })
64
+ return
65
+ }
46
66
 
47
- if (process.env.NO_CLEAN) {
48
- console.log('skip typecheck')
49
- } else {
50
- fs.existsSync('tsconfig.tsbuildinfo') && fs.rmSync('tsconfig.tsbuildinfo')
51
- }
67
+ build()
52
68
 
53
- async function buildTsc() {
54
- if (jsOnly || shouldSkipTypes) return
55
- if (shouldSkipInitialTypes) {
56
- shouldSkipInitialTypes = false
57
- return
58
- }
69
+ async function build() {
70
+ if (process.env.DEBUG) console.log('»', pkg.name)
71
+ try {
72
+ const start = Date.now()
73
+ await Promise.all([
74
+ //
75
+ buildTsc(),
76
+ buildJs(),
77
+ ])
78
+ console.log('built', pkg.name, 'in', Date.now() - start, 'ms')
79
+ } catch (error) {
80
+ console.error(`Error building:`, error.message)
81
+ }
82
+ }
59
83
 
60
- // NOTE:
61
- // for Intellisense to work in monorepo you need baseUrl: "../.."
62
- // but to build things nicely we need here to reset a few things:
63
- // baseUrl: ., outDir: types, rootDir: src
64
- // now we can have the best of both worlds
84
+ async function buildTsc() {
85
+ if (jsOnly || shouldSkipTypes) return
86
+ if (shouldSkipInitialTypes) {
87
+ shouldSkipInitialTypes = false
88
+ return
89
+ }
65
90
 
66
- // NOTE: to get intellisense to *not* suggest importing from the index file when it re-exports another package...
67
- // (like tamagui does with @tamagui/core...)
68
- // we add `exclude: ['src/index.ts']` to the tsconfig.json which fixes that
69
- // but then it causes it to not export the types out from index... so....
70
- // we do a stupid, stupid thing to re-write it temporarily without it before build. then restore it after
71
- // honestly hate typescript config all around but this seems to work so fuck it
72
- const tsConfOg = await fs.readFile('tsconfig.json')
73
- const tsConfJSON = json5.parse(tsConfOg)
74
- if (tsConfJSON.exclude && tsConfJSON.exclude.includes('src/index.ts')) {
75
- tsConfJSON.exclude = tsConfJSON.exclude.filter((x) => x !== 'src/index.ts')
76
- await fs.writeJSON('tsconfig.json', tsConfJSON)
77
- }
78
- try {
79
- await exec('npx', [
80
- 'tsc',
81
- '--baseUrl',
82
- '.',
83
- '--outDir',
84
- 'types',
85
- '--rootDir',
86
- 'src',
87
- '--declaration',
88
- '--emitDeclarationOnly',
89
- '--declarationMap',
90
- ])
91
- } finally {
92
- // restore
93
- await fs.writeFile('tsconfig.json', tsConfOg)
94
- }
95
- }
91
+ function buildNoMap() {
92
+ return exec(
93
+ 'npx',
94
+ `tsc --baseUrl . --outDir types --rootDir src --declaration --emitDeclarationOnly`.split(' ')
95
+ )
96
+ }
96
97
 
97
- const externalPlugin = createExternalPlugin({
98
- skipNodeModulesBundle: true,
99
- })
98
+ function buildWithMap() {
99
+ return exec(
100
+ 'npx',
101
+ `tsc --baseUrl . --outDir types --rootDir src --declaration --emitDeclarationOnly --declarationMap`.split(
102
+ ' '
103
+ )
104
+ )
105
+ }
100
106
 
101
- try {
102
- await Promise.all([
103
- buildTsc(),
104
- ...(skipJS
105
- ? []
106
- : [
107
- pkgMain
108
- ? esbuild
109
- .build({
110
- entryPoints: files,
111
- outdir: 'dist/cjs',
112
- bundle: false,
113
- sourcemap: true,
114
- target: 'node14',
115
- keepNames: true,
116
- format: 'cjs',
117
- color: true,
118
- logLevel: 'error',
119
- plugins: [externalPlugin],
120
- minify: false,
121
- platform: 'node',
122
- })
123
- .then(() => {
124
- console.log(' >-> commonjs')
125
- })
126
- : null,
127
- // dont bundle for tree shaking
128
- pkgModule
129
- ? esbuild
130
- .build({
131
- entryPoints: files,
132
- outdir: 'dist/esm',
133
- sourcemap: true,
134
- target: 'es2019',
135
- keepNames: true,
136
- format: 'esm',
137
- color: true,
138
- logLevel: 'error',
139
- minify: false,
140
- platform: 'neutral',
141
- })
142
- .then(() => {
143
- console.log(' >-> esm')
144
- })
145
- : null,
146
- esbuild
147
- .build({
148
- // only diff is jsx preserve and outdir
149
- jsx: 'preserve',
150
- outdir: 'dist/jsx',
151
- entryPoints: files,
152
- sourcemap: false,
153
- target: 'es2019',
154
- keepNames: true,
155
- format: 'esm',
156
- color: true,
157
- logLevel: 'error',
158
- minify: false,
159
- platform: 'neutral',
160
- })
161
- .then(() => {
162
- console.log(' >-> jsx')
163
- }),
164
- ]),
165
- ])
166
- } catch (error) {
167
- console.log('error', error)
168
- } finally {
169
- console.log('built in', `${(Date.now() - x) / 1000}s`)
107
+ // NOTE:
108
+ // for Intellisense to work in monorepo you need baseUrl: "../.."
109
+ // but to build things nicely we need here to reset a few things:
110
+ // baseUrl: ., outDir: types, rootDir: src
111
+ // for best of both worlds
112
+ try {
113
+ await buildWithMap()
114
+ } finally {
115
+ // if no types folder, patch a typescript bug...
116
+ if (!(await fs.pathExists('types'))) {
117
+ console.warn('BUG re-run without declaration first fixes no output bug...')
118
+ await buildNoMap()
119
+ await buildWithMap()
170
120
  }
171
121
  }
122
+ }
172
123
 
173
- if (shouldWatch) {
174
- const path = require('path')
175
- process.env.IS_WATCHING = true
176
- process.env.DISABLE_AUTORUN = true
177
- build().then(() => {
178
- const finish = (_, path, stats) => {
179
- build()
180
- }
181
- const chokidar = require('chokidar')
182
- chokidar
183
- // prevent infinite loop but cause race condition if you just build directly
184
- .watch('src', {
185
- persistent: true,
186
- alwaysStat: true,
187
- ignoreInitial: true,
124
+ async function buildJs() {
125
+ if (skipJS) {
126
+ return
127
+ }
128
+ let files = (await fg(['src/**/*.(m)?ts(x)?', 'src/**/*.css'])).filter(
129
+ (x) => !x.includes('.d.ts')
130
+ )
131
+ const externalPlugin = createExternalPlugin({
132
+ skipNodeModulesBundle: true,
133
+ })
134
+ const start = Date.now()
135
+ return await Promise.all([
136
+ pkgMain
137
+ ? esbuildWriteIfChanged({
138
+ entryPoints: files,
139
+ outdir: flatOut ? 'dist' : 'dist/cjs',
140
+ bundle: false,
141
+ sourcemap: true,
142
+ target: 'node14',
143
+ keepNames: false,
144
+ format: 'cjs',
145
+ color: true,
146
+ logLevel: 'error',
147
+ plugins: [externalPlugin],
148
+ minify: false,
149
+ platform: 'node',
188
150
  })
189
- .on('change', finish)
190
- .on('add', finish)
191
- })
151
+ : null,
152
+ // dont bundle for tree shaking
153
+ pkgModule
154
+ ? esbuildWriteIfChanged({
155
+ entryPoints: files,
156
+ outdir: flatOut ? 'dist' : 'dist/esm',
157
+ sourcemap: true,
158
+ target: 'node16',
159
+ keepNames: false,
160
+ format: 'esm',
161
+ color: true,
162
+ logLevel: 'error',
163
+ minify: false,
164
+ platform: 'neutral',
165
+ })
166
+ : null,
167
+ pkgModuleJSX
168
+ ? esbuildWriteIfChanged({
169
+ // only diff is jsx preserve and outdir
170
+ jsx: 'preserve',
171
+ outdir: flatOut ? 'dist' : 'dist/jsx',
172
+ entryPoints: files,
173
+ sourcemap: true,
174
+ target: 'es2019',
175
+ keepNames: false,
176
+ format: 'esm',
177
+ color: true,
178
+ logLevel: 'error',
179
+ minify: false,
180
+ platform: 'neutral',
181
+ })
182
+ : null,
183
+ ]).then(() => {
184
+ if (process.env.DEBUG) console.log(`built js in ${Date.now() - start}ms`)
185
+ })
186
+ }
187
+
188
+ /**
189
+ * esbuild but avoids touching unchanged files to not freak out vite
190
+ * @param {esbuild.BuildOptions} opts
191
+ * @returns {Promise<void>}
192
+ */
193
+ async function esbuildWriteIfChanged(opts) {
194
+ if (shouldWatch) {
195
+ const built = await esbuild.build({ ...opts, write: false })
196
+ if (!built.outputFiles) {
197
+ return
198
+ }
199
+ await Promise.all(
200
+ built.outputFiles.map(async (file) => {
201
+ const outDir = dirname(file.path)
202
+ await fs.ensureDir(outDir)
203
+ const outString = new TextDecoder().decode(file.contents)
204
+ if (
205
+ !(await fs.pathExists(file.path)) ||
206
+ (await fs.readFile(file.path, 'utf8')) !== outString
207
+ ) {
208
+ // console.log('write', file.path)
209
+ await fs.writeFile(file.path, outString)
210
+ }
211
+ })
212
+ )
192
213
  } else {
193
- build()
214
+ await esbuild.build(opts)
194
215
  }
195
216
  }