Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Test proposals #2

Closed
reconbot opened this issue Oct 23, 2015 · 3 comments
Closed

Test proposals #2

reconbot opened this issue Oct 23, 2015 · 3 comments

Comments

@reconbot
Copy link

I know it's probably early for this but I worked up the test cases for imports and exports of how I think CommonJS to es modules might look.

https://gist.github.com/reconbot/5358ab4a532d2f253df0

// CommonJS to ES modules test cases

// Importing

var foo = require('bar');
// becomes 
import foo from 'bar';

require('bar')(foo);
// becomes
import tempvar from 'bar';
tempvar(foo);

var foo = require('bar').foo;
// becomes
import {foo} from 'bar';


// Exporting

module.exports = { //pojo
  name: 'todd',
  value: 'person'
};
//becomes
export var name = 'todd';
export var value = 'person';
export default {name, value};

module.exports = function(){}; // or anything not a pojo
//becomes
export default function(){};

module.exports.name = 'todd';
module.exports.value = 'person';
// becomes 
export var name = 'todd';
export var value = 'person';
export default {name, value};

I think this would cover all commonJS use cases but I'm not sure. And the last import example is a nice to have.

@Rich-Harris
Copy link
Contributor

Thanks – this definitely does need more tests. At the moment it's a very basic proof-of-concept.

Sadly I don't think named imports/exports are realistic. It's just way too hard to cover all the many ways in which a CommonJS package author could foil whatever techniques we used to identify them:

var myPackage = exports;
myPackage.foo = function () {...}

function augment ( pkg ) {
  pkg.bar = function () {...}
}

augment( myPackage );

We couldn't turn that into named foo and bar exports, partly because of the limits of static analysis, partly because it would be very difficult to rewrite the code without risking breakage.

Fundamentally, a CommonJS module is only capable of exporting a single default object, much as it likes to pretend otherwise. (Not a criticism of CommonJS, that's just how it is – it took a change in the language to improve upon it.)

So, given that we'd fail to handle those cases (both of which I've seen in the wild) well, we should limit ourselves to default exports. It might be confusing for people who do...

import { named } from 'some-commonjs-module'

...but I think we can solve that with good error messages and documentation.

@reconbot
Copy link
Author

This leaves me grumpy. On one hand you're absolutely right. On the other I'm wondering if we can do a little bit of magic to enable rollup savings between most modules.

I could see the "cleverness risk" of named exports drop pretty low for the case of a direct assignment or property only assignment of module.exports when they are never accessed again.

And the only way to actually make use of the named exports is to know which exports we were able to name and the modify the imports accordingly. I'm willing to bet this would cover a large % of export statements with great success.

@Rich-Harris
Copy link
Contributor

Somehow we managed to implement this without closing this issue, at least on the exporter side – named exports are created alongside default exports where possible. We're not creating named imports, but there isn't really anything to be gained by doing so anyway

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

No branches or pull requests

2 participants