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:
Robin Malfait
2022-03-17 17:23:29 +01:00
committed by GitHub
parent c9883f6611
commit 8e79f1cb27
9 changed files with 163 additions and 12 deletions
+29 -9
View File
@@ -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
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
ROOT_DIR="$(git rev-parse --show-toplevel)/"
+32
View File
@@ -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')
)
+16
View File
@@ -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
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
node="yarn node"
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# Known variables