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

putout(source, options) - show more options in readme #116

Closed
milahu opened this issue Oct 30, 2022 · 12 comments
Closed

putout(source, options) - show more options in readme #116

milahu opened this issue Oct 30, 2022 · 12 comments

Comments

@milahu
Copy link

milahu commented Oct 30, 2022

example: transform tsx to tsx

import putout from "putout"

const source = `
const hello: string = 'world';
const hi = 'there';
console.log(hello);
`;

const res = putout(source, {
    isTS: true,
    isJSX: true,
    //isFlow: true,
    //parser: 'babel',
    //sourceFileName: 'input.tsx',
    //sourceMapName: 'input.tsx.map',
    processors: [
        //'typescript', // @putout/processor-typescript type checking for typescript files
    ],
    plugins: [
        //'typescript', // @putout/plugin-typescript transform TypeScript code. Enabled by default for ts and tsx files.
        'remove-unused-variables',
    ],
});

console.log(res.code);

not perfect, because it should return typescript
had to disable the typescript plugin, which was removing the : string

example result

const hello: string = 'world';
console.log(hello);
@milahu
Copy link
Author

milahu commented Oct 30, 2022

also ... how can i replace jsx?

input

const div = <div className="asdf"></div>

output

const div = <div class="asdf"></div>

i tried

module.exports.replace = () => ({
    '<__a className="__b">': '<__a class="__b">',
})

but babel throws BABEL_TEMPLATE_PARSE_ERROR

SyntaxError: Unexpected token, expected "," (2:5)
  1 | /* @babel/template */;
> 2 | <__a className="__b">
    |     ^

edit:

https://github.com/coderaiser/putout/blob/master/packages/plugin-react-router/lib/convert-switch-to-routes/index.js

https://github.com/coderaiser/putout/blob/master/packages/plugin-react-hooks/lib/apply-short-fragment/index.js

module.exports.rules = ({
    'jsx-classname-to-class': {
        report: () => `Use class instead of className attribute`,
        include: () => [
            'JSXOpeningElement',
        ],
        filter: (path) => {
            return !!path.node.attributes.find(attr => attr.name.name == "className")
        },
        fix: (path) => {
            const attr = path.node.attributes.find(attr => attr.name.name == "className")
            attr.name.name = "class"
            // TODO handle collisions: class attribute can exist already
        },
    },
})

@coderaiser
Copy link
Owner

coderaiser commented Oct 30, 2022

How exactly I can help you :)?

About collision, filter should be improved a bit, to filter out nodes that was processed already. There is no support of JSX for Replacer, Includer does the job.

had to disable the typescript plugin, which was removing the : string

-const a: string = 'hello';
+const a = 'hello';

Type is striped, because it’s always string, in such case and it works the same, but easier to read. Anyways you can disable any plugin or any count of rules from the plugin, if you don’t need them.

@milahu
Copy link
Author

milahu commented Oct 30, 2022

the readme section for putout(source, options) should be more verbose
and / or
the parameters of putout(source, options) should be typed

currently i see

putout(source: any, opts: any): {
    code: any;
    places: any;
}

@coderaiser
Copy link
Owner

Are you up for a PR to improve docs?

@milahu
Copy link
Author

milahu commented Oct 30, 2022

sure : )

two seconds ...

@milahu
Copy link
Author

milahu commented Oct 30, 2022

demo plugin: transform tsx to tsx

const putout = require("putout")

const source = `
function App(props: { name?: string }) {
  const name = props?.name || "world"
  return (
    <div className="app">
      hello {name}
    </div>
  )
}
`;

console.log("input:\n" + source)

/* based on
https://github.com/coderaiser/putout/blob/master/packages/plugin-react-router/lib/convert-switch-to-routes/index.js
https://github.com/coderaiser/putout/blob/master/packages/plugin-react-hooks/lib/apply-short-fragment/index.js
*/
const myPlugin = {
  rules: {
    'jsx-classname-to-class': {
        report: () => `Use class instead of className attribute`,
        include: () => [
            'JSXOpeningElement',
        ],
        fix: (path) => {
            const attr = path.node.attributes.find(attr => attr.name.name == "className")
            attr.name.name = "class"
        },
        filter: (path) => {
            const hasClassName = !!path.node.attributes.find(attr => attr.name.name == "className")
            const hasClass = !!path.node.attributes.find(attr => attr.name.name == "class")
            return hasClassName && !hasClass
        },
    },
  }
}

const res = putout(source, {
    isTS: true,
    isJSX: true,
    //sourceFileName: 'input.tsx',
    processors: [
        //'typescript', // @putout/processor-typescript type checking for TypeScript code
    ],
    plugins: [
        //'typescript', // @putout/plugin-typescript transform TypeScript code
        ['my-plugin', myPlugin],
    ],
    rules: {
      // default: all rules are on
      //"my-plugin/jsx-classname-to-class": "on",
    }
});

console.log("output:\n" + res.code)

result

input:

function App(props: { name?: string }) {
  const name = props?.name || "world"
  return (
    <div className="app">
      hello {name}
    </div>
  )
}

output:

function App(props: { name?: string }) {
  const name = props?.name || "world"
  return (
    (<div class="app">hello{name}
    </div>)
  );
}

im not happy with the missing whitespace in hello{name} ... ideas?
ideally the indent should be preserved, as that style is rather common in jsx

@coderaiser
Copy link
Owner

It looks like a bug in recast.

@milahu
Copy link
Author

milahu commented Oct 30, 2022

related benjamn/recast#167

maybe we handle JSXText wrong?

edit: benjamn/recast#211

@milahu
Copy link
Author

milahu commented Oct 31, 2022

nevermind. im moving on to eslint as its more popular

this issue can be fixed by #117

feel free to close

@coderaiser
Copy link
Owner

The best way is using both: ESLint and 🐊Putout. They have different rules set that do not overlap. Also 🐊Putout has ability to show progress bar and run ESLint for each transformed file.

@coderaiser
Copy link
Owner

coderaiser commented Nov 8, 2022

@coderaiser
Copy link
Owner

coderaiser commented Nov 8, 2022

Just landed ability to use __jsx_children keyword to find children of JSXElement:

🐊📜https://putout.cloudcmd.io/#/gist/42107dbcd0dcca5c60e7237655136916/a780bef3d4373bda03aad30e6904b53a19382d63

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

No branches or pull requests

2 participants