-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[Roadmap] The future of experimentalCodeSplitting and experimentalDynamicImports #2092
Comments
To be discussed: How to handle IIFE and UMD builds. |
I guess the easiest approach it so just forbid using those with the |
One thing I would like to work on before unflagging is reviewing all the plugin hooks against this again, including transformBundle and if we can do a transformChunk (#2043). Will aim to come back to this one in the next couple of weeks. |
Also basic dynamic import interpolations (#2097) would be good to include ( |
Good thinking, added to the list
I disagree. I think this should be an optional feature and I would prefer to focus on essential, hard-to-change-later aspects here. The list is already very long as it is and I think we should rather focus on putting the final touches to the core parts first. |
Perhaps the input array / string distinction is just a little too non-obvious. Thinking about #2123 further, I'm wondering if we shouldn't have a boolean This would simplify a lot of the logic knowing what type of build we are doing. We could then make an automatic determination of the |
My hope is that in the end, the non-code-splitting case will actually internally be handled as a code-splitting case but with a single chunk and a different chunk-naming logic that uses If dynamic imports are handled separately via their own option |
The other issue here is that the output of I think if we can find a good way to handle this bundle return, then yes inlineDynamicImports would be enough. |
An important update here - This means that instead of I'm in the process of reworking the above into a single rollup build code path though, and will be combining this with the plugin API changes PR. |
But why should Otherwise those options are probably equivalent. |
Sounds awesome! |
@lukastaegert firstly, all targets except globals support dynamic imports, and code-splitting is explicitly disabled for IIFE and UMD targets still entirely. Secondly, there is currently no logic to inline dynamic imports as if they were static imports (eg if two modules dynamic import import the same shared module). Rather the inlining logic is based on inlining the namespace for a module already in the chunk. I guess we could add some new logic to convert dynamic imports into static imports that resolve into promise expressions, but I'm really not sure what use case that would be useful for to justify the development on that. Note that simply defining a manual chunk with the contents of the dynamic import will effectively defer to the vendor chunk already, with the benefit that the vendor chunk doesn't need to be loaded as a static dependency if it isn't used statically. |
I guess you are right in that the implications are probably not worth the effort (+ the additional formats supported in the single file build). So I’m ok with going along with your suggestion, thanks for taking the time to think about mine 😉 Especially since this flag will be rather invisible i.e. only needed when you actually want code splitting when starting with a single entry point. That being said, I would actually expect everyone who uses dynamic imports to want code-splitting so we might think of tweaking the default in the single file case e.g. depending on the presence of the |
We could definitely consider switching to have codeSplitting the default. Perhaps I've actually reworked the logic already (pending PR update) around handling Will hopefully be able to sync the PR by the end of this week with these updates. |
Ah I see! Not what I had in mind originally but this sounds like a really good idea and will definitely lower the barrier to use code-splitting! |
I have somewhat updated the description but the code-splitting section probably needs a little more work |
Quick question regarding code-splitting; is there a way to input an entire directory? I currently have a directory structure as follows: src
├── dir1
│ └── index.js
└── dir2
└── index.js With my rollup config, if I have an input array as follows: const input = ['./src/dir1/index.js', './src/dir2/index.js']; With the lib
├── index.js
└── index2.js This is an undesirable result since I want consumers of the library to be able to do the following in cjs: const Dir1 = require('lib/dir1'); |
@BrainBacon this is a great question, and something we're still working out how to handle best, so appreciated for the feedback. Currently the way to do this would be via That said, it could be nicer of the name guess was better than just |
Another option here could simply be to improve the name guess from |
@guybedford Thank you so much! Hmm yeah this is a complicated problem. My intuition was that if I could specify a directory as the input, then the output I don't know if that helps, but maybe a list of use-case examples can help with working through the problem? |
In my case this would also result in undesirable behavior since some of the directories have multiple JS files in addition to the I can see the following situation ending up breaking that system:
Would result in:
|
@BrainBacon agreed, perhaps just using the input object form is the better approach here? @lukastaegert I've been thinking a little more about the code splitting use of Perhaps we should make the code splitting distinction that |
I guess you are right, rollup IS getting confusing. There seems to be some interest in such a feature. I think the idea that people have is that having input as an array will just build independent bundles using the same options and some sensible naming logic and place the results in Maybe at the same time we get rid of the array form for code-splitting as the object form is superior in most ways? |
@lukastaegert it seems I actually misinterpreted the issue at #1435 in thinking this was building a concatenation of the inputs - instead it seems that the expectation users have around multiple inputs is that they are separate input builds, run one after another. What I would say is that code splitting is in many cases optimal for the use case of many separate input builds (being different to separate output builds for different target environments for example). Code splitting solves the same use case but with the additional feature of shared bundles, which I think might actually a better default for the same use case. That said, we could possibly still have a boolean codesplitting option to switch into a code splitting mode explicitly instead of automatically, even for multiple inputs. I also find an input array very useful myself in bundling simple multiple entrypoint cases as you can just do So I'm tempted to say we leave things as they are with the input after all... will aim to summarize my thoughts in #2126 further with the updates there along these lines. |
@lukastaegert Exactly this! Developing libraries that expose components which can then be loaded individually by requiring the components asynchronously. I am currently using the multiEntry plugin but an out of the box implementation with some nice documentation would be very much appreciated. By the way, yes, things are possible when you use the multiEntry plugin but it is still not at its best. I am still struggling to figure out how to bundle "common" scripts to those individual components for example. |
But this actually sounds like @guybedford's suggestion is more like what you want. Just for reference, these are the two options explained with a small example: Assume you have modules
Following my suggestion,
So you see there is an overlap between the generated files. @guybedford's suggestion, on the other hand, would produce something like the following result:
So the shared dependencies would be automatically extracted in a separate bundle. The current question is if this should be the default behaviour. |
Thanks for the comments @lukastaegert! I guess what I am trying to achieve is even something different.
I would like to invoke
I already know (since I am the one developing the library) that the entry to the application is via SystemJS.import('out/a.js').then((aModule) => {
aModule.bootstrapApplication();
}); I assume SystemJS should be smart enough to load the following files in this case.
Imagine now some What is important here is that the 3rd party script (let's name it
aModule.loadPlugin('3.js');
System.define(['out/b.js']... So SystemJS should also load I partially implemented what is being said. Just had to hack it too much here and there and don't feel very comfortable. I spent days with gulp, achieved what I wanted but was not comfortable with its output. I spent days with webpack, partially achieved what I wanted but the output is terrible. Rollup, I have to be honest here, produces the best output so far but I have the following impressions.
That being said, I have to say thank you for your efforts on open sourcing rollup and spending your valuable time to fix it, improve it, release it. |
I can definitely feel with you here. The problem is that at the moment, we are basically two people taking care of rollup core and some people who kindly took responsibility to maintain some of the plugins but there is noone looking after the documentation. At the moment, @guybedford and myself try to keep the info mostly up to date. But if there is anyone willing to do improvements in this area, this would be more than welcome. And documentation is an easy way to start contributing.
I wonder why, I hope this will improve over time.
Unfortunately, this is not some extravagance but there is a reason for this. Rollup was built around ES modules not only because it is the only "official" JS module format but also because it is the only format that enables us to do the deep analysis and optimizations Rollup is known for. Internally, everything is represented as ES6 modules and I fear there is no easy way to change this as other formats have very different semantics. Of course, only time will tell where Rollup is heading here.
I guess this could easily be improved, maybe it would be worth creating a separate issue for this. Beyond that, @guybedford is working on a new API to emit files but I did not take a look yet in how far this extends to plugins yet. Thanks for the feedback! |
I like that rollup is currently limited to bundling JS and does not try to be a full build system like webpack. IMO you should just use gulp or some other build system for these kinds of tasks. |
I think most of this has been fledged out now and should be part of the next major release. Feel free to reopen if there is more need for discussion. |
This is a collection of ideas what should happen before we deprecate these two
experimental
options. Of course everything here is open to discussion. This description should be updated accordingly including issues tracking individual steps.experimentalDynamicImports
At the moment, this option controls both the parseability of dynamic imports as well as various code snippets dealing with them. As this is still only a stage-3 feature, we should probably not get rid of this option just yet. Nevertheless, the following might make sense:
experimentalDynamicImports
should only control if the corresponding acorn plugin is added but all other checks for this option should be removed. I.e. if the user adds their own acorn plugin to parse this, everything should still work. This will reduce some complexity for us.inlineDynamicImports
to control if dynamic imports are inlined.true
will throw an error (or a warning that the option is ignored)false
. In casefile
is provided, the necessarydir
will be the directory of the output fileexperimentalCodeSplitting
src/rollup/index.ts
but also inGraph.ts
. This is problematic as improvements being made for one workflow will not automatically propagate to the other. With the recent improvements for code-splitting, it should be possible to map the non-code-splitting case to the code-splitting case and get rid of the code path of the former. If there are performance concerns, we should make sure that any additional logic in the code-splitting case executes as quickly as possible in situations where it is not necessary.dir
option:dir
is present, adding thefile
option should produce at least a warning.dir
is present, usingiife
orumd
formats should produce an error.dir
is present, output file names will respect thechunkNames
/entryNames
optionsdir
is missing, providing more than one input should produce an errordir
is missing, providing an alias name for a single input either via CLI orinput
option should produce at least a warningdir
is missing, providing themanualChunks
option should produce an errortransformBundle
transformChunk
hook? transformChunk hook #2043There may be more ideas to add to this list/things to be discussed/things that were missed. Looking forward for feedback. Might make sense to add
experimentalPreserveModules
here as well.The text was updated successfully, but these errors were encountered: