egoist / rollup-plugin-postcss

Seamless integration between Rollup and PostCSS.
MIT License
677 stars 217 forks source link

undefined classname with typescript css modules #173

Closed oufresh closed 4 years ago

oufresh commented 5 years ago

Hello, I'm using rollup to build a typescript module with React components. I have this configuration of rollup:

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import external from "rollup-plugin-peer-deps-external";
import postcss from 'rollup-plugin-postcss'
import resolve from 'rollup-plugin-node-resolve';
import url from 'rollup-plugin-url';
import svgr from '@svgr/rollup';

import pkg from "./package.json";

export default {
  input: "src/index.tsx",
  output: [
    {
      file: pkg.main,
      format: "cjs",
      exports: "named",
      sourcemap: true
    },
    {
      file: pkg.module,
      format: "es",
      exports: "named",
      sourcemap: true
    }
  ],
  plugins: [
    external(),
    postcss({
      modules: true
    }),
    //css(),
    url(),
    svgr(),
    resolve(),
    typescript({
      rollupCommonJSResolveHack: true,
      exclude: "**/__tests__/**",
      clean: true
    }),
    commonjs({
      include: ["node_modules/**"],
      namedExports: {
        "node_modules/react/react.js": [
          "Children",
          "Component",
          "PropTypes",
          "createElement"
        ],
        "node_modules/react-dom/index.js": ["render"]
      }
    })
  ]
};

and this tsconfig.json

{
  "compilerOptions": {
    "outDir": "build",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom", "es2016", "es2017"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "declaration": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "build", "demo", "dist", "example", "rollup.config.js"]
}

During the build I have this waring:

src/MyComponent.tsx
MyComponentBackGround is not exported by src/MyComponent.module.css
3: export var MyComponent = function (props) {
4:     var str = "Hello, the text is: " + props.text;
5:     return React.createElement("div", { className: style.MyComponentBackGround },
                                                            ^
6:         React.createElement("label", null, str));
7: };
```bash

and if I look into the builded index.js I see:

```javascript
var css = ".MyComponent-module_MyComponentBackGround__2MMVh {\n    background-color: antiquewhite;\n    color: black;\n    padding: 5px;\n}";
var MyComponent_module = {"MyComponentBackGround":"MyComponent-module_MyComponentBackGround__2MMVh"};
styleInject(css);

var style = /*#__PURE__*/Object.freeze({
    'default': MyComponent_module
});

var MyComponent = function (props) {
    var str = "Hello, the text is: " + props.text;
    return React.createElement("div", { className: undefined },
        React.createElement("label", null, str));
};

Note { className: undefined }

I have in the src directory the files:

MyComponent.tsx

import * as React from "react";
import * as style from "./MyComponent.module.css";

export interface IMyComponentProps {
    text: string;
}

export const MyComponent = (props: IMyComponentProps) => {
    const str = "Hello, the text is: " + props.text;
    return <div className={style.MyComponentBackGround}><label>{str}</label></div>;
};

MyComponent.module.css

.MyComponentBackGround {
    background-color: antiquewhite;
    color: black;
    padding: 5px;
}```

**MyComponent.module.css.d.ts**

```javascript
declare const styles: {
  readonly "MyComponentBackGround": string;
};
export = styles;

As expected when I use the component exported by the module in a demo app the style doesn't work and there's no classname in the html div.

Can you help me to solve this issue?

Thanks all.

oufresh commented 4 years ago

Hello,

I added

 postcss({
            extract: false,  // extracts to `${basename(dest)}.css`
            plugins: [autoprefixer()],
            writeDefinitions: true,
            // modules: { ... }
        }),

to the configuration of rollup and it works correctly with imports of css modules.

Anyway I updated some projects and I'm currently using @rollup/plugin-typescript and rollup-plugin-postcss. It works with this configuration:

// rollup.config.js
import typescript from "@rollup/plugin-typescript";
import postcss from "rollup-plugin-postcss";
import autoprefixer from "autoprefixer";
import serve from "rollup-plugin-serve";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import replace from "@rollup/plugin-replace";

const dev = "development";
const prod = "production";

function parseNodeEnv(nodeEnv) {
  if (nodeEnv === prod || nodeEnv === dev) {
    return nodeEnv;
  }
  return dev;
}

const nodeEnv = parseNodeEnv(process.env.NODE_ENV);
console.log("Found Node Env: ", nodeEnv);

const plugins = [typescript(),
  replace({
    // The react sources include a reference to process.env.NODE_ENV so we need to replace it here with the actual value
    "process.env.NODE_ENV": JSON.stringify(nodeEnv)
  }),
  postcss({
    extract: false,
    writeDefinitions: true,
    modules: true,
    namedExports: true,
    plugins: [autoprefixer()]
  }),
  resolve(),
  commonjs({
    include: "node_modules/**"
  })];

if (nodeEnv === dev) {
    // For playing around with just frontend code the serve plugin is pretty nice.
    // We removed it when we started doing actual backend work.
    plugins.push(serve("build"))
}

export default {
  input: "src/index.tsx",
  output: {
    dir: "build",
    format: "esm",
    sourcemap: true
  },
  plugins: plugins
};