azu / commonjs-to-es-module-codemod

Codemod that convert CommonJS(require/exports) to ES Modules(import/export) for JavaScript/TypeScript
MIT License
80 stars 15 forks source link

Fails on shebang #10

Open kvz opened 2 years ago

kvz commented 2 years ago

Hi! thanks for this mod 💖

I just tried it on some cli files that started with:

#!/usr/bin/env node

'use strict'

const commander = require('commander')

And that is translated to:

#!/usr/bin/env node'use strict'

import commander from 'commander';

Naturally after running the script it will complain that node'use strict' is not an existing interpreter.

The added semicolons are fine, but the corrupted shebang sadly makes it that we cannot use your tool as is.

If you have an idea how to fix that would be nice, otherwise i may run some kind of post-cleanup job perhaps.

All the best :)

kvz commented 2 years ago

Just found another file with some issue:

image

here is its full original header in case you'd like to test

#!/usr/bin/env node

'use strict'

// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
const mySetImmediate = global.GENTLY ? process.syncSetImmediate : setImmediate
const async = require('async')
const db = require('../../lib/Database').obj
const config = require('../../lib/config')
const trigPager = require('../../lib/trigPager')
azu commented 2 years ago

Thanks for report. I confirm it, however I do not understand what cause the bug.

https://github.com/azu/commonjs-to-es-module-codemod/blob/cbbbf022a6c862bcb9612997b3ec6dd93ec868d6/transforms/module-exports-to-export-default.js#L47-L51 This transformer generate the wrong result.

#!/usr/bin/env node and 'use strict' is joined when jscodeshift replace module.exports staement to foo()(anything).

It maybe a bug in jscodeshift 's replaceWith function.

// random replaceWith
function transformer(file, api, options) {
    const j = api.jscodeshift;
    return j(file.source)
        .find(j.ExpressionStatement, {
            expression: {
                left: {
                    object: {
                        name: "module"
                    },
                    property: {
                        name: "exports"
                    }
                },
                operator: "="
            }
        })
        .replaceWith((path) => {
            return j.expressionStatement(j.callExpression(
                j.identifier('foo'),
                []
            ));
        })
        .toSource();
}