-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Babel Following Closure Compilation #26779
Babel Following Closure Compilation #26779
Conversation
Hey @jridgewell, these files were changed:
|
build-system/babel-plugins/babel-plugin-transform-function-declarations/index.js
Outdated
Show resolved
Hide resolved
Are the numbers reflecting extension changes? Diffing both I only see that
|
build-system/babel-plugins/babel-plugin-transform-function-declarations/index.js
Show resolved
Hide resolved
Should be, I'll verify though since it's a surprise there was no change. |
Does Closure Compiler not support generating two outputs, one for |
Closure Compiler doesn't support outputting with two different Ideally we are not doing any transpilation with Closure, and relying on Babel for this work. |
build-system/babel-plugins/babel-plugin-transform-function-declarations/index.js
Show resolved
Hide resolved
@rsimha Can you approve the eslintrc change? |
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 working on this, @kristoferbaxter. I've requested some changes to the compilation code. Also, I didn't see any changes to .eslintrc
. Is it missing from this PR?
@@ -138,8 +141,18 @@ function getJsonConfigurationPlugin() { | |||
* @param {!Object<string, boolean>} buildFlags | |||
* @return {!Array<string|!Array<string|!Object>>} | |||
*/ | |||
function plugins({isEsmBuild, isForTesting, isSinglePass, isChecktypes}) { | |||
const applied = [...defaultPlugins(isEsmBuild || false)]; | |||
function plugins({ |
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.
FYI @rcebulko and @jridgewell, since this code is being refactored in #27161.
build-system/compile/compile.js
Outdated
* @param {boolean} isEsmBuild | ||
* @return {!Promise} | ||
*/ | ||
function postClosureBabel(directory, isEsmBuild) { |
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.
A couple questions, since it looks like we're now doing babel transforms before and after closure compilation:
- Any chance the two can be consolidated at some point?
- The pre-closure babel transforms run on all files at once. This currently prevents us from enabling lazy-building for minified builds. Would it be possible to do the pre-closure transforms per-file as well, and add them to the chain in the main compile function?
Obviously, both these items needn't be addressed in this PR.
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.
Any chance the two can be consolidated at some point?
Not likely, the transforms executed post closure are expected to optimize the output of Closure Compiled code for our specific usecase. There might be times where we need to retain information from a pre-closure scan/transform and use it afterwards too.
The pre-closure babel transforms run on all files at once. This currently prevents us from enabling lazy-building for minified builds. Would it be possible to do the pre-closure transforms per-file as well, and add them to the chain in the main compile function?
Sounds like an interesting experiment for a future PR. Don't have a compelling reason why this must be done all at once.
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.
Agree, I've talked to @erwinmombay about a plan to address pre-closure transforms in a new PR.
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.
This is being done in #27426.
@rsimha Sorry, it was Looking at the other comments now. |
…ddressed additional output from unformatted comments
@@ -23,7 +23,7 @@ module.exports = function() { | |||
Statement(path) { | |||
const {node} = path; | |||
const {trailingComments} = node; | |||
if (!trailingComments) { | |||
if (!trailingComments || trailingComments.length <= 0) { |
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.
This transform was executing on empty array lengths, addressed since this PR also includes a new transform doing something very similar.
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.
just for my own knowledge, can the comments property actually be null
?
@kristoferbaxter read through it again and LGTM |
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.
LGTM after a few minor comments are addressed. Thanks!
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.
Whoa that's a large diff. :)
src/examiner/examiner.js
changes LGTM.
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.
Latest changes LGTM.
Paging @jridgewell who added strict mode directives a long time ago (#9575), for comment on whether there's any reason we can't remove all the use strict
s in our code.
Modules are strict by default so moving our infra source to ES6 would allow that. Though I think we'd still need transpilation to run browser tests on IE. Somewhat related: AMP currently runs in sloppy mode (#19380), so we probably need to check that "strict by default" in module build doesn't break anything that relies on sloppy mode behavior. |
If we convert the entire node source code to ESM, and load it with either There is also the option to invoke node with |
const conf = require('./build.conf'); | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
const resorcery = require('@jridgewell/resorcery'); |
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.
This should be @ampproject/remapping
.
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.
Looks like the entire codebase is using your previously personal named scope version. Sounds like a good change to make wholesale.
|
||
return { | ||
compressed: minified.code, | ||
terserMap: minified.map, |
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.
Nit: why not just return the minified
object as is? code
and map
properties are pretty standard for every build library.
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 can, but the method consuming it was renaming the values anyway. Since it's only intended to be used within this module, I renamed the output to the expected form.
remapped.toString() | ||
); | ||
|
||
return next(null, file); |
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.
Did we verify the sourcemaps coming out of this? Please verify by loading it into https://justin.ridgewell.name/source-map-visualization/
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 did verify before submitting the first PR. Will check again.
Statement(path) { | ||
const {node} = path; | ||
const {trailingComments} = node; | ||
if (!trailingComments || trailingComments.length <= 0) { |
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.
Shouldn't this be looking at leadingComments
, too?
...comment, | ||
value: comment.value.replace(/\n +/g, `\n`), | ||
})); | ||
next.addComments('leading', formattedComments); |
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.
Why put the comments onto a new node in this plugin? The babel-plugin-transform-fix-leading-comments
should already be taking care of this.
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.
Feel free to try within the codebase, the existing transform did not properly format the comments in a way that would work with terser.
isNewedInProgramScope: (t, path) => { | ||
const {name} = path.get('id').node; | ||
let isNewed = false; | ||
path |
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 can use the binding directly to skip a full file traversal:
const binding = path.scope.getBinding(name);
const isNewed = binding.referencePaths.some(p => p.parentPath.isNewExpression());
}); | ||
return isNewed; | ||
}, | ||
}; |
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.
There are more cases we should be checking for. Essentially, if the binding is used in any way that is not a simple CallExpression
, then it is not safe to convert.
const binding = path.scope.getBinding(name);
const isSafeToTransform = binding.referencePaths.every(p => p.parentPath.isCallExpression({ callee: p.node }));
});
This would subsume the isExported
and isNewed
checks.
}, | ||
}; | ||
|
||
function createVariableDeclaration(t, path) { |
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.
Nit: Everything should be inside the module.exports
function, so that you don't need to keep passing around the t
variable. The function will only ever be invoked once, so it won't slow anything down.
return { | ||
name: 'safe-arrows', | ||
pre() { | ||
this.bailoutCount = {...BAIL_OUT_CONDITIONS}; |
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.
Can we delete all of this? It's just doing extra work which makes it more difficult to understand the transformer.
console /*OK*/ | ||
.log(`Success for function ${path.get('id').node.name}.`); | ||
} | ||
path.replaceWith(createVariableDeclaration(t, path)); |
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.
This is not 100% safe. FunctionDeclaration
s are available to be used at any time in their enclosing scope, even before the program would reach the line that define the function. Replacing it with a variable declaration does not preserve that.
The only way to make this safe is to find the enclosing block, and insert this variable as the first statement of the body.
Introduces a Babel and Terser processing step post Closure Compiler invocation.
This allows us to write Babel plugins (like the one included) that modify the output of Closure generated code to take advantage of newer language features in the
module
build.This PR also removes
shorten-license
which did not appear to work for ESM builds.