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
[ImportParserPlugin] fix return value when creating context for import()
#8294
[ImportParserPlugin] fix return value when creating context for import()
#8294
Conversation
For maintainers only:
|
import()
@@ -254,7 +254,7 @@ class ImportParserPlugin { | |||
dep.loc = expr.loc; | |||
dep.optional = !!parser.scope.inTry; | |||
parser.state.current.addDependency(dep); | |||
return true; | |||
return false; |
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 think walking the full expression is not correct as it would handle constant pieces twice.
like this one: import(`./${CONSTANT}/${DEFINED_EXPRESSION}`)
with DefinePlugin({ CONSTANT: JSON.stringify("folder"), DEFINED_EXPRESSION: "foobar" })
Could you add this to the test?
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.
Sadly you are right. Seems only reliable way to fix this is to walk necessary expressions in ContextDependencyHelpers
. I'll push a new iteration
if (param.isConditional()) { | ||
param.options.forEach(param => { | ||
const result = this.processItem(parser, expr, param); | ||
param.options.forEach((param, idx) => { |
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.
We need some tests for this.
I think this fails if multiple ?:
operators are nested. In this case options
has more than 2 elements:
import(a ?
(b ? "x" : `./${CONST_PREFIX}/${DEFINED_EXPRESSION}/${CONST_SUFFIX}`) :
(c ? `./${CONST_PREFIX}/${DEFINED_EXPRESSION}/${CONST_SUFFIX}` : "y")
)
I think it make sense to add the expression tracking to the BasicEvaluatedExpression
(i. e. setExpression
for the whole thing, and setTemplateString(quasis, parts)
for template strings), instead of reimplementing it here.
- You can call
setExpression
inParser.evaluateExpression
to do it once for all - You need to change
getSimplifiedTemplateResult
inParser
a bit to get all the expressions too. BasicEvaluatedExpression.setTemplateString
now takesquasis
which is still the same,parts
which are all the quasis and epxressions asBasicEvaluatedExpression
s, so all the parts of the template string.
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! I've thought it's too heavy for this PR, but surely it's more appropriate for easily tracking back the expr from BasicEvaluatedExpression
@@ -45,7 +45,9 @@ ContextDependencyHelpers.create = ( | |||
Dep, | |||
range, | |||
param, | |||
paramExpr, |
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.
You no longer need this argument, as param
now contains this information.
@@ -84,7 +86,17 @@ ContextDependencyHelpers.create = ( | |||
); | |||
dep.loc = expr.loc; | |||
const replaces = []; | |||
if (prefixRange && prefix !== prefixRaw) { | |||
const templateLiteral = |
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.
You can walk all parts
of the param
.
- If it's a constant string: replace the
range
with the string (push toreplaces
) - If it's not constant: walk it with the parser
@@ -21,20 +21,24 @@ class RequireResolveDependencyParserPlugin { | |||
if (expr.arguments.length !== 1) return; | |||
const param = parser.evaluateExpression(expr.arguments[0]); | |||
if (param.isConditional()) { | |||
for (const option of param.options) { | |||
param.options.forEach((option, idx) => { |
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.
All these changes can be reverted as the expression is now tracked in the BasicEvaluatedExpression
.
expr, | ||
parser, |
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.
To avoid a breaking change, make this argument optional. In this case expressions are not walked.
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.
OK, thanks! Then in this PR I'll only handle import()
case, then later working on AMD define
, require
, CommonJS require
and require.resolve
parser.walkExpression(e); | ||
} | ||
}); | ||
if (prefix !== prefixRaw) { | ||
replaces.push({ | ||
range: prefixRange, | ||
value: prefix |
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.
Lower in this file, at the else
case, you need to walk the whole expression.
@sokra , I've published a new iteration. It's more readable now. Thanks! |
Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon. |
fix bug which keeps const conditional expression in bundle remove parsing code from ContextDependencyHelpers
It looks like this Pull Request doesn't include enough test cases (based on Code Coverage analysis of the PR diff). A PR need to be covered by tests if you add a new feature (we want to make sure that your feature is working) or if you fix a bug (we want to make sure that we don't run into a regression in future). @ljqx Please check if this is appliable to your PR and if you can add more test cases. Read the test readme for details how to write test cases. |
Thanks |
This PR fixes #8293 . Now
ImportParserPlugin
returnstrue
when creating context, which stops parser walking on param ofimport()
, thenDefinePlugin
fails to change value of it.What kind of change does this PR introduce?
a bugfix
Did you add tests for your changes?
yes
Does this PR introduce a breaking change?
no
What needs to be documented once your changes are merged?
nothing