Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple entries to output multiple build files #175

Open
fnky opened this issue Aug 2, 2019 · 19 comments · May be fixed by #367
Open

Multiple entries to output multiple build files #175

fnky opened this issue Aug 2, 2019 · 19 comments · May be fixed by #367
Labels
kind: bug Something isn't working kind: feature New feature or request topic: multi-entry Related to multi-entry support

Comments

@fnky
Copy link

fnky commented Aug 2, 2019

Current Behavior

When building source with multiple entries, using --entry src/**.ts the build only uses the source of the first file it finds as the main entry point for ESM and CJS output.

Desired Behavior

It would be nice to be able to specify multiple destinations for different source files from a single codebase.

Suggested Solution

A solution could be to change the behavior of --entry flag, so that instead of outputting only definition files from multiple sources, it should output entry points for each specified entry file.

For example, with a folder structure like this:

src/
  code.ts
  ui.ts

Running tsdx build --entry src/**.ts or --entry src/code.ts src/ui.ts will yield the following output files:

dist/
  code.js
  code.cjs.production.js
  code.cjs.development.js
  code.esm.js
  ui.js
  ui.cjs.production.js
  ui.cjs.development.js
  ui.esm.js

Where code.js and ui.js are similar to index.js for single entry projects.

Who does this impact? Who is this for?

This is useful for building applications, plugins or other types of projects, where multiple entries are required, without having to create a monolithic repo architecture with a custom build process to combine build files.

An example is the recently released Figma Plugin API, which specifies a main file for the underlying plugin code, and a ui file for browser UI part.

See an example project using React and Webpack to create a Figma UI plugin

Describe alternatives you've considered

  • Creating a monorepo and using a custom script to merge the builds into a single folder.
  • Move to a custom setup with webpack that allows for this type of configuration.

Additional context

I was looking for ways to specify multiple entries with --entry as outlined in #28 but it seems to only output source files for the first file it finds and the rest just outputs as definition files, not actual source files. This is a bit confusing and may be a bug as it shares the same property name as webpack (entry), but works differently.

@fnky fnky changed the title Multiple entries not outputting multiple entry points Multiple entries to output multiple build files Aug 2, 2019
@jaredpalmer
Copy link
Owner

This shouldn’t be too tough. Thanks for the write up and use case

@elado
Copy link
Contributor

elado commented Sep 28, 2019

another use case is adding command line tool (package.json bin) to a package in a separate src/cli.ts file.
but here, there's no need to use esm/umd/cjs builds.

tsdx.config.js rollup method returns a single entry per build format (esm/umd/cjs) but would be great to be able to also hook into the final config, so more entries can be injected.

running yarn build --entry src/index.ts --entry src/cli.ts only runs both builds on the same output file, so only the latter is getting in there.

@jaredpalmer
Copy link
Owner

Yep. This should be easy to implement just have to fool around with the cjs entry generation so it does it multiple times

@darthtrevino
Copy link

To follow up with @elado 's comment, if your code uses web-workers at all it would be nice to be able to use multiple entry points split across output files so that worker scripts are separate from everything else.

@yordis
Copy link
Contributor

yordis commented Nov 3, 2019

Related to this I guess,

How could I avoid having one single outputted file for ESM build?

src/
  folder/
    file.ts
  code.ts
  ui.ts
dist/
  folder/
    file.js
  code.js
  ui.js

I am looking for having something like Material UI folks put together, so it is more ESM friendly by default.

@agilgur5
Copy link
Collaborator

agilgur5 commented Dec 12, 2019

So this seems to be a bug caused by the rollup config's output.file being set to the same thing for every entry file:

const outputName = [
`${paths.appDist}/${safePackageName(opts.name)}`,

I created a workaround-ish with tsdx.config.js to support multiple entries:

module.exports = {
  rollup(config, options) {
    const outputDir = process.cwd() + '/dist/'
    const extension = '.' + config.output.file.split('.').slice(1).join('.')
    let filename = config.input.split('src/')[1] // remove src/
    filename = filename.split('.')[0] // remove extension, if any

    config.output.file = outputDir + filename + extension
    console.log(config.output.file)
    // replace / with __ for UMD names
    config.output.name = filename.replace('/', '__')
    return config
  }
}

and this will work with tsdx build --entry src/index.ts --entry src/cli.ts, outputting dist/index.js and dist/cli.js and their respective formats (cjs, esm, etc) and type declarations. EDIT: see next comment regarding CJS "entry file" issues


Buuut besides being very hacky, the output has some issues (possibly minor, pending your use case):

  • The index.ts file is output as index.js instead of ${packageName || nameArg}.js like it normally is. Though it probably makes more sense for the case of multiple entry files to not have a default name. This also applies to UMD names.
  • Entries in a subdirectory will output what seem to be extraneous type declarations, e.g. if you had src/cli/index.ts (instead of src/cli.ts), you will get dist/cli/index.js output correctly, and its types seem to output correctly, but then you'll also get an extraneous output of dist/cli/src/**/*.d.ts that just copies all the type declarations again. If all of your entries are in the same directory (e.g. src/) this doesn't seem to pop up

Also #365 seems directly related to this. Also related to this issue, @yordis created a separate issue #321 for that specific use case above, which I also gave a partial workaround for in #321 (comment)

@agilgur5
Copy link
Collaborator

agilgur5 commented Dec 12, 2019

So I realized there's one other fairly big issue with my workaround:
tsdx only ever outputs one CJS "entry file" (the one that splits between dev & prod builds), so while dist/index.js will be created, dist/cli.js will not be created, only dist/cli.esm.js, dist/cli.cjs.development.js, dist/cli.cjs.production.min.js and dist/cli.d.ts will be (and any other formats you might specify).
There's no way to workaround this in tsdx.config.js, it has to be fixed internally. I submitted a PR (#367) to resolve these issues and make --entry src/index.ts --entry src/cli.ts work correctly without hacky workarounds.

If you're not using CJS though, you don't have a need for CJS entry files, so the hacky workaround could potentially work for you.

EDIT: fixed the duplicate type declarations issue in the PR as well, it similarly can only be fixed internally.

Another issue is that package.json fields like module won't apply for more than one entry, since module only accepts a single file. This could be resolved by creating more package.jsons though... but that's fairly complex of a solution. Directing your users to directly import a .esm.js file or just use the CJS build is the alternative there 😕

@brainkim
Copy link

Does anyone know how to do this just with raw rollup? I’m having trouble deduplicating my own files/making d.ts files show up in the right places.

@ambroseus
Copy link
Contributor

@brainkim guess this would be helpful
https://levelup.gitconnected.com/code-splitting-for-libraries-bundling-for-npm-with-rollup-1-0-2522c7437697

@kevboh
Copy link

kevboh commented Jul 20, 2020

Hello! I just ran into this as well. Would love some way to export a library that also bundles a CLI, and I'm happy to pitch in to make that happen.

KATT added a commit to KATT/tsdx that referenced this issue Sep 17, 2020
I spent ten minutes with adding globs and comma-separated paths before giving up going into the issues and searching/finding jaredpalmer#175 / jaredpalmer#367. 

Maybe delete the `(s)` until the issue is resolved to prevent other people from doing the same. :)
@felixmosh
Copy link
Contributor

Is it possible to use rollup-plugin-multi-input for this?

wilsonshakespeare pushed a commit to wilsonshakespeare/utilzed that referenced this issue Feb 7, 2021
- refactor: Move build command to build.sh
  note: this will allow multiple module build entry files

- feat: Add indexify.js script, this will generate moduleName.js files
  note: this is because tsdx.config.js override do not generate js files

- feat: Add tsdx.config.js to generate multiple esm, cjs modules

- refactor: Move index file out from module folders
  refer jaredpalmer/tsdx#175 (comment)

Important note:
Base on the comment tsdx do not support multiple entry
wilsonshakespeare added a commit to wilsonshakespeare/utilzed that referenced this issue Feb 11, 2021
* chore: Build multiple modules instead of one index.js

- refactor: Move build command to build.sh
  note: this will allow multiple module build entry files

- feat: Add indexify.js script, this will generate moduleName.js files
  note: this is because tsdx.config.js override do not generate js files

- feat: Add tsdx.config.js to generate multiple esm, cjs modules

- refactor: Move index file out from module folders
  refer jaredpalmer/tsdx#175 (comment)

Important note:
Base on the comment tsdx do not support multiple entry

* chore: Update size-limit checker for all modules

* doc: Update CHANGELOG.md and README.md

Co-authored-by: Wilson Lim <[email protected]>
@yaquawa
Copy link

yaquawa commented Apr 6, 2021

Hey guys, I'm happy with using tsup now 👍🏼

@mikestopcontinues
Copy link

Hey, what's the status of this? It looks like it's holding up a lot of projects, judging by the refs.

@fnky
Copy link
Author

fnky commented Apr 27, 2021

@mikestopcontinues It's currently part of the v0.15.0 milestone. Not sure if it's actively worked on at the moment. I have personally moved away from TSDX for now.

@mikestopcontinues
Copy link

Thanks @fnky . I guess I'll stick with microbundle for now, but I'll keep an eye out here. :)

@flybayer
Copy link

I've switched to https://github.com/preconstruct/preconstruct

@y-nk
Copy link

y-nk commented Jun 26, 2021

can't believe it's a year without fixing. @jaredpalmer do you need some help with that?

@ImanMh
Copy link

ImanMh commented Jul 14, 2021

Can somebody from TSDX team mentions if this is totally a bad idea or it's on the roadmap so I can make the best decision about my problem?

@mikestopcontinues
Copy link

@ImanMh At this point, I think you need to look elsewhere. Look into esbuild. It handles typescript, .d.ts files, and multiple entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug Something isn't working kind: feature New feature or request topic: multi-entry Related to multi-entry support
Projects
None yet
Development

Successfully merging a pull request may close this issue.