Skip to content
This repository has been archived by the owner on Oct 30, 2020. It is now read-only.

Generated typings not compatible with project #20

Open
aaronbeall opened this issue Jan 25, 2017 · 15 comments · Fixed by TeamSupercell/typings-for-css-modules-loader#2 · May be fixed by #51
Open

Generated typings not compatible with project #20

aaronbeall opened this issue Jan 25, 2017 · 15 comments · Fixed by TeamSupercell/typings-for-css-modules-loader#2 · May be fixed by #51

Comments

@aaronbeall
Copy link

I am using this loader setup for TypeScript and PostCSS with Webpack 1.13.1:

{
  test: /\.tsx?$/,
  loader: 'ts',
  exclude: /node_modules/
},
{
  test: /\.css$/,
  loader: 'style!typings-for-css-modules?modules&camelCase!postcss',
  //loader: 'style!css!postcss'
}

(The commented out css loader is the previous setup which works without CSS modules.)

When I import a .css file using import {locals as styles} from "./example.css" as the generated typings indicate, I get nothing at runtime. If I use import * as styles from "./example.css" I see all the class names at runtime, but still no locals, and TypeScript flags errors for all references, such as styles.myClassName.

@aaronbeall aaronbeall changed the title Generated typings not compatible with Generated typings not compatible with project Jan 25, 2017
@timse
Copy link
Contributor

timse commented Jan 26, 2017

can you paste the generated typings here?

@aaronbeall
Copy link
Author

aaronbeall commented Jan 27, 2017

Example:

export interface IEstimateProjectRowCss {
  'estimate-button': string;
  'estimateButton': string;
  'hovered': string;
  'selected': string;
  'bg': string;
}

export const locals: IEstimateProjectRowCss;

The thing I don't understand about this output is that locals is not a thing I see in the generated JS module at all.

The generated typings for namedExport seems correct, but some of our class names are reserved words so we cannot use this without some refactoring.

@aaronbeall
Copy link
Author

aaronbeall commented Jan 27, 2017

I think it's because I'm using style-loader. My whole loader is:

{
  test: /\.css$/,
  loader: 'style!typings-for-css-modules?modules&camelCase!postcss',
}

If I understand the comment in the documentation about exports being extracted out of locals when used with style-loader then it explains the mis-match.

But does this mean there's no way to use non-namedExport typings with style-loader?

@timse
Copy link
Contributor

timse commented Jan 30, 2017

need to look into this when i find the time!

@scamden
Copy link

scamden commented Oct 3, 2017

i see the same thing without using style-loader or postcss just fyi

my config with postcss commented out for testing:

        loader: 'typings-for-css-modules-loader',
        options: {
          namedExport: false,
          camelCase: true,
          sourceMap: true,
          modules: true,
          importLoaders: 1,
          localIdentName: '[name]__[local]___[hash:base64:5]'
        }
      },
      // {
      //   loader: 'postcss-loader',
      //   options: {
      //     plugins: (loader) => [
      //       autoprefixer(),
      //     ],
      //     sourceMap: true
      //   }
      // },
      'resolve-url-loader?sourceMap',
      'sass-loader?sourceMap'
    ]

passing the above to extract text plugin

scamden referenced this issue Oct 3, 2017
css-loader exports mappings to exports.locals, not to exports.default
@timse
Copy link
Contributor

timse commented Oct 4, 2017

any idea how to fix that @scamden ?

@scamden
Copy link

scamden commented Oct 5, 2017

sorry for the delay. many build issues to figure out at the moment :P

did you happen to see my comment on 81ff68c?

i'm not too sure but i think this commit is just wrong? css-modules seems to export not on a locals object at all but just at the root of the module. let me know if i'm missing something about how this all works but maybe the fix is to just revert this commit and go back to exporting as default?

@aaronbeall
Copy link
Author

aaronbeall commented Oct 6, 2017

@scamden Actually css-loader (and by extension typings-for-css-modules-loader) exports a locals object, but style-loader and ExtractTextPlugin both move all the keys of locals to be direct named exports. So the correct type defs really depends on whether or not style-loader or ExtractTextPlugin is in play. The namedExport option only toggles how typings-for-css-modules-loader exports in the type defs, not how the css module is actually exported -- that, again, depends on what else in play. This was my initial confusion that led me to enter this issue, but AFAIK the type defs are correct, it's just confusing to figure out what your type defs should actually be. I haven't really found an explanation on what or why the locals object is there and melts away with style-loader or ExtractTextPlugin, but documentation was never quite Webpack's strong point. :)

@scamden
Copy link

scamden commented Oct 10, 2017

@aaronbeall that makes sense. unfortunately it still leads to a bug right? because ultimately ts won't let me get the css class off the default object and if I use the locals object as the types suggest it fails at runtime (since they are not actually there after extract text loader runs). if you determined that this was ultimately correct how did you remedy? @timse is there a way to perhaps add a flag for style / extract text mode?

@aaronbeall
Copy link
Author

@scamden That's what namedExport does

@scamden
Copy link

scamden commented Oct 10, 2017

well unfortunately it's not all it does haha. it also causes classnames using reserved js keywords to fail. i would love to use namedExports, but it's not compatible with twitter bootstrap for example which uses the classname "in" for modal animations. would be awesome to have an option not to use named export but still export the big map object as default for loaders that expose it that way

@aaronbeall
Copy link
Author

aaronbeall commented Oct 10, 2017

Yeah, you're right. I guess there's just no way to use named exports with reserved words. It is possible to export top level reserved word keys, though, using export = syntax:

interface IFooCss { }
declare const styles: IFooCss;
export = styles;

That could be a new option?

As for the default export, that seems to only work if you use module: "es6" in tsconfig, whereas if you use commonjs for example you get no default imports. So again the right type defs depend on your configuration. This could be yet another option, now we have namedExport | exportLocals | exportInterface | defaultExport, which are mostly mutually exclusive. Or you could just refactor away your reserved words and use namedExport. :)

@scamden
Copy link

scamden commented Oct 10, 2017

(Secretly I did eventually change the classname in, thankfully we have a copy of bootstrap and are not compiling it directly from source but it does still seem like a bug for others)

@sarink
Copy link

sarink commented Dec 4, 2017

Is there anyone who's actually using this without the style-loader? How do you get your CSS into the DOM without it?

I think there really needs to be an option to toggle this behavior.

I would happily use namedExport, but I require the interface, and it seems that it disappears when you turned namedExport on :(

sarink added a commit to sarink/typings-for-css-modules-loader that referenced this issue Dec 4, 2017
When using the `style-loader`, the `locals` object gets invisibly murdered. Fixes Jimdo#20. If someone's not using the `style-loader` they can `import {locals}`, and if they _are_ using the `style-loader`, they can use the default import. This should make everyone happy, and be fully backwards-compatible.
@scamden
Copy link

scamden commented Dec 7, 2017

@sarink extract text plugin is the alternative

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