It's a small demo to show how to set up css-modules-require-hook with webpack and react. If you are familiar with the technologies you can jump to the quick start. Otherwise, you can find detailed description below.
Make sure that you have Node.js and npm and run these commands:
$ git clone [email protected]:css-modules/css-modules-require-hook.git
$ cd css-modules-require-hook/demo
$ npm install
$ npm run compile
$ npm run start
Open http://localhost:3000/.
In short CSS Modules provide modularity with generated class names. Therefore, generated names should be present in CSS styles and in templates which form resulting html. Since, we talk about server rendering in the current example I'll show you how to set require hook to generate the same names in runtime as the CSS styles.
The modern frontend is so tough that you have to use particular bundler systems in order to generate a simple CSS file. My favourite one is webpack, so I'll show you how to set it with the require hook.
To understand webpack configs you should be familiar with loaders. In order to use CSS Modules with webpack you should set css-loader. Also extract-text-webpack-plugin provides you possibility to create pure CSS file. So eventually, your configuration should look similar to this:
module: {
loaders: [
{
test: /\.css$/i,
loader: ExtractTextPlugin.extract('style',
'css?modules&localIdentName=[name]_[local]__[hash:base64:5]'),
},
],
},
plugins: [
new ExtractTextPlugin('styles.css', {
allChunks: true
}),
],
I use express to handle user requests and react components to serve html for them. In order to make it independent and good looking I decided to use a custom template engine to isolate all the rendering stuff and to have neat calls in the middlewares. So, here is my structure:
- app/
view-engine.js
worker.js
Is an entry point for the app. It sets react template engine:
// sets react rendering engine
app.engine('js', viewEngine);
app.set('views', path.join(__dirname, '../components'));
app.set('view engine', 'js');
and declares basic middlewares:
app.get('/', (req, res) => res.render('Page'));
Describes the simple template engine and attaches require hook:
// teaches node.js to load css files
// uses external config cmrh.conf.js
require('css-modules-require-hook/preset');
Note that to generate the same names in runtime as the CSS styles you should provide the same pattern to webpack and to the require hook.
Use localIdentName
for webpack:
loader: ExtractTextPlugin.extract('style',
'css?modules&localIdentName=[name]_[local]__[hash:base64:5]'),
and generateScopedName
for the require hook. For example, if you use presets then you can put it to the cmrh.conf.js
file:
module.exports = {
// the custom template for the generic classes
generateScopedName: '[name]_[local]__[hash:base64:5]',
};