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

cssauron and babel #18

Closed
atomrc opened this issue Aug 2, 2017 · 14 comments
Closed

cssauron and babel #18

atomrc opened this issue Aug 2, 2017 · 14 comments

Comments

@atomrc
Copy link
Collaborator

atomrc commented Aug 2, 2017

Ok so I am not sure where the problem comes from exactly but here is what I am experiencing

  • In dev mode, I don't compile for an es5 target, so I don't run babel on the files, everything works as expected
  • in production mode, I need to be compatible with es5 so I need to give the js files to babel (and Uglify doesn't accept many es6 features so it crashes when trying to minify the bundle)

The thing is, cssauron is imported as follow (in the generated es2015 file in /lib)

import * as cssauron from 'cssauron';

Which is then compiled, by babel, into

var cssauron = _interopRequireWildcard(_cssauron)/* it's missing '.default' here */

And so my app now crashes.
I really don't know where the problem lies (my babel config file? my typescript config file? the import of cssauron? ...)

Do you have any idea how I can deal with this? I think updating the import to

import cssauron from 'cssauron'

would fix the problem, but maybe it's not THE solution.

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

Also, I see that the package contains es2015 and commonjs versions. Do you know how I can force typescript to use the commonjs version that would then solve my problem?

@TylorS
Copy link
Owner

TylorS commented Aug 2, 2017

Are you using webpack, or tsc directly, or something else?

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

I am using webpack. I have to admit I am really confused. I don't really understand how the import * as cssauron can work since cssauron only has a default export ...

@TylorS
Copy link
Owner

TylorS commented Aug 2, 2017

Cssauron is actually in commonjs. import * as cssauron from 'cssauron' compiles to commonjs as const cssauron = require('cssauron')

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

Actually no, babel doesn't seem to compile the same way typescript does. Here is my test input file

import * as cssauron from 'cssauron'
console.log(cssauron);

Which compiles to

'use strict';
var _cssauron = require('cssauron');
var cssauron = _interopRequireWildcard(_cssauron);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

console.log(cssauron);

And when I execute the compiled part, here is the output

{ default: [Function: language] } 

So Babel automatically added the default export. Which is why I get the error on my side. Do you thinks it would be a problem changing import * as to import cssauron ?

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

I think the problem is with the custom cssauron.d.ts type declaration. It declares a module that exports a named function while the original cssauron module only has a default export.

I am trying to fix this, but I have no idea how to do that ... :/

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

Well it seems the problem is not new microsoft/TypeScript#5285 and there seems to be a --allowSyntheticDefaultImports that fixes this.
I am currently trying to understand the reasons of all this. If you have any pointer that could help, I'd be grateful :)

@TylorS
Copy link
Owner

TylorS commented Aug 2, 2017

I've actually had this exact problem before, now that I think of it. The solution is fairly terrible, but maybe it's worth the hassle. I created a wrapper library that handled the differences in exports between commonjs and es2015 correctly. https://github.com/TylorS/typed-i18next

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 2, 2017

Outch :/ This is bad news! Do you know any way I could tell webpack to use the commonjs version of snabbdom-selector so that I don't have the problem with that import? Would using require("snabbdom-selector") work?

I am also using i18next (but I might not have seen the problem yet, I'll probably discover it once I fix this issue).
I hope I won't have to rollback using typescript on my code base,
I don't really feel like wrapping every single dependency that does this!

@TylorS
Copy link
Owner

TylorS commented Aug 3, 2017

Using require('snabbdom-selector') should work in webpack AFAIK

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 3, 2017

arf, no it still imports the es2015 version :/

Anyhow, I have tested many thing to fix this, but cannot find a suitable solution :(
This really feels like weird cause the meaning of import * as is "import every property exported by the module". So in case of a function it should only import the properties of the function, not the function itself.

I am really confused about this...

@atomrc
Copy link
Collaborator Author

atomrc commented Aug 3, 2017

Ok so finally I found a solution to my problem. I changed the resolve.mainFields in the webpack config to

resolve: {
  mainFields: ["main", "module"]
}

So now I use the main field in priority.

That being said, I feel we should remove the module and jsnext:main fields in the package.json as they can cause the trouble I was in.
What do you think?

@TylorS
Copy link
Owner

TylorS commented Aug 3, 2017

That seems like a very good short term solution.

@FeliciousX
Copy link

thanks @atromc .

extra reading >> http://www.thedreaming.org/2017/04/28/es6-imports-babel/

but yeah might be worth to make it work seamlessly on browser env without the hack

atomrc added a commit to atomrc/snabbdom-selector that referenced this issue Aug 4, 2017
@atomrc atomrc closed this as completed in e0ebe35 Aug 4, 2017
atomrc added a commit that referenced this issue Aug 4, 2017
Fix #18 Remove 'module' and 'jsnext:main' targets
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

No branches or pull requests

3 participants