jednano / tsx-react-postcss-webpack

TypeScript/React/PostCSS/Webpack Starter
MIT License
0 stars 1 forks source link

classnames_1.default is not a function #1

Open jednano opened 7 years ago

jednano commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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.