Skip to content

Commit

Permalink
Add tests for CSS Modules with React
Browse files Browse the repository at this point in the history
  • Loading branch information
Kocal committed Sep 20, 2024
1 parent dbd5e5d commit 0f7130e
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 2 deletions.
12 changes: 12 additions & 0 deletions fixtures/react-css-modules/components/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import './styles.css';
import './styles.less';
import './styles.scss';
import './styles.stylus';
import stylesCss from './styles.module.css?module';
import stylesLess from './styles.module.less?module';
import stylesScss from './styles.module.scss?module';
import stylesStylus from './styles.module.stylus?module';

export default function App() {
return <div className={`red large justified lowercase ${stylesCss.italic} ${stylesLess.underline} ${stylesScss.bold} ${stylesStylus.rtl}`}></div>
}
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.red {
color: red;
}
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.justified {
text-align: justify;
}
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.italic {
font-style: italic;
}
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.underline {
text-decoration: underline;
}
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.bold {
font-weight: bold;
}
2 changes: 2 additions & 0 deletions fixtures/react-css-modules/components/styles.module.stylus
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.rtl
direction: rtl;
3 changes: 3 additions & 0 deletions fixtures/react-css-modules/components/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.large {
font-size: 50px;
}
2 changes: 2 additions & 0 deletions fixtures/react-css-modules/components/styles.stylus
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.lowercase
text-transform: lowercase
6 changes: 6 additions & 0 deletions fixtures/react-css-modules/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {createRoot} from 'react-dom/client';
import App from './components/App';

const root = createRoot(document.getElementById('app'));

root.render(<App />);
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
"preact": "^10.5.0",
"preact-compat": "^3.17.0",
"puppeteer": "^23.2.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sass": "^1.17.0",
"sass-loader": "^16.0.1",
"sinon": "^14.0.0",
Expand Down
91 changes: 90 additions & 1 deletion test/functional.js
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,96 @@ module.exports = {
});
});

it('React supports CSS/Sass/Less/Stylus modules', (done) => {
const appDir = testSetup.createTestAppDir();
const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev');
config.enableSingleRuntimeChunk();
config.setPublicPath('/build');
config.addEntry('main', './react-css-modules/main.js');
config.enableReactPreset();
config.configureBabel(function(config) {
config.presets = [
['@babel/preset-react', {
runtime: 'automatic', // TODO: To remove when Babel 8, "automatic" will become the default value
}]
];
});
config.enableSassLoader();
config.enableLessLoader();
config.enableStylusLoader();
config.configureCssLoader(options => {
// Remove hashes from local ident names
// since they are not always the same.
if (options.modules) {
options.modules.localIdentName = '[local]_foo';
}
});

// Enable the PostCSS loader so we can use `lang="postcss"`
config.enablePostCssLoader();
fs.writeFileSync(
path.join(appDir, 'postcss.config.js'),
`
module.exports = {
plugins: [
require('autoprefixer')()
]
} `
);

testSetup.runWebpack(config, (webpackAssert) => {
console.log(config.outputPath);
expect(config.outputPath).to.be.a.directory().with.deep.files([
'main.js',
'main.css',
'manifest.json',
'entrypoints.json',
'runtime.js',
]);

const expectClassDeclaration = (className) => {
webpackAssert.assertOutputFileContains(
'main.css',
`.${className} {`
);
};

expectClassDeclaration('red'); // Standard CSS
expectClassDeclaration('large'); // Standard SCSS
expectClassDeclaration('justified'); // Standard Less
expectClassDeclaration('lowercase'); // Standard Stylus

expectClassDeclaration('italic_foo'); // CSS Module
expectClassDeclaration('bold_foo'); // SCSS Module
expectClassDeclaration('underline_foo'); // Less Module
expectClassDeclaration('rtl_foo'); // Stylus Module

testSetup.requestTestPage(
browser,
path.join(config.getContext(), 'www'),
[
'build/runtime.js',
'build/main.js'
],
async({ page }) => {
const divClassArray = await page.evaluate(() => Array.from(document.body.querySelector('#app > div').classList.values()));

expect(divClassArray.includes('red')).to.be.true; // Standard CSS
expect(divClassArray.includes('large')).to.be.true; // Standard SCSS
expect(divClassArray.includes('justified')).to.be.true; // Standard Less
expect(divClassArray.includes('lowercase')).to.be.true; // Standard Stylus

expect(divClassArray.includes('italic_foo')).to.be.true; // CSS module
expect(divClassArray.includes('bold_foo')).to.be.true; // SCSS module
expect(divClassArray.includes('underline_foo')).to.be.true; // Less module
expect(divClassArray.includes('rtl_foo')).to.be.true; // Stylus module

done();
}
);
});
});

it('Preact supports CSS/Sass/Less/Stylus modules', (done) => {
const appDir = testSetup.createTestAppDir();
const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev');
Expand Down Expand Up @@ -1802,7 +1892,6 @@ module.exports = {
});
});


it('Vue.js error when using non-activated loaders', (done) => {
const config = createWebpackConfig('www/build', 'dev');
config.setPublicPath('/build');
Expand Down
24 changes: 23 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4851,7 +4851,7 @@ log-symbols@^4.1.0:
chalk "^4.1.0"
is-unicode-supported "^0.1.0"

loose-envify@^1.0.0, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
Expand Down Expand Up @@ -5918,11 +5918,26 @@ raw-body@2.5.2:
iconv-lite "0.4.24"
unpipe "1.0.0"

react-dom@^18.0.0:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.2"

react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==

react@^18.0.0:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
dependencies:
loose-envify "^1.1.0"

readable-stream@^2.0.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
Expand Down Expand Up @@ -6183,6 +6198,13 @@ sax@~1.3.0:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==

scheduler@^0.23.2:
version "0.23.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==
dependencies:
loose-envify "^1.1.0"

schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe"
Expand Down

0 comments on commit 0f7130e

Please # to comment.