import-export icon indicating copy to clipboard operation
import-export copied to clipboard

Can produce hard-to-understand bugs when it transforms imported modules

Open yortus opened this issue 8 years ago • 0 comments

Hi @Macmee,

I saw this on /r/node and thought it seems useful. Thanks for making it!

I wanted to suggest using a proper parser, rather than regex-based replacing, to rewrite the source modules as they are loaded. The reason is that the regexes will replace matching text even when not appropriate, such as inside strings, regexes, and comments. If you'd rather keep it simple, then perhaps put a warning in the README about this behaviour as it would be hard to debug for someone hit by it.

As an example of what I mean, if you use this library to import itself, it will make replacements in the index.js that mess up the regexes resulting in a mysteriously non-working module whose source becomes (note 4 out of 6 regexes are corrupted):

var hook = require('node-hook');

var hook = { hook(...args) { } };
hook.hook('.js', (src, name) => {
    src = src.replace(/import ([^{]*?) from '(.*?)'/g, 'const $1 = require("$2")');
    src = src.replace(/module.exports = ([^ ]*)/g, 'module.exports = $1');
    src = src.replace(/export (var|let|const) ([a-zA-Z0-9_$]*)/g, '$1 $2 = module.exports.$2');
    src = src.replace(/var  = module.exports. = function([a-zA-Z0-9_$]*)/g, 'var $1 = module.exports.$1 = function');
    src = src.replace(/var  = module.exports. = class([a-zA-Z0-9_$]*)/g, 'var $1 = module.exports.$1 = class');
    src = src.replace(/var (.*?)= require("(.*?)").(.*?);/g, (all, $1, $2) => {
        return $1.split(",")
            .map(part => 'var ' + part + '= require("' + $2 + '").' + part.trim() + ';')
            .join('');
    });
    return src;
});

yortus avatar Jun 16 '16 05:06 yortus