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

classnames_1.default is not a function #1

Open
jednano opened this issue Dec 10, 2016 · 3 comments
Open

classnames_1.default is not a function #1

jednano opened this issue Dec 10, 2016 · 3 comments

Comments

@jednano
Copy link
Owner

jednano commented Dec 10, 2016

On my classnames branch, the dev server starts just fine with npm start; however, I get the following runtime error when I try to load the home page:

listening on port: 8080
ts-loader: Using typescript@2.2.0-dev.20161207 and z:\Documents\GitHub\tsx-react-postcss-webpack\tsconfig.json
webpack built fbd56652ab3fa37fda1d in 9670ms
TypeError: classnames_1.default is not a function
    at Constructor.render (z:\Documents\GitHub\tsx-react-postcss-webpack\components\Home.js:14:43)

Next, I tried changing the import statement in Home.js from:

import classnames from 'classnames';

to:

import * as classnames from 'classnames';

And now I get another runtime error, but it displays in-browser:

image

Now, I tried what @bowdenk7 and @DanielRosenwasser suggested by manually changing the classnames definition to the following:

declare var classNames: ClassNamesFn;
declare namespace classNames { }
declare module "classnames" { 
     export = classNames;
}

I also tried export default classNames as well as declare function classNames(...classes: ClassValue[]): string;

But I get the exact same error at runtime in the browser, so I inspected the source code of classnames and found this gem:

	if (typeof module !== 'undefined' && module.exports) {
		module.exports = classNames;
	} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
		// register as 'classnames', consistent with npm package name
		define('classnames', [], function () {
			return classNames;
		});
	} else {
		window.classNames = classNames;
	}

Which made me realize that it actually does return a function, so I changed the import syntax back to:

import classnames from 'classnames';

No dice, so I added the allowSyntheticDefaultImports compiler flag in my tsconfig.json and now I get:

TypeError: classnames_1.default is not a function

I cannot find a fix here! Is the issue with the classnames library? Because this all works perfectly in Babel compilation.

@jednano
Copy link
Owner Author

jednano commented Dec 10, 2016

I also tried changing my module compiler option to es6, but then I get:

z:\Documents\GitHub\tsx-react-postcss-webpack\boot.ts:1
(function (exports, require, module, __filename, __dirname) { import './server';
                                                              ^^^^^^

@jednano
Copy link
Owner Author

jednano commented Dec 10, 2016

Adding the following to the actual classnames source code does fix everything:

		Object.defineProperty(exports, "__esModule", { value: true });
		exports.default = classNames;

But I'm not at all sure that's the right approach, or I would submit a PR.

@jednano
Copy link
Owner Author

jednano commented Dec 11, 2016

I think I've identified the problem as the fact that my webpack setup transpiles with TypeScript first, followed by Babel. Since they have different ways of importing, that's the problem. I could theoretically have TS compile to an ES5 target, but then other things break, like livereload. I think the solution, at this point, is to just fix the classnames module to properly export its default module, for which I've submitted a PR.

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

1 participant