Fix Tree-shaking support (#1247)
* improve Tree Shaking in ESM Instead of bundling everything into a single ESM file, we generate every single file as ESM. This is what we did in 1.4.x as well. I would expect if your library had a single ESM file and you only used 1 function that the application you use it in correctly does the tree-shakign for you. Apparantly a lot of applications are not properly setup for this, so let's create multiple files instead. * update changelog
This commit is contained in:
+29
-9
@@ -1,32 +1,52 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR=$(cd ${0%/*} && pwd -P)
|
||||
|
||||
# Known variables
|
||||
outdir="./dist"
|
||||
SRC='./src'
|
||||
DST='./dist'
|
||||
name="headlessui"
|
||||
input="./src/index.ts"
|
||||
input="./${SRC}/index.ts"
|
||||
|
||||
# Find executables
|
||||
esbuild=$(yarn bin esbuild)
|
||||
tsc=$(yarn bin tsc)
|
||||
resolver="${SCRIPT_DIR}/resolve-files.js"
|
||||
rewriteImports="${SCRIPT_DIR}/rewrite-imports.js"
|
||||
|
||||
# Setup shared options for esbuild
|
||||
sharedOptions=()
|
||||
sharedOptions+=("--bundle")
|
||||
sharedOptions+=("--platform=browser")
|
||||
sharedOptions+=("--target=es2019")
|
||||
|
||||
# Generate actual builds
|
||||
NODE_ENV=production $esbuild $input --format=esm --outfile=$outdir/$name.esm.js --minify ${sharedOptions[@]} $@ &
|
||||
NODE_ENV=production $esbuild $input --format=cjs --outfile=$outdir/$name.prod.cjs --minify ${sharedOptions[@]} $@ &
|
||||
NODE_ENV=development $esbuild $input --format=cjs --outfile=$outdir/$name.dev.cjs ${sharedOptions[@]} $@ &
|
||||
# ESM
|
||||
resolverOptions=()
|
||||
resolverOptions+=($SRC)
|
||||
resolverOptions+=('/**/*.{ts,tsx}')
|
||||
resolverOptions+=('--ignore=.test.,__mocks__')
|
||||
INPUT_FILES=$($resolver ${resolverOptions[@]})
|
||||
|
||||
NODE_ENV=production $esbuild $INPUT_FILES --format=esm --outdir=$DST --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} &
|
||||
NODE_ENV=production $esbuild $input --format=esm --outfile=$DST/$name.esm.js --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} &
|
||||
|
||||
# Common JS
|
||||
NODE_ENV=production $esbuild $input --format=cjs --outfile=$DST/$name.prod.cjs --minify --bundle --pure:React.createElement ${sharedOptions[@]} $@ &
|
||||
NODE_ENV=development $esbuild $input --format=cjs --outfile=$DST/$name.dev.cjs --bundle --pure:React.createElement ${sharedOptions[@]} $@ &
|
||||
|
||||
# Generate types
|
||||
tsc --emitDeclarationOnly --outDir $outdir &
|
||||
tsc --emitDeclarationOnly --outDir $DST &
|
||||
|
||||
# Copy build files over
|
||||
cp -rf ./build/ $outdir
|
||||
cp -rf ./build/ $DST
|
||||
|
||||
# Wait for all the scripts to finish
|
||||
wait
|
||||
|
||||
# Rewrite ESM imports 😤
|
||||
$rewriteImports "$DST" '/**/*.js'
|
||||
|
||||
# Remove test related files
|
||||
rm -rf `$resolver "$DST" '/**/*.{test,__mocks__,}.*'`
|
||||
rm -rf `$resolver "$DST" '/**/test-utils/*'`
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
ROOT_DIR="$(git rev-parse --show-toplevel)/"
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env node
|
||||
let fastGlob = require('fast-glob')
|
||||
|
||||
let parts = process.argv.slice(2)
|
||||
let [args, flags] = parts.reduce(
|
||||
([args, flags], part) => {
|
||||
if (part.startsWith('--')) {
|
||||
flags[part.slice(2, part.indexOf('='))] = part.slice(part.indexOf('=') + 1)
|
||||
} else {
|
||||
args.push(part)
|
||||
}
|
||||
return [args, flags]
|
||||
},
|
||||
[[], {}]
|
||||
)
|
||||
|
||||
flags.ignore = flags.ignore ?? ''
|
||||
flags.ignore = flags.ignore.split(',').filter(Boolean)
|
||||
|
||||
console.log(
|
||||
fastGlob
|
||||
.sync(args.join(''))
|
||||
.filter((file) => {
|
||||
for (let ignore of flags.ignore) {
|
||||
if (file.includes(ignore)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
.join('\n')
|
||||
)
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
let fs = require('fs')
|
||||
let path = require('path')
|
||||
let fastGlob = require('fast-glob')
|
||||
|
||||
console.time('Rewrote imports in')
|
||||
fastGlob.sync([process.argv.slice(2).join('')]).forEach((file) => {
|
||||
file = path.resolve(process.cwd(), file)
|
||||
let content = fs.readFileSync(file, 'utf8')
|
||||
let result = content.replace(/from([^"']*?)(["'])\.(.*?)\2/g, 'from$1".$3.js"')
|
||||
if (result !== content) {
|
||||
fs.writeFileSync(file, result, 'utf8')
|
||||
}
|
||||
})
|
||||
console.timeEnd('Rewrote imports in')
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
node="yarn node"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Known variables
|
||||
|
||||
Reference in New Issue
Block a user