-
-
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
Allow injecting Acorn plugins #1857
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to have this feature, thanks for the PR.
src/Module.ts
Outdated
@@ -45,9 +45,10 @@ export interface CommentDescription { block: boolean, text: string, start: numbe | |||
export interface ExportDescription { localName: string, identifier?: string } | |||
export interface ReexportDescription { localName: string, start: number, source: string, module: Module } | |||
|
|||
function tryParse (module: Module, acornOptions: Object) { | |||
function tryParse (module: Module, acornOptions: Object, acornInjects: Function[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These injections don't need to happen for every module parse - rather the acornInjects.reduce(acc, plugin) => plugin(acc))
step can be done in the Graph constructor I think rather?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acorn plugins are not composable in that they expect the acorn
object to be passed as an argument (example). I think I'll need to import acorn
in Graph.js
, produce the final acorn
object there, and then pass it to tryParse
. Sound good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds sensible! Alternatively because we have live bindings in ES Modules, it could be possible to have Graph.ts explicitly export its own acorn variable which is imported by Module.ts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually that said, much better to have class-level encapsulation actually here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to figure out how to pass the entire acorn
object to tryParse
. I think it's related to the fact that it's declared as a namespace in @types/acorn, but I don't know TypeScript well enough to know for sure.
I ended up passing the parse
function instead.
src/rollup/index.ts
Outdated
@@ -61,6 +61,7 @@ export interface InputOptions { | |||
}; | |||
|
|||
acorn?: {}; | |||
acornInjects?: Function[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just calling this acornPlugins
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to change the name as you see fit. I chose acornInjects
to avoid the confusion between acorn.plugins
(where plugins are enabled, e.g. asyncIteration: true
) and acornPlugins
(where plugin functions would be passed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm perhaps acornInjectPlugins
to be clearer then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed this field to acornInjectPlugins
. I can also rename it to acronPlugins
if you prefer; perhaps it's not really all that confusing. I'll leave the final decision to you. Thanks.
8f63cd8
to
34b2022
Compare
I added a few tests. I wasn't quite sure where to put them, so I went for |
@guybedford This is ready for your review. Once approved, I'd like to squash this into a single commit and update the commit message with the new name for |
@stasm looks great to me and thanks for padding out the tests. There's on issue with the internal plugin we're applying for dynamic import - the line at https://github.com/rollup/rollup/pull/1857/files#diff-356410863c3a18aee7d09896d52d6b08R1 should be possible to be removed since Acorn is passed through, and also the line at https://github.com/rollup/rollup/pull/1857/files#diff-356410863c3a18aee7d09896d52d6b08R41 should be able to be moved into Graph.ts to be the first plugin that is attached when dynamic import is enabled. Let me know if that makes sense, or if you have any questions on this further. |
Actually I see that the acorn import is stilll used for the type in the Module.ts file. Perhaps just alter this to |
Yeah, I wasn't sure what |
If I remove https://github.com/rollup/rollup/pull/1857/files#diff-356410863c3a18aee7d09896d52d6b08R41, what should happen to https://github.com/rollup/rollup/pull/1857/files#diff-356410863c3a18aee7d09896d52d6b08L184 and https://github.com/rollup/rollup/pull/1857/files#diff-356410863c3a18aee7d09896d52d6b08L187? I don't think I understand what |
Nevermind, Github didn't do a good job showing me the lines you linked to. I think I understand, let me try. |
To the best of my understanding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the extra code. This looks great to merge to me.
I squashed the commits and rebased on top of the current master. Thanks for helping to get this ready to merge and for the review! |
Right after the last comment I ended up working on this - 4d97152, which alters this dynamic import application process. So depending on which lands first we'll just need to adjust the conflict here. |
Sorry, missed this one for the latest release. Will probably release this together with #1841 once I have reviewed that. Thanks! |
You probably want to rebase to latest master |
Add a new field in Rollup input options: `acornInjectPlugins`. If specified, it should be an array of `inject` functions which hook plugins into Acorn. Example `rollup.config.js`: ```js import acornAsyncIteration from 'acorn-async-iteration/inject'; export default { acorn: { ecmaVersion: 9, plugins: { asyncIteration: true } }, acornInjectPlugins: [ acornAsyncIteration ] }; ```
Rebased. @guybedford you might want to take another look. Your changes in #1816 are a bit over my head :) I'm still moving |
src/Graph.ts
Outdated
this.acornParse = ensureArray(options.acornInjectPlugins).reduce( | ||
(acc, plugin) => plugin(acc), | ||
acorn | ||
).parse; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we could add the dynamic import plugin via something like [...(this.dynamicImport ? [injectDynamicImportPlugin] : []) , ...ensureArray(options.acornInjectPlugins)].reduce(...
, altering wrapDynamicImport
to retun the acorn instance to match the pattern.
Not having the dynamicImport
check on the plugin is my oversight though, no pressure to add that here you've done a lot already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking yesterday that it would be nice to use the same system to inject both internal and user-defined plugins. With your recent changes, it should be easy to do. Let me try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in d58553b. I wasn't sure how to declare the return type of injectDynamicImportPlugin
, but leaving it undeclared worked too.
LGTM. |
👍 perfect! |
Thanks :) I wasn't sure what you meant by:
Would you like the plugin to check the value of |
I was referring to only wrapping the injection with dynamic import enabled, exactly as you did in https://github.com/rollup/rollup/pull/1857/files#diff-7c1e6304262c178e7fe268b62060e26bR166. |
Ah, I see. Cool, I think this is ready to merge, then! It might make sense to keep it as two separate commits: the first one adds a new feature and the second one moves an existing feature to use the new one. Feel free to squash if you prefer, though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice!
@lukastaegert How would you like to proceed wrt. the merge conflicts? Should I try to rebase on top of |
It's ok if you just merge into your branch. I will use merges anyway for the final assembly of the release as there are very many different PRs that need to be consolidated. Thanks! |
This PR makes it possible to pass Acorn plugins into Rollup.
Acorn doesn't support non-Stage 4 proposals. There is a number of plugins which add support for the upcoming ECMAScript features. Inspired by comments in #1512 I'd like to propose to make it possible to add plugins to Acorn via
rollup.config.js
.I added a new optional field in Rollup input options called
acornInjects
. If specified, it should be an array ofinject
functions which hook plugins into Acorn.Example
rollup.config.js
:I originally wrote this for my own use. I'm submitting this PR to see if you think it's a good addition. I'll be happy to add tests to this PR if you do.