Make babel-template nicer in a bunch of ways#6492
Conversation
| NAMESPACE: t.identifier(data.name), | ||
| IMPORT_NAME: t.identifier(importName), | ||
| template` | ||
| Object.defineProperty(EXPORTS, "EXPORT_NAME", { |
There was a problem hiding this comment.
I could also opt to use template.ast on a lot of these and do
Object.defineProperty(${metadata.exportName}, "${exportName}", {
but I kind of felt like it hurt readability of some of the templates.
| MODULE_NAME: moduleName, | ||
|
|
||
| AMD_ARGUMENTS: t.arrayExpression(amdArgs), | ||
| COMMONJS_ARGUMENTS: commonjsArgs, |
There was a problem hiding this comment.
The nice thing about adding validation is that it catches all you're dumb mistakes :D
|
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/5400/ |
packages/babel-template/package.json
Outdated
| "main": "lib/index.js", | ||
| "dependencies": { | ||
| "babel-code-frame": "7.0.0-beta.3", | ||
| "babel-traverse": "7.0.0-beta.3", |
There was a problem hiding this comment.
This severs the cyclic dependency that I filed. By making babel-template only depend on babel-types, we avoid risking cycles that we'd otherwise get if we split things out of babel-traverse but still wanted to use them as dependencies in babel-traverse.
| ? buildNameListCheck({ | ||
| EXPORTS_LIST: t.identifier(metadata.exportNameListName), | ||
| }) | ||
| ? template` |
There was a problem hiding this comment.
is this also a template.statement or it doesn't matter?
There was a problem hiding this comment.
The default is essentially autodetect statement or statements so I really didn't need to change the other cases either. Guess I just didn't do this one.
f01ae58 to
2ed4c8f
Compare
| // error.stack does not exists in IE <= 9 | ||
| rootStack = error.stack | ||
| .split("\n") | ||
| .slice(3) |
There was a problem hiding this comment.
Can you add a comment which explains why 3? It looks too magic to me.
|
|
||
| export type Formatter<T> = { | ||
| code: string => string, | ||
| validate: BabelNodeFile => void, |
There was a problem hiding this comment.
Where are BabelNode* types imported in this file? 🤔
There was a problem hiding this comment.
Ideally we'd get Flowtype set up properly and have them live in babel-types, but for now they live in https://github.com/babel/babel/blob/master/lib/types.js
| validate: (ast: BabelNodeFile) => { | ||
| const { program } = ast; | ||
| if (program.directives && program.directives.length > 0) { | ||
| throw new Error("Unexpected directives found"); |
There was a problem hiding this comment.
Does this mean that this code is invalid?
// I want an expression statement which contains a string literal
const ast = template.statement`"string";`();There was a problem hiding this comment.
Yeah, you'd have to do
template.statement`("string");`();
if you wanted to get a string expression statement.
It's the same behavior we have right now, it's just that now it actually throws an error instead of silently discarding the string :P
There was a problem hiding this comment.
I think we should wrap the code in { ... } so that my example is parsed as an expression statement. Otherwise it is inconsistent with template.statements, which wraps the input.
e.g.
template.statements`"string";`(); // [ ExpressionStatement {} ]
template.statement`"string";`(); // Error! 💥 Or probably (better) we should use () => { /* input */ } as the wrapper in the statements formatter, so that directives are always parsed as directives.
There was a problem hiding this comment.
They both throw at the moment, but I can certainly tweak this logic so strings are always interpreted as statements and not directives, if you think it'll be more ideal. I can see how the name of the functions might make that more surprising.
|
@loganfsmyth I just tested this PR locally: is this the expected behavior? Shouldn't const ast = template.statements.ast`foo; bar;`;
console.log(ast); |
|
@nicolo-ribaudo Oh dang, you're right. I actually forgot that I'd wrapped |
| fn: (Array<BabelNodeStatement>) => T, | ||
| ): Formatter<T> { | ||
| return { | ||
| code: str => `"==@babel/template==";;\n${str}`, |
There was a problem hiding this comment.
Curious for thoughts on this. Since we want to force things to be statements and not directives, the easiest thing is just to prepend a ; to the string. I felt like it'd be a little weird for people to get errors like
SyntaxError: Unexpected token, expected ; (2:4)
1 | ;
> 2 | omg 45
| ^
so I threw a little header in there so it's clearer, e.g.
SyntaxError: Unexpected token, expected ; (2:4)
1 | "==@babel/template==";;
> 2 | omg 45
| ^
There was a problem hiding this comment.
this certainly gives at least some context
35bae92 to
0c3804b
Compare
0c3804b to
f230497
Compare
Breaking changes:
[foo, bar]./[_$A-Z0-9]/will need to pass a customplaceholderPatternor rename the placeholder. There are no cases of this in Babel's core plugins.New features:
Identifiernodes, or intoStringLiteralnodes if the placeholder was a string.template.expression("4"),template.statement("function foo(){}"),template.statements(..),template.program(""), andtemplate.smart(the current default).new Errorand stack processing by using.aston the template function: