8000 css module issue · Issue #626 · symfony/webpack-encore · GitHub
[go: up one dir, main page]

Skip to content

css module issue #626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lowki opened this issue Aug 13, 2019 · 13 comments
Closed

css module issue #626

lowki opened this issue Aug 13, 2019 · 13 comments

Comments

@lowki
Copy link
lowki commented Aug 13, 2019

Hello.
I can't get css module fully working in my React app.

The problem is that it only works if I use the :local(.myClassName) notation in my .scss files

Here's a js sample

import React from 'react'
import styles from './Card.scss'

class Card extends React.Component {
  render () {
    return (
      <a className={styles.card} id={'card'}/>
   )
  }
}

export default Card

Here's a scss sample

.card {
  border: 1px solid #dadada;
  display: block;
  text-decoration: none;
  color: #000;
}

And the generated dom (no class tag)

<a id="card"></a>

Here is my webpack.config.js

var Encore = require('@symfony/webpack-encore')
var CopyWebpackPlugin = require('copy-webpack-plugin')
Encore
  .setOutputPath('web/build/')
  .setPublicPath('/build')
  .enableSingleRuntimeChunk()
  .cleanupOutputBeforeBuild()
  .enableSourceMaps(!Encore.isProduction())
  .enableVersioning(Encore.isProduction())
  .addEntry('app', './assets/js/index.js')
  .copyFiles({
    from: './assets/img',
    to: 'img/[path][name].[ext]'
  })
  .enableReactPreset()
  .enableSassLoader()
  .addPlugin(new CopyWebpackPlugin([
    { from: './assets/pwa', to: './' }
  ]))
module.exports = Encore.getWebpackConfig()
@Kocal
Copy link
Member
Kocal commented Aug 13, 2019

What about using import styles from './Card.scss?module'?

@lowki
Copy link
Author
lowki commented Aug 13, 2019

What about using import styles from './Card.scss?module'?

I wasn't aware of this notation, but it dos not change anything.

@nicolalamacchia
Copy link

I'm trying to use CSS modules with Encore, but I got stuck here. I have a component like this:

import React from 'react'
import style from '@style/Component.module.css?module'

const Component = () => <section className={style.section}><Stuff /></section>
export default Component

While in my webpack.config.js I have:

// ...
Encore
  // ...
  .enableSassLoader(() => ({ resolveUrlLoader: false }))
  // ...
// alias to @style which is working correctly
// ...

Am I missing something?

@nicolalamacchia
Copy link

Eventually I opted for something like this:

import style from '!!style-loader!css-loader?modules!@style/Component.module.css'

But I would prefer to update my webpack config in order to avoid the verbose import in every file.

@Lyrkan
Copy link
Collaborator
Lyrkan commented Dec 16, 2019

@nicolalamacchia If you want to enable modules globally you can probably do it using:

Encore.configureCssLoader(options => {
  options.modules = true;
});

Not sure why it doesn't work when importing something like @style/Component.module.css?module though... it should be matched by the first block (for which that option is already set to true by default) here:

oneOf: [
{
resourceQuery: /module/,
use: cssExtractLoaderUtil.prependLoaders(
this.webpackConfig,
cssLoaderUtil.getLoaders(this.webpackConfig, true)
)
},
{
use: cssExtractLoaderUtil.prependLoaders(
this.webpackConfig,
cssLoaderUtil.getLoaders(this.webpackConfig)
)
}
]

@nicolalamacchia
Copy link

I cannot use options.modules = true since it messes with my global CSS (namely Bootstrap).

@Lyrkan
Copy link
Collaborator
Lyrkan commented Dec 17, 2019

@nicolalamacchia Are you using a recent version of Encore? Modules seem to work properly with the following setup:

// webpack.config.js
const Encore = require('@symfony/webpack-encore');
const path = require('path');

Encore
  .cleanupOutputBeforeBuild()
  .setOutputPath('build/')
  .setPublicPath('/build')
  .addEntry('app', './assets/js/app.js')
  .enableSingleRuntimeChunk()
  .addAliases({
    '@style': path.resolve('./assets/css')
  })
;

module.exports = Encore.getWebpackConfig();
// assets/js/app.js
import style from '@style/app.css?module';

console.log(style);
/* assets/css/app.css */
.foo {
  background: #ff0000;
}

.bar {
  color: white;
}

Generated files:

/* build/app.css */
.foo_25gLR{background:red}.bar_3FvIL{color:#fff}
// build/app.js
(window.webpackJsonp=window.webpackJsonp||[]).push([["app"],{PhA5:function(o,n,s){o.exports={foo:"foo_25gLR",bar:"bar_3FvIL"}},ng4s:function(o,n,s){"use strict";s.r(n);var p=s("PhA5"),a=s.n(p);console.log(a.a)}},[["ng4s","runtime"]]])

@rmaury
Copy link
rmaury commented Nov 16, 2021

Hi, I had some similar issue (?module not working with jest ) and fixed it with something like that (with Webpack Encore) :

.configureCssLoader(options => {
options.modules = {
auto: /.module.\w+$/i
}})
And now you can create a file with '.module.scss' suffix, and you can import it in a ts file. It works with Jest.

@derekqq
Copy link
derekqq commented Mar 13, 2022

@rmaury I have a similar problem with jest, unfortunately adding your code does not help, can you please add the whole config wepback encore + jest here?

@rmaury
Copy link
rmaury commented Mar 14, 2022

@rmaury I have a similar problem with jest, unfortunately adding your code does not help, can you please add the whole config wepback encore + jest here?

Sorry for the delay

Yes of course,
In webpack file I'll have something like that (simplified version) :

// webpack.config.js
var Encore = require("@symfony/webpack-encore");
var path = require("path");

if (!Encore.isRuntimeEnvironmentConfigured()) {
  Encore.configureRuntimeEnvironment(process.env.NODE_ENV || "dev");
}

Encore.setOutputPath("public/build/")
  .setPublicPath("/build")
  .addEntry("app", "./assets/js/index.tsx")
  .splitEntryChunks()
  .enableSingleRuntimeChunk()
  .cleanupOutputBeforeBuild()
  .enableBuildNotifications()
  .enableSourceMaps(!Encore.isProduction())
  .enableVersioning(Encore.isProduction())
  .configureCssLoader(options => {
    options.modules = {
      auto: /\.module\.\w+$/i
    }
  })
  .enableSassLoader()
  .enableTypeScriptLoader()
  .enableReactPreset()
  .addEntry("polyfill", "babel-polyfill");

const config = Encore.getWebpackConfig();

module.exports = config;

A custom.module.sass in a sass folder

@import 'variables'

$theme-colors: ("primary": $primary, "danger": $danger, "success": $success, "light": $gray-100, "secondary": $secondary, "info": $info)

:export
  @each $key, $value in $theme-colors
    #{unquote($key)}: $value

A custom.module.sass.ts in the same folder

export interface I_globalSass {
  primary: string;
  danger: string;
  success: string;
  light: string;
  secondary: string;
  info: string;
}

export const variables: I_globalSass;

export default variables;

And in you component you can now import like that :

import variables from "../../../../sass/custom.module.sass";

Et voilà.

Now, You should be able to import your component in Jest file without error.

Just in case, for my project this is my jest.config.js

module.exports = {
  clearMocks: true,
  globals: {
    fetch: require('node-fetch'),
  },
  moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
  moduleNameMapper: {
    '\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/__mocks__/fileMock.js',
    '\\.(scss|sass|css|less)$': '<rootDir>/__mocks__/fileMock.js',
  },
  preset: 'ts-jest',
  setupFiles: ['<rootDir>/.jest/register-context.js'],
  setupFilesAfterEnv: ['<rootDir>/.jest/setupTests.js'],
  snapshotSerializers: ['enzyme-to-json/serializer'],
  testEnvironment: "jsdom",
  testMatch: ["<rootDir>/assets/**/*.test.(ts|tsx)"],
  moduleDirectories: [
    'node_modules'
  ],
  transform: {
    "\\.tsx?$": "ts-jest",
    "\\.jsx?$": "babel-jest", // if you have jsx tests too
  },
  globals: {
    "ts-jest": {
      "tsConfig": '<rootDir>/tsconfig.test.json'
    }
  },
  transformIgnorePatterns: [
    "[/\\\\]node_modules[/\\\\](?!lodash-es/).+\\.js$"
  ],

const { defaults } = require('jest-config');

And my tsconfig.json

{
  "compilerOptions": {
    "noImplicitAny": false,
    "target": "ES5",
    "module": "commonjs",
    "jsx": "react-jsx",
    "declaration": true,

    "outDir": "./public/build/",

    "strict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    /* Module Resolution Options */
    "moduleResolution": "node",

    "typeRoots": [
      "./node_modules/@types"
    ],
    "types": [
      "jest",
      "node"
    ],
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true, 
    "resolveJsonModule": true
  },
  "include": ["./assets/js/**/*", "./custom.d.ts", "./assets/__tests__/**/*"],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

@carsonbot
Copy link
Collaborator

Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?

1 similar comment
@carsonbot
Copy link
Collaborator

Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?

@rmaury
Copy link
rmaury commented May 15, 2025 via email

@carsonbot carsonbot removed the Stalled label May 15, 2025
@stof stof closed this as completed May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants
0