egoist / tsup

The simplest and fastest way to bundle your TypeScript libraries.
https://tsup.egoist.dev
MIT License
8.46k stars 209 forks source link

quirky config behavior when handling "use client" flags #1106

Open DopamineDriven opened 2 months ago

DopamineDriven commented 2 months ago

The following config preserves all "use client" flags for react files containing this flag but it is not clear why this is the case.

import { relative } from "path";
import { defineConfig, type Options } from "tsup";
// prettier-ignore
const tsupConfig = (options: Options) => ({
  // esbuildOptions: (options, _) => {
  //   options.keepNames = true;
  //   options.minifyIdentifiers = false;
  // },
  // minifyIdentifiers: false,
  // banner: { js: '"use client"' },
  entry: ["src/**/*.ts", "src/**/*.tsx", "src/globals.css", "src/tailwind.cjs","!src/fs/**/*.{ts,json}"],
  target: ["esnext"],
  external: ["react"],
  experimentalDts: true,
  watch: process.env.NODE_ENV === "development",
  keepNames: true,
  shims: true,
  bundle: true,
  format: ["cjs", "esm"],
  tsconfig: relative(process.cwd(), "tsconfig.json"),
  clean: true,
  outDir: "dist",
  ...options
} satisfies Options);

export default defineConfig(tsupConfig);

however, if I uncomment the commented out code block as follows

import { relative } from "path";
import { defineConfig, type Options } from "tsup";
// prettier-ignore
const tsupConfig = (options: Options) => ({
  esbuildOptions: (options, _) => {
    options.keepNames = true;
    options.minifyIdentifiers = false;
  },
  minifyIdentifiers: false,
  banner: { js: '"use client"' },
  entry: ["src/**/*.ts", "src/**/*.tsx", "src/globals.css", "src/tailwind.cjs","!src/fs/**/*.{ts,json}"],
  target: ["esnext"],
  external: ["react"],
  experimentalDts: true,
  watch: process.env.NODE_ENV === "development",
  keepNames: true,
  shims: true,
  bundle: true,
  format: ["cjs", "esm"],
  tsconfig: relative(process.cwd(), "tsconfig.json"),
  clean: true,
  outDir: "dist",
  ...options
} satisfies Options);

export default defineConfig(tsupConfig);

It now applies the "use client" flag to every single output file which is of course undesired behavior


Lastly, if I remove the commented out code as follows

import { relative } from "path";
import { defineConfig, type Options } from "tsup";
// prettier-ignore
const tsupConfig = (options: Options) => ({
  entry: ["src/**/*.ts", "src/**/*.tsx", "src/globals.css", "src/tailwind.cjs","!src/fs/**/*.{ts,json}"],
  target: ["esnext"],
  external: ["react"],
  experimentalDts: true,
  watch: process.env.NODE_ENV === "development",
  keepNames: true,
  shims: true,
  bundle: true,
  format: ["cjs", "esm"],
  tsconfig: relative(process.cwd(), "tsconfig.json"),
  clean: true,
  outDir: "dist",
  ...options
} satisfies Options);

export default defineConfig(tsupConfig);

it doesn't preserve any "use client" flags in the output code at all

I am thoroughly confused as to why having the commented-out block of config options does the trick when it comes to properly preserving the "use client" flag (for targeted files containing this flag only)


{
  "name": "@takeda-digital/ui",
  "version": "10.0.0",
  "files": [
    "dist/**/*.{js,cjs,d.ts,d.cts,css}"
  ],
  "license": "MIT",
  "sideEffects": true,
  "type": "module",
  "prettier": {
    "$schema": "http://json.schemastore.org/prettierrc",
    "plugins": [
      "prettier-plugin-tailwindcss",
      "prettier-plugin-organize-imports"
    ],
    "arrowParens": "avoid",
    "jsxSingleQuote": true,
    "bracketSameLine": true,
    "bracketSpacing": true,
    "singleQuote": false,
    "useTabs": false,
    "trailingComma": "none",
    "semi": true,
    "printWidth": 80,
    "tabWidth": 2
  },
  "typesVersions": {
    "*": {
      "*": [
        "dist/*.d.ts",
        "dist/*.d.cts",
        "dist/*/index.d.ts"
      ],
      "tailwind": [
        "dist/tailwind.d.cts"
      ]
    }
  },
  "publishConfig": {
    "access": "restricted",
    "registry": "https://takedaawsuseast.jfrog.io/REDACTED/",
    "typesVersions": {
      "*": {
        "*": [
          "dist/*.d.ts",
          "dist/*.d.cts",
          "dist/*/index.d.ts"
        ],
        "tailwind": [
          "dist/tailwind.d.cts"
        ]
      }
    }
  },
  "source": "src/index.tsx",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": "./dist/index.js",
    "./*": "./dist/*.js",
    "./tailwind": {
      "require": "./dist/tailwind.cjs"
    },
    "./index.css": "./dist/index.css",
    "./globals.css": "./dist/globals.css"
  },
  "scripts": {
    "lint": "TIMING=1 eslint . --ext .js,.jsx,.ts,.tsx",
    "dev": "pnpm build",
    "prebuild": "tsx src/fs/script.ts",
    "build": "rm -rf dist && tsup",
    "publish": "npm publish",
    "postbuild": "tsx src/fs/postscript.ts"
  },
  "peerDependencies": {
    "next": "^14.1.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "dependencies": {
    "@swc/helpers": "^0.5.8",
    "clsx": "^2.1.0",
    "tailwind-merge": "^2.2.2"
  },
  "devDependencies": {
    "@microsoft/api-extractor": "^7.43.0",
    "@swc/core": "^1.4.13",
    "@swc/wasm": "^1.4.13",
    "@tailwindcss/forms": "^0.5.7",
    "@tailwindcss/typography": "^0.5.12",
    "@types/node": "^20.12.7",
    "@types/react": "^18.2.75",
    "@types/react-dom": "^18.2.24",
    "autoprefixer": "^10.4.19",
    "chokidar": "^3.6.0",
    "eslint": "^8.57.0",
    "eslint-config-custom": "workspace:*",
    "eslint-config-next": "^14.1.4",
    "next": "^14.1.4",
    "postcss": "^8.4.38",
    "postcss-focus-visible": "^9.0.1",
    "postcss-import": "^16.1.0",
    "prettier": "^3.2.5",
    "prettier-plugin-organize-imports": "^3.2.4",
    "prettier-plugin-tailwindcss": "^0.5.13",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "tailwindcss": "^3.4.3",
    "tailwindcss-animate": "^1.0.7",
    "terser": "^5.30.3",
    "tslib": "^2.6.2",
    "tsup": "^8.0.2",
    "tsx": "^4.7.2",
    "typescript": "^5.4.4"
  }
}
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "baseUrl": ".",
    "outDir": "dist",
    "lib": ["dom", "dom.iterable", "esnext"],
    "declaration": true,
    "allowJs": true,
    "checkJs": true,
    "strictBindCallApply": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "noStrictGenericChecks": false,
    "skipLibCheck": true,
    "alwaysStrict": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "jsx": "react-jsx"
  },
  "include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "**/*.d.ts"]
}

- node version: 20.12.2
- npm version: 10.5.0

Upvote & Fund

Fund with Polar