Reject invalid plugin names#5842
Reject invalid plugin names#5842sarupbanskota wants to merge 3 commits intobabel:plugin-orderingfrom sarupbanskota:enforce_plugin_names
Conversation
| constructor(plugin: {}, key?: string) { | ||
| if (plugin.name != null && typeof plugin.name !== "string") { | ||
| throw new Error("Plugin .name must be a string, null, or undefined"); | ||
| if (!plugin.name || typeof plugin.name !== "string") { |
There was a problem hiding this comment.
Hmm, sorry I've been a bit out of the loop. Is there documentation somewhere for why we want to require the name? I'm concerned it'll make it harder for people to upgrade to 7.x
There was a problem hiding this comment.
yep @loganfsmyth, this was discussed in the meeting on 7 June (altho I wasn't around).
It has to do with simplifying the "intelligent plugin sorting" process.
Benefits
- Allows for global topological ordering with the DAG map.
- Serves as a known identifying key for the plugin.
- Provides opportunity to deduplicate identically configured plugins.
Steps
- Deprecate unnamed plugins in Babel 6.
- Add deprecation message.
- Publish a new patch version with that deprecation.
- Write a deprecation guide on how to make this change for your plugins.
- Enforce named plugins in Babel 7.
Also relevant: #5814 (comment)
There was a problem hiding this comment.
Note that I rebased this branch on top of plugin-ordering :-)
There was a problem hiding this comment.
Babel 6 stuff is happening on another PR - #5827
| if (plugin.name != null && typeof plugin.name !== "string") { | ||
| throw new Error("Plugin .name must be a string, null, or undefined"); | ||
| if (!plugin.name || typeof plugin.name !== "string") { | ||
| throw new Error("Plugin .name must be a valid JS identifier of type string"); |
There was a problem hiding this comment.
"Plugin .name must be a string"?
There was a problem hiding this comment.
@jridgewell since that constructor is taking in a plugin object with a bunch of properties, I didn't want to make the assumption that the passed in value for name would always be of type string. e.g if it received { name: true } that would still pass the first conditional
There was a problem hiding this comment.
Happy to just look for name's existence if you think the type check isn't necessary
There was a problem hiding this comment.
No, I'm commenting on your error message. the "valid JS identifier of type string" is needlessly wordy, just say "needs to be a string"
There was a problem hiding this comment.
ah, okay - sounds good, thanks for that. I'll update it!
|
I'm guessing the next step will be to name the unnamed core packages? I wrote a little script: const fileSystem = require('fs');
const returnFilesWithin = (path) => {
return fileSystem.readdirSync(path);
}
returnFilesWithin('packages').forEach(package => {
if (fileSystem.lstatSync(`packages/${package}`).isDirectory()) {
fileSystem.readFile(`packages/${package}/package.json`, 'utf8', (err, content) => {
const packageOptions = JSON.parse(content);
console.log(packageOptions.name);
});
}
})and that printed https://gist.github.com/sarupbanskota/4bf6627eb1501be1b8c14be406164aa4. No empty lines 🤔 What am I missing? |
|
learned from @hzoo that it needs to be within the visitor: {
name: "transform-es2015-computed-properties"
...
}i'll think of ways to do it for all core plugin packages update: name: "transform-es2015-computed-properties",
visitor: {
...
} |
|
Why does the visitor have a name and not the plugin? |
|
yeah that's incorrect - check http://astexplorer.net/ for an example |
|
Just documenting thought process here. Based on two | examples, we wanna do the following:
body:
type: "ExportDefaultDeclaration"
declaration:
type: "FunctionDeclaration"
body:
type: "BlockStatement"
body:
type: "ReturnStatement"
argument:
type: "ObjectExpression"
properties: [Array 1] ← we wanna inject `name` as another prop hereInstead of manually updating filenames on the core packages, I'm doing this programmatically to teach myself to play with the various babel packages available, but as @nathanhammond and @hzoo discussed on Slack, we could use this logic to build a tiny plugin upgrade service or similar |
|
Not every plugin has to be formatted in that way but hopefully most are? I would just check for https://github.com/babel/kneden/blob/master/src/index.js#L19 Still don't think the names should be used as capabilities, but if this somehow will give us better error messages ok. |
|
Ah shoot, I made quite a bit of progress and only noticed your comment now @hzoo. Anyway, here's what I have so far: export default function({ types: t }) {
return {
visitor: {
ExportDefaultDeclaration(path) {
let pluginReturn;
try {
pluginReturn = path // "ExportDefaultDeclaration"
.get('declaration') // "FunctionDeclaration"
.get('body') // "BlockStatement"
.get('body.0') // "ReturnStatement"
.get('argument') // "ObjectExpression"
.get('properties.0'); // "ObjectMethod"
} catch(e) {
console.log(e);
} finally {
const nameKey = t.identifier("name");
const nameValue = t.stringLiteral("pluginName");
pluginReturn.insertBefore(t.objectProperty(nameKey, nameValue));
}
}
}
}
}Other than the fact that it may not work for every case, please let me know if you see anything if I'm totally in the wrong direction with the way I've written it! What's pending for me:
|
sarupbanskota
left a comment
There was a problem hiding this comment.
What I ran here was the following:
const exec = require('child_process').exec;
const fileSystem = require('fs');
const returnFilesWithin = (path) => {
return fileSystem.readdirSync(path);
}
returnFilesWithin('packages').forEach(package => {
const PLUGIN_PACKAGE = /^babel-plugin/;
if (PLUGIN_PACKAGE.test(package)) {
if (fileSystem.lstatSync(`packages/${package}/src`).isDirectory()) {
const cmd = `codemod --require babel-register --plugin plugin.js packages/${package}/src/index.js ${package}`;
exec(cmd, (error, stdout, stderr) => {
console.log(package);
});
}
}
});plugin.js is a plugin I've written locally
|
Just copying over my message from Slack: I wrote this plugin https://github.com/babel/babel/pull/5842/files#diff-9db534602dc20174af286fa13dba8b05 and ran this code to run it through babel's core packages https://github.com/babel/babel/pull/5842/files#diff-46ab14e9c7ab9cf574a7e8f116b8d6b0
|
|
I figured out the problem, and will send an update tonight |
These changes were done programmatically; the process is explained at http://bit.ly/2s0r6Oi. Notes: babel-plugin-transform-class-properties already has a name. babel-plugin-transform-regenerator's source seems to be a node_module
Inject plugin name into original module via facebook/regenerator#296
|
I'm triaging old PR on Babel. Since this has been sitting for ages, I'm going to close it. If you want to rebase this to just add plugin names to our packages, feel free to open a new PR. |
Uh oh!
There was an error while loading. Please reload this page.