Skip to content

Multiple entries are merged into single build configuration, making per-entry configuration impossible #15

@thedanchez

Description

@thedanchez

Description

When using multiple entries in the preset options, the generated tsup configurations merge all entries into a single object, making it impossible to apply different configurations to different entries. An example of this would be

Current Behavior

When using multiple entries like this:

import * as preset from "tsup-preset-solid";

const options: preset.PresetOptions = {
  entries: [
    {
      entry: "src/index.tsx",
    },
    {
      name: "testUtils",
      entry: "src/testUtils/index.tsx",
    }
  ]
};

Using preset.parsePresetOptions(options), yields me the following result:

[
  {
    target: 'esnext',
    platform: 'browser',
    format: 'esm',
    clean: true,
    dts: true,
    entry: {
      'index/index': 'src/index.tsx',
      'testUtils/index': 'src/testUtils/index.tsx'
    },
    outDir: 'dist/',
    treeshake: { preset: 'safest' },
    replaceNodeEnv: true,
    esbuildOptions: [Function: esbuildOptions],
    outExtension: [Function: outExtension],
    esbuildPlugins: [ [Object] ]
  },
  {
    target: 'esnext',
    platform: 'browser',
    format: 'esm',
    clean: false,
    dts: undefined,
    entry: {
      'index/index': 'src/index.tsx',
      'testUtils/index': 'src/testUtils/index.tsx'
    },
    outDir: 'dist/',
    treeshake: { preset: 'safest' },
    replaceNodeEnv: true,
    esbuildOptions: [Function: esbuildOptions],
    outExtension: [Function: outExtension],
    esbuildPlugins: []
  }
]

From the above, it looks like we get two outputs where one has DTS as true and the other undefined -- in other words, one is defined for types and the other is not.

If say, I wanted to go ahead and add custom option configuration depending on the target name like so, I cannot do it:

const tsupOptions = preset
    .generateTsupOptions(parsedOptions)
    .map((tsupOption) => {
      // tsupOption.name is always undefined
      if (tsupOption.name === "testUtils") {
        return { name: "@org/solid/testUtils", ...tsupOption };
      }

      return { name: "@org/solid", minify: true, ...tsupOption };
    });

Expected Behavior

Unless I'm missing something, each entry should generate its own build configuration, allowing for per-entry customization (or perhaps make this behavior configurable by adding some option to tsup-preset-solid to allow for it):

[
  {
    entry: { 'index/index': 'src/index.tsx' },
    dts: true
  },
  {
    entry: { 'index/index': 'src/index.tsx' },
    dts: undefined
  },
  {
    name: "testUtils",
    entry: { 'testUtils/index': 'src/testUtils/index.tsx' },
    dts: true,
  },
  {
    name: "testUtils",
    entry: { 'testUtils/index': 'src/testUtils/index.tsx' },
    dts: undefined,
  },
]

Moreover on the above, after generating the tsup options via preset.generateTsupOptions, I would expect the name value to be populated so that each one can be identified.

Additional Context

The package.json exports are generated correctly with separate paths for each entry, but the build configurations don't maintain this separation.

Last Thoughts

Feel free to correct me if I have the wrong impression of how all of this is supposed to work. I'm still something of an "advanced beginner" when it comes to bundling and I may be suggesting something unhealthy here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions