Tsdx: [tsdx-config] Css module build fail

Created on 27 Aug 2019  Â·  29Comments  Â·  Source: formium/tsdx

Hi guys,
I just installed tsdx to try out the new functionality of the config file.
The step I followed are:
1) in the root of the project I created a file called tsdx.config.js:

const postcss = require('rollup-plugin-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

module.exports = {
  rollup(config, options) {
    config.plugins.push(
      postcss({
        plugins: [
          autoprefixer(),
          cssnano({
            preset: 'default',
          }),
        ],
        inject: false,
        // only write out CSS for the first bundle (avoids pointless extra files):
        extract: !!options.writeMeta,
        modules: true,
      })
    );
    return config;
  },
};

2) I installed the 3 dependencies that are required;
3) in the src folder I create a file called: style.module.css
4) in the index.tsx I imported it:

import * as React from 'react';
import * as style './style.module.css';
// Delete me
export const Thing = () => {
  return (
    <div className={style.test}>the snozzberries taste like snozzberries</div>
  );
};

5) running yarn start

✖ Failed to compile
(typescript) Error: /Users/daniele/Desktop/testLibTsDx/src/index.tsx(2,19): syntax error TS1005: 'from' expected.
Error: /Users/daniele/Desktop/testLibTsDx/src/index.tsx(2,19): syntax error TS1005: 'from' expected.
    at error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:9429:30)
    at throwPluginError (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:15701:12)
    at Object.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:15756:24)
    at Object.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:16148:38)
    at RollupContext.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:17187:30)
    at lodash_3 (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:24954:23)
    at arrayEach (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:532:11)
    at forEach (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:9360:14)
    at printDiagnostics (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:24927:5)
    at Object.transform (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:26754:17)

✨  Done in 2.18s.

Did I miss something?

support integration

Most helpful comment

For all the people are struggling to add css modules to tsdx this is the solution:
1) Create tsdx.config.js

const postcss = require('rollup-plugin-postcss');
module.exports = {
  rollup(config, options) {
    config.plugins.push(
      postcss({
        modules: true,
      })
    );
    return config;
  },
};

2) install rollup-plugin-postcss

 yarn add rollup-plugin-postcss -dev

3) in the src folder create a file called typings.d.ts:

declare module '*.css' {
  const content: { [className: string]: string };
  export default content;
}

4) in the src folder create a file called style.module.css

.test {
  color: red;
}

5) in the index.tsx import it:

import * as React from 'react';
import styles from './style.module.css';
// Delete me
export const Thing = () => {
  return (
    <div className={styles.test}>the snozzberries taste like snozzberries</div>
  );
};

@jaredpalmer feel free to close it or set as fixed or I can create a PR to your readme to add is an example. Up to you and thanks again for the great work!

All 29 comments

index.tsx(2,19): syntax error TS1005: 'from' expected.

you forgot "from". read your own error please.

Sorry my bad. After trying different things I missed the from this is the right error message:

import * as React from 'react';
import * as style from './style.module.css';
// Delete me
export const Thing = () => {
  return (
    <div className={style.test}>the snozzberries taste like snozzberries</div>
  );
};
✖ Failed to compile
(typescript) Error: /Users/daniele/Desktop/testLibTsDx/src/index.tsx(2,24): semantic error TS2307: Cannot find module './style.module.css'.
Error: /Users/daniele/Desktop/testLibTsDx/src/index.tsx(2,24): semantic error TS2307: Cannot find module './style.module.css'.
    at error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:9429:30)
    at throwPluginError (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:15701:12)
    at Object.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:15756:24)
    at Object.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup/dist/rollup.js:16148:38)
    at RollupContext.error (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:17187:30)
    at lodash_3 (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:24954:23)
    at arrayEach (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:532:11)
    at forEach (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:9360:14)
    at printDiagnostics (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:24927:5)
    at Object.transform (/Users/daniele/Desktop/testLibTsDx/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:26754:17)

✨  Done in 2.15s.

I also tried:

import style from './style.module.css';

can you please reopen? @sw-yx

I don't use CSS modules, but you may need a specific TS rollup setup to make them work. The one i used just does regular css and scss if node-sass is installed IIRC.

The good news is that you have the flexibility now with tsdx.config.js to do this on your own.

@jaredpalmer I took the documentation from your readme :) this is what I'm trying out! If you look up on my comment you'll find the tsdx.config.js I'm using

I meant that this can be solved by you (in userland) and is now outside the scope of the project. My example doesn't support css modules. You will need to make some changes.

@jaredpalmer ok I'm confused. From the readme of https://github.com/egoist/rollup-plugin-postcss
they say:
https://github.com/egoist/rollup-plugin-postcss#css-modules
or in other words:

 modules: true,

and is exactly what I added from your example.
Another thing if in my node_modules I look in the tsdx folder something related to tsdxconfig I'm not able to find any occurrence. I've installed 0.8

I forgot to publish 0.9 the other day, so docs did not reflect the current version. This is fixed now. I'm so sorry!

Ahah I was sure about that. No problem it happen. I’ll have another try tomorrow morning and if everything is ok I’ll take care to close my ticket.
Thanks for the awesome work.

despite this time, I can see in the node_modules thetsdxConfig I still got the same annoying error. Someone has been able to get it working?
Thanks,
Daniele.

For all the people are struggling to add css modules to tsdx this is the solution:
1) Create tsdx.config.js

const postcss = require('rollup-plugin-postcss');
module.exports = {
  rollup(config, options) {
    config.plugins.push(
      postcss({
        modules: true,
      })
    );
    return config;
  },
};

2) install rollup-plugin-postcss

 yarn add rollup-plugin-postcss -dev

3) in the src folder create a file called typings.d.ts:

declare module '*.css' {
  const content: { [className: string]: string };
  export default content;
}

4) in the src folder create a file called style.module.css

.test {
  color: red;
}

5) in the index.tsx import it:

import * as React from 'react';
import styles from './style.module.css';
// Delete me
export const Thing = () => {
  return (
    <div className={styles.test}>the snozzberries taste like snozzberries</div>
  );
};

@jaredpalmer feel free to close it or set as fixed or I can create a PR to your readme to add is an example. Up to you and thanks again for the great work!

@daniele-zurico @jaredpalmer You can use vscode typed-css-modules plugin with npm [email protected] instaled globally to create correct .d.ts files on save, or use npm dts-gen cli to do the same.

@daniele-zurico After trying your code I get a

(Typescript plugin) SyntaxError: error.

style.module.css: Unexpected token (1:0)

> 1 | .test {
    | ^
  2 |     color: black;
  3 |     font-style: italic;
  4 | }

New to TypeScript. What is going wrong?

@marijnbent try to comment the content of src/typings.d.ts

Hi,
I am facing the same problem. I need a .css file in my project and I am trying to import it but I am continuously getting the same error. I tried the code given by @daniele-zurico and I am still facing the same problem.

image

Any help would be appreciated.
Thanks.

Almost as if the tsdx.config.js file isn't overriding some values and postcss isn't triggered. If inject is set to false, and cssnano is added, I still see an injected css file..

@Ajamuar Hi! Did you solve the problem?

I put the typings.d.ts file in the src directory and downgrade the version of tdx to 0.9.3. That helped

@daniele-zurico @teplenin I have the same problem of @Ajamuar using Daniele's solution and "tsdx": "^0.10.5". Downgrading to 0.9.3 the build passes.

I think is the case to open a new ticket! I dint try on the new version so I’m not sure but It looks like a regression problem

@daniele-zurico @jaredpalmer I opened a related BUG issue here: https://github.com/jaredpalmer/tsdx/issues/284

I think it's not strictly related to CSS-MODULES as much as a more generic issue with Rollup custom config in tsdx.config.js.

@teplenin Hi, I couldn't find a solution, so I moved my styling inside the tsx file. It isn't the ideal solution but it works. In short, I removed the styling file altogether.

This works for me:

  • tsdx 0.11.0
  • src/typings.d.ts:
declare module '*.css' {
  const content: {[className: string]: string}
  export default content
}
  • tsdx.config.js:
const postcss = require('rollup-plugin-postcss')
const autoprefixer = require('autoprefixer')
const cssnano = require('cssnano')

module.exports = {
  /**
   * @param {import('rollup/dist/rollup').InputOptions} config
   */
  rollup(config, options) {
    config.plugins.push(
      postcss({
        modules: true,
        plugins: [
          autoprefixer(),
          cssnano({
            preset: 'default',
          }),
        ],
        inject: false,
        // only write out CSS for the first bundle (avoids pointless extra files):
        extract: !!options.writeMeta,
      })
    )
    return config
  },
}
  • import styles from './style.module.css' -> {container: "style-module_container__30I_8", list: "style-module_list__3gJhy", listItem: "style-module_listItem__2pC6c"}

@Idered your config works thanks to tzdx 0.11.0. All the 0.10.x versions have a bug that break the build importing any .css file. Nothing else 😉.

For anyone who comes here and is trying to figure out why your CSS isn't getting compiled with your TypeScript code, you have to have inject: true.

Here's my config:

/* eslint-disable @typescript-eslint/no-var-requires */
const postcss = require('rollup-plugin-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

module.exports = {
    /**
     * @param {import('rollup/dist/rollup').InputOptions} config
     */
    rollup(config, options) {
        config.plugins.push(
            postcss({
                modules: true,
                plugins: [
                    autoprefixer(),
                    cssnano({
                        preset: 'default',
                    }),
                ],
                sourceMap: true,
                inject: true,
                extract: false,
            })
        );
        return config;
    },
};

@dgreene1 not sure what you mean by "your CSS isn't getting compiled with your TypeScript code". The method in the docs with extract: !!options.writeMeta puts your CSS into a separate file (like Webpack's MiniCssExtractPlugin), and it does work, there's even an integration test for it.

inject is always false when extract is true, so you've inverted the docs' configuration for a different result. inject true and extract false are actually the defaults for rollup-plugin-postcss, so you don't need to explicitly configure those.
From your comment it's not clear what specifically you're trying to achieve by doing so. Are you trying to have style tags injected into consumer code? Usually a library lets consumers choose to use styles (or build them into the components themselves or have a single file to explicitly import), hence extract being a reasonable default to use for most of TSDX's use-case.

But you can configure differently sure, up to you how or if you want to use rollup-plugin-postcss. This specific issue is partially around typings with CSS as well as some bugs that occurred older versions of TSDX

Thank you for the clarity. My libraries consumers are a bit inexperienced and they couldn’t figure out how to import the CSS so I’m packaging it with the JS. But maybe there are disadvantages of that?

The advantages though of inject:true are:

  • easier installs for newbies
  • tree shaking of styles

@dgreene1 there are a few disadvantages. Here's the table from Webpack's extract-text-webpack-plugin docs (which is an equivalent in Webpack-land), listing advantages and caveats of extraction (the inverse of what you asked):

Advantages | Caveats
-- | --
Fewer style tags (older IE has a limit) | Additional HTTP request
CSS SourceMap (with devtool: "source-map" and extract-text-webpack-plugin?sourceMap) | Longer compilation time
CSS requested in parallel | No runtime public path modification
CSS cached separate | No Hot Module Replacement
Faster runtime (less code and DOM operations) | ...

I'd summarize the key disadvantages of injection as:

  1. A runtime component, style-inject, is now bundled with your app. It's tiny, but it's additional heft
  2. The styles are injected as they are loaded into the head, making the browser do more work. There's also more overhead incurred when the browser parses many small chunks as opposed to one big chunk.
  3. (Typically) Worse caching as CSS is cached with JS instead of separately

There are also disadvantages specifically from the library perspective:

  1. The injected styles may be a surprise to users. In the extracted variant, users have to _explicitly_ import the styles, so much less chance of surprise there.
  2. It's fairly difficult to override injected styles and even harder to remove them. This makes customization more difficult. In-line styles are actually better for this. (Larger libraries like component kits usually have specific ways of overriding styles)
  3. Might be duplicating runtime style-injectors in a few places

It might also make some pieces of your JS library harder to tree-shake as the injection is a side-effect, but I'm not totally sure on that as I don't know all the nuances of side-effect detection.

You know your library consumers best and what to do for their use case. I just chimed in because I saw "CSS isn't getting compiled" and I was like "hold up I wrote integration tests for this" 😆


I'll be locking this issue soon as this, broken v0.10 stuff, etc are all different from the original issue. These things are getting jumbled together and likely make it much harder to understand for readers.

Was this page helpful?
0 / 5 - 0 ratings