s-panferov / awesome-typescript-loader

Awesome TypeScript loader for webpack
Other
2.35k stars 179 forks source link

css module/ importing css files in tsx or ts files #146

Closed Truedrog closed 8 years ago

Truedrog commented 8 years ago

I am trying to make css-modules and typescript to work together with webpack.

So i have this file import * as styles from './styles.css'; which throwing an error about not found module. Ok. After some googling i've found this project https://github.com/Quramy/typed-css-modules so i created my styles.d.ts and tried to build, but got this error: ERROR in [default] File '/Users/~/Sites/webpack-starter/src/components/Button/styles.css has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'. ERROR in [default] /Users/~/Sites/webpack-starter/src/components/Button/index.tsx:3:24 Cannot find module './styles.css'.

i also tried to delete d.ts file and replace import to let styles = require('./styles.css'): but got same errors.

Truedrog commented 8 years ago

Forgot to mention that typed css modules approach is working in ts-loader.

s-panferov commented 8 years ago

Please show your webpack.config.json

Truedrog commented 8 years ago

@s-panferov this is the part where loader is used


/**
 * COMMON WEBPACK CONFIGURATION
 */

const path = require('path');
const webpack = require('webpack');

module.exports = (options) => ({
  entry: Object.assign({
    vendors: [
      'babel-polyfill',// needed for regenerator-runtime (ES7 generator support is required by redux-saga)
      'react',
      'react-dom',
      'redux',
      'react-redux',
    ],
    app: options.entry,
  }),
  output: Object.assign({ // Compile into js/build.js
    path: path.resolve(process.cwd(), 'build'),
    publicPath: '/',
    sourceMapFileName: '[name].[hash].js',
  }, options.output), // Merge with env dependent settings
  module: {
    loaders: [
      {
        test: /\.ts(x?)$/,
        loaders: [
          'react-hot',
          'babel?presets[]=es2015',
          'awesome-typescript-loader?configFileName=tsconfig.webpack.json',
        ],
        exclude: [/node_modules/, /\.(spec|e2e)\.ts(x?)$/],
      },
      // {
      //     test: /\.js$/, // Transform all .js files required somewhere with Babel
      //     loader: 'babel',
      //     exclude: /node_modules/,
      //     query: options.babelQuery,
      // },
      {
        //     // Transform our own .css files with PostCSS and CSS-modules
        test: /\.css$/,
        exclude: /node_modules/,
        loader: options.cssLoaders,
      },
      {
        // Do not transform vendor's CSS with CSS-modules
        // The point is that they remain in global scope.
        // Since we require these CSS files in our JS or CSS files,
        // they will be a part of our compilation either way.
        // So, no need for ExtractTextPlugin here.
        test: /\.css$/,
        include: /node_modules/,
        loaders: ['style-loader', 'css-loader'],
      },
      {
        test: /\.jpe?g$|\.gif$|\.png$/i,
        loader: 'url-loader?limit=10000',
      },
      {
        test: /\.html$/,
        loader: 'html-loader',
      }],
  },
  plugins: options.plugins.concat([
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors_[hash].js'),
  ]),
  postcss: () => options.postcssPlugins,
  resolve: {
    // modules: ['src', 'node_modules'],
    extensions: [
      '',
      '.webpack.js',
      '.web.js',
      '.tsx',
      '.ts',
      '.js'
    ],
    // packageMains: [
    //     'jsnext:main',
    //     'main',
    // ],
  },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
  stats: false, // Don't show stats in the console
  progress: true,
});
nomaed commented 8 years ago

Do you need to have the css to be assigned to a variable? I am using import './somefile.css'; or require('somefile.css'); and that's it, it works great.

I am getting the same error that you see when trying to import anything that's not a js/ts file and assign it to a variable. For these cases, I have to use require() for webpack to handle the dependency, instead of typescript. For example, when importing angular templates, I can't use import template from './somefile.html'; (or import * as template from './somefile.html';). I have to use: const template = <string>require('./somefile.html');

If there's a way to use import for these, I would love to hear about it, but from what I understand - it can't work in typescript.

Truedrog commented 8 years ago

I did use let styles = require<any>('./styles.css'); This is ok for compiler and vscode, no errors. And yes it has to be a variable. See https://github.com/css-modules/css-modules The problem is that I got runtime error from awesome-typescript-loader when the script is running. Ts-loader is working fine.

nomaed commented 8 years ago

I see. I am not using it inline but extracting all css files to a css bundle file, so that's not an issue for me.

Truedrog commented 8 years ago

Looks like my problem is gone. Don't really know why. Maybe because I refined my tsconfig file:

module:commonjs // was missing.

Closing.

testerez commented 8 years ago

I'm also getting this error: File '[...].scss' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'

When importing like this: import styles from './Box.scss';

I'm using ts 2.0.2 with this module definition:

declare module '*.scss' {
  const content: any;
  export default content;
}

tsc is happy with it and compile my files with no error. Is there any reason why awesome loader couldn't support it?

BevanR commented 7 years ago

This can also be fixed by adding an empty string to Webpack's resolve.extensions array.

    resolve: {
        // Support Typescript file extension.
        extensions: ['', '.ts']
    },

This is missing from the documentation:

screen shot 2016-12-14 at 2 51 17 pm

313 fixes that.

I used webpack --display-error-details to debug.

longlho commented 7 years ago

typescript 2.4.0-dev allow custom transformer so you can try using this

chyzwar commented 7 years ago

You can use module: 'es6' in typescript config, it would then allow for import styles from './x.css';

pmunin commented 7 years ago

import styles from './x.css'; didn't work for me, it shows me an error:

ERROR in ./src/_export.ts (2,20): error TS2307: Cannot find module './x.css'.

But it worked after I change that line to import './x.css'; Also in webpack.config.js I had the following loader:

{
        test: /\.css$/,
        loader:'style-loader!css-loader',
        exclude: /node_modules/
}

typescript version: 2.4.2 tsconfig.json has the following:

{
  "compilerOptions": {
    "sourceMap": true,
    "lib": [
      "dom",
      "es5",
      "scripthost",
      "es2015.iterable"
    ],
    "target": "es6",
    "allowSyntheticDefaultImports": true
  }
}
pouriaMaleki commented 7 years ago

@pmunin try this:

https://medium.com/@sapegin/css-modules-with-typescript-and-webpack-6b221ebe5f10

immanoj16 commented 6 years ago

simply write const styles = require('./Hello.css');. It will work. This article is helpful see this.

gabalicious commented 6 years ago

Nothing worked until I did what @immanoj16 suggested. const styles = require('./Hello.css')

Hano1388 commented 6 years ago

Another cause of this error, is to give it a wrong path when importing (styles.css | styles.scss) to index.tsx file. I was trying to import it with a wrong path and was getting the same error. Just wanted to let ya know, this is another cause of the issue so, make sure to give it the right path when you import it.

MartinDawson commented 6 years ago

@immanoj16 I see the benefit now. Thanks a lot for the link.

sanchay0 commented 6 years ago

If you don't find any of these comments helpful, typings-for-css-modules-loader is what you need. Watch this egghead video for more context.

JustFly1984 commented 5 years ago

@Hano1388 you've saved my day! I was forced to disable eslint-plugin-import rules cos it fails with typescript type and interface import/export declarations, and copy-pase imports is not safe anymore :(

vijeeshks commented 5 years ago

Hi.. just write normal javascript in ts like this

` var head = document.getElementsByTagName('HEAD')[0];

    // Create new link Element 
    var link = document.createElement('link'); 

    // set the attributes for link element  
    link.rel = 'stylesheet';  

    link.type = 'text/css'; 

    link.href = 'style.css';  

    // Append link element to HTML head 
    head.appendChild(link);  

` Now u can set the the classes using setAttribute option in HTML...