Skip to content
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

Adds option for running plugin through babel-preset-env pipeline #31

Merged
merged 1 commit into from
Jan 3, 2018
Merged

Conversation

mcMickJuice
Copy link
Contributor

#29

Points of discussion/questions:

  • Not sure of naming of this cli option
  • How can we write a unit test against this?

@mcMickJuice mcMickJuice changed the title Addeds option for running plugin through babel-preset-env pipeline Adds option for running plugin through babel-preset-env pipeline Jun 25, 2017
@eventualbuddha
Copy link
Collaborator

@mcMickJuice sorry it took me so long to get to this. I've mostly finished it up, leaving the option name the same as you had it. I added a test to ensure export default … plugins work as expected. What do you think?

@mcMickJuice
Copy link
Contributor Author

No problem and all looks good. Ship it!

@eventualbuddha
Copy link
Collaborator

eventualbuddha commented Dec 25, 2017

Cool, still some things I need to do first:

@mcMickJuice
Copy link
Contributor Author

For typescript, should we have a separate issue to tackle that? along with doc updates and tests?

@eventualbuddha
Copy link
Collaborator

Yeah, I’ll make a ticket for TypeScript.

@mcMickJuice
Copy link
Contributor Author

update help docs to encourage --babel-transform instead of babel-register

Updated readme, explaining how to use new switch and when to use babel-register instead of --babel-transpile. Split out example of using ts-node/register

@mcMickJuice
Copy link
Contributor Author

ensure plugins with multiple files get transpiled correctly

Currently working on this and my test is failing. Seems like imported modules are not being transpiled...

@eventualbuddha
Copy link
Collaborator

Seems like imported modules are not being transpiled...

Yeah, I didn’t really explain it in my comment, but that’s something that I was reasonably sure wouldn’t work correctly with the way I implemented it. The problem is that the function I pass to babel-register to determine which files should be transpiled only whitelists the path that was require.resolve-d, but nothing imported or required by that file.

A better approach might be to do the require.resolve, then somehow whitelist everything in that package (if it is a package) or in its directory, possibly excluding node_modules and other stuff like that. Unfortunately, this is somewhat complex and I’m open to alternative suggestions. For example, what about doing the require inside a try block and, if the error is a SyntaxError, turn on babel-register for everything and try again?

@mcMickJuice
Copy link
Contributor Author

Yep, removing the ignore function fixes this issue.

Are you looking to avoid transpiling node_modules for purposes of speed? If so, babel-register does this by default.

@mcMickJuice
Copy link
Contributor Author

We could also just accept an ignore regex in the event that someone is using an npm package that is not transpiled. Essentially exposing the same config setting that babel-register accepts

@eventualbuddha
Copy link
Collaborator

By default babel-register also only transpiles files in packages that have babel-register as a dependency, right? I think that’s one issue I was trying to avoid eight the approach I took.

@mcMickJuice
Copy link
Contributor Author

I'm not sure about that. But could we consider this an edge case and not alter babel-register's default behavior? If there are future issues we can have a bug opened and add further extension points (e.g. exposing babel-register config to cli).

If you're cool with this, I can remove the whitelisting and push the test I added.

@eventualbuddha
Copy link
Collaborator

Sure, let’s start with this and file bugs for other issues.

@eventualbuddha
Copy link
Collaborator

What do you think about making this on by default?

@mcMickJuice
Copy link
Contributor Author

Completely agree. I just updated docs to say this functionality is on by default. I'll move forward with turning this on by default and exposing a switch to use babel-register.

Since this project now has a dependency on babel-register, should the switch be --use-local-babel which bypasses the registering of babel-preset-env and just calls babel-register without any arguments. If that sounds good to you I can start on that.

@mcMickJuice
Copy link
Contributor Author

Not sure why my pushes are failing in the CI env 🤷‍♂️

@mcMickJuice
Copy link
Contributor Author

Updated to use --use-local-babel switch and updated functionality to opt out of using babel-preset-env, updated tests and docs. Couldn't think of a good way to write a test to ensure that local babelrc file was being used if --use-local-babel switch is passed

Copy link
Collaborator

@eventualbuddha eventualbuddha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looking good. I will wait to merge until I get home and can test it out a bit on a development computer (I’m writing this on an iPad). Thanks for helping to get this feature in!

src/index.ts Outdated
@@ -15,6 +15,7 @@ OPTIONS
-o, --plugin-options PLUGIN=OPTS JSON-encoded OPTS for PLUGIN (allows multiple).
-r, --require PATH Require PATH before transform (allows multiple).
--extensions EXTS Comma-separated extensions to process (default: "${Array.from(DEFAULT_EXTENSIONS).join(',')}").
--use-local-babel Run plugins through babel plugins/presets specified in local .babelrc file instead of babel-preset-env
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: end this statement in a period.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, should we add a --no-transpile-plugins option? Using babel-register does slow things down a bit and it might be nice to allow opting out of that. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this something we can have as a separate, dependent issue on this feature? Just to keep this PR focused?

@@ -0,0 +1,7 @@
import path from 'path'

const i = path.join(__dirname, 'hello.js')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here?

const i = path.join(__dirname, 'hello.js')

export default function incrementValue(value) {
return value + 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 2-space indent, use semicolons. (I should set up prettier on this project)


export default function incrementValue(value) {
return value + 1
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use trailing newlines

import incrementValue from './increment-value'

export default function() {
return {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use 2-space indent

test/CLITest.ts Outdated
let afile = await createTemporaryFile('a-file.js', '3 + 4;');
let { status } = await runCodemodCLI([afile, '-p', plugin('increment-export-default'), '--use-local-babel']);

const syntaxError = 255;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get where you’re coming from with having this as const, but let’s just use let.

test/CLITest.ts Outdated

it('fails when specifying --use-local-babel as there are no plugins loaded', async function() {
let afile = await createTemporaryFile('a-file.js', '3 + 4;');
let { status } = await runCodemodCLI([afile, '-p', plugin('increment-export-default'), '--use-local-babel']);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also make some sort of assertion about the output. Ideally we could even catch SyntaxError and provide a better error message telling users they may need to use a custom .babelrc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's difficult to find where to place the try catch to determine if the SyntaxError is a result of the plugin or the code that we're modding. We could also look at the stack trace to determine where the syntax error occurred?:

/Users/z002s72/dev/git-clones/babel-codemod/test/fixtures/plugin/increment-export-default.js:1
(function (exports, require, module, __filename, __dirname) { export default function() {
                   ^^^^^^

SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:599:28)
    at loader (/Users/z002s72/dev/git-clones/babel-codemod/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/z002s72/dev/git-clones/babel-codemod/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)

Copy link
Contributor Author

@mcMickJuice mcMickJuice Dec 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like wrapping the following in try/catch captures the specific plugin related SyntaxError:

// index.ts, line 76
let plugins = options.getBabelPlugins();

However the error is undefined...im little lose here 😄

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll take a look when I get home.

src/Options.ts Outdated
@@ -83,6 +92,16 @@ export default class Options {
}
}

loadBabelTranspile() {
let pluginOptions;
if(!this.useLocalBabel) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space between if and (

README.md Outdated

`babel-codemod` also supports non-standard/future language features that are not currently supported by the latest version of node. It does this by leveraging `babel-preset-env` which loads the [latest babel plugins](https://github.com/babel/babel/tree/master/packages/babel-preset-env#support-all-plugins-in-babel-that-are-considered-latest). This feature is on by default.

This feature should support most use cases when writing plugins in advanced Javascript syntax. However, if you are writing plugins with syntax that is beyond "latest", or you would like to use your own set of plugins and presets, you can pass in the `--use-local-babel` switch in combination with a local `.babelrc` file that lists the presets/plugins you want applied to your plugin code.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: capitalize as “JavaScript”

README.md Outdated

### Transpiling using typescript
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: capitalize as “TypeScript”

Adds `--[no-]transpile-plugins` option to control whether babel should
be used to transpile plugins before loading them. This will allow
plugins to be written using language features unsupported by the current
version of nodejs.

Typically and by default simply using `babel-preset-env` will transpile
the language features that people will want to use. However, if
required, support for loading a custom babel config is controlled by
`--[no-]find-babel-config`.

Thanks to @mcMickJuice for his work on the feature in #31.
@eventualbuddha eventualbuddha merged commit 4d7d95f into codemod-js:master Jan 3, 2018
@eventualbuddha
Copy link
Collaborator

Released in v1.3.0 with the final CLI options being --[no-]transpile-plugins (on by default) and --[no-]find-babel-config (off by default). Thanks @mcMickJuice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants