Closed ArneBab closed 3 years ago
Do you know if it's part of some ECMAScript? Or is it just an ad-hoc language extension?
To be sure, this looks like just a function call, but according to our grammar (as of now) it is interpreted as an import statement.
This is not part of ECMAScript, but rather syntax used by webpack via babel to transpile the code into legacy-browser-compatible javascript, see https://webpack.js.org/guides/code-splitting/#dynamic-imports
I’m not looking for a way to put this into js2-mode, but rather to enable myself to work more efficiently with our existing codebase.
Okay, but is this code compatible with recent ECMAScript versions (going by the spec)?
It could be, and that would mean a bug in our parser.
The proposal for async import()
is currently in stage 4: https://github.com/tc39/proposal-dynamic-import
Thank you.
In that case, patches welcome. Since we don't have any runtime part, the change will probably require no more than 5-15 lines of code.
Just noting another (related) use case for dynamic import is loadable components.
Would an approach for this be something like, modify js2-parse-import to bail if the import
usage looks like a function call, ie, import
is immediately followed by a left paren? If js2-parse-import bails, then would js2-parse-function-stmt simply parse it as a function call?
Would an approach for this be something like, modify js2-parse-import to bail if the import usage looks like a function call, ie, import is immediately followed by a left paren?
Yep.
Here's a patch to try:
diff --git a/js2-mode.el b/js2-mode.el
index 8327ca3..abc1bfa 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -8612,7 +8612,7 @@ node are given relative start positions and correct lengths."
(aset parsers js2-FOR #'js2-parse-for)
(aset parsers js2-FUNCTION #'js2-parse-function-stmt)
(aset parsers js2-IF #'js2-parse-if)
- (aset parsers js2-IMPORT #'js2-parse-import)
+ (aset parsers js2-IMPORT #'js2-parse-import-maybe)
(aset parsers js2-LC #'js2-parse-block)
(aset parsers js2-LET #'js2-parse-let-stmt)
(aset parsers js2-NAME #'js2-parse-name-or-label)
@@ -8742,6 +8742,13 @@ Return value is a list (EXPR LP RP), with absolute paren positions."
(js2-node-add-children pn (car cond) if-true if-false)
pn))
+(defun js2-parse-import-maybe ()
+ (if (eq (js2-peek-token) js2-LP)
+ (let ((name (js2-parse-name js2-IMPORT)))
+ (js2-unget-token)
+ (js2-parse-function-call name))
+ (js2-parse-import)))
+
(defun js2-parse-import ()
"Parse import statement. The current token must be js2-IMPORT."
(unless (js2-ast-root-p js2-current-scope)
from the code this looks as if it should match, and it catches imports on top-level like this:
import(/* webpackChunkName: "some-dialog" */ 'path/to/some-dialog');
What can I do to make it work as preparation for a return-value, too?
export function someFun () {
return import(/* webpackChunkName: "some-dialog" */ 'path/to/some-dialog').then(({ SomeDialog }) => {
return new SomeDialog().show();
}).catch(error => console.log(error));
}
OK, I see the problem. Let me try something else.
Thanks for tackling this!
This should do it. Let me know if it's still not working right.
Working for me!
Very cool! Thank you!
Webpack uses function-scope lazy imports in the style of
Is there a way to get js2-mode to not display this as error?
I need an error-free buffer for js2-refactor variable renaming.