Open fnky opened 5 years ago
This shouldn’t be too tough. Thanks for the write up and use case
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.
Yep. This should be easy to implement just have to fool around with the cjs entry generation so it does it multiple times
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.
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.
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:
https://github.com/jaredpalmer/tsdx/blob/d621994f3eb21b6f686cccf7170ba541e72886c3/src/createRollupConfig.ts#L32-L33
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):
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.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 upAlso #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 https://github.com/jaredpalmer/tsdx/issues/321#issuecomment-564784332
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.json
s 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 😕
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.
@brainkim guess this would be helpful https://levelup.gitconnected.com/code-splitting-for-libraries-bundling-for-npm-with-rollup-1-0-2522c7437697
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.
Is it possible to use rollup-plugin-multi-input
for this?
Hey, what's the status of this? It looks like it's holding up a lot of projects, judging by the refs.
@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.
Thanks @fnky . I guess I'll stick with microbundle for now, but I'll keep an eye out here. :)
I've switched to https://github.com/preconstruct/preconstruct
can't believe it's a year without fixing. @jaredpalmer do you need some help with that?
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?
@ImanMh At this point, I think you need to look elsewhere. Look into esbuild. It handles typescript, .d.ts files, and multiple entries.
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:
Running
tsdx build --entry src/**.ts
or--entry src/code.ts src/ui.ts
will yield the following output files:Where
code.js
andui.js
are similar toindex.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
Additional context
I was looking for ways to specify multiple entries with
--entry
as outlined in https://github.com/palmerhq/tsdx/pull/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.