admin管理员组

文章数量:1336340

I am trying to add CSS to my ponent built in React using SSR, but I am unable to do so.

Things I've looked at:

  • /?v=v10.0.0-alpha.22
  • webpack loaders

But in none the process is simple or clearly mentioned. The one which I tried a lot was isomorphic loader which seemed promising, but then it gave some vague errors after setting it in my CSS files:

Unexpected token (1:0) You may need an appropriate loader to handle this file type.

This is my boilerplate package -

How do I add styles to my React SSR code.

Update

const dev = process.env.NODE_ENV !== "production";
const path = require( "path" );
const { BundleAnalyzerPlugin } = require( "webpack-bundle-analyzer" );
const FriendlyErrorsWebpackPlugin = require( "friendly-errors-webpack-plugin" );

const plugins = [
    new FriendlyErrorsWebpackPlugin(),
];

if ( !dev ) {
    plugins.push( new BundleAnalyzerPlugin( {
        analyzerMode: "static",
        reportFilename: "webpack-report.html",
        openAnalyzer: false,
    } ) );
}

module.exports = {
    mode: dev ? "development" : "production",
    context: path.join( __dirname, "src" ),
    devtool: dev ? "none" : "source-map",
    entry: {
        app: "./client.js",
    },
    resolve: {
        modules: [
            path.resolve( "./src" ),
            "node_modules",
        ],
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_ponents)/,
                loader: "babel-loader",
            },
        ],
    },
    output: {
        path: path.resolve( __dirname, "dist" ),
        filename: "[name].bundle.js",
    },
    plugins,
};

I am trying to add CSS to my ponent built in React using SSR, but I am unable to do so.

Things I've looked at:

  • https://www.npmjs./package/isomorphic-style-loader
  • https://cssinjs/server-side-rendering/?v=v10.0.0-alpha.22
  • webpack loaders

But in none the process is simple or clearly mentioned. The one which I tried a lot was isomorphic loader which seemed promising, but then it gave some vague errors after setting it in my CSS files:

Unexpected token (1:0) You may need an appropriate loader to handle this file type.

This is my boilerplate package - https://github./alexnm/react-ssr

How do I add styles to my React SSR code.

Update

const dev = process.env.NODE_ENV !== "production";
const path = require( "path" );
const { BundleAnalyzerPlugin } = require( "webpack-bundle-analyzer" );
const FriendlyErrorsWebpackPlugin = require( "friendly-errors-webpack-plugin" );

const plugins = [
    new FriendlyErrorsWebpackPlugin(),
];

if ( !dev ) {
    plugins.push( new BundleAnalyzerPlugin( {
        analyzerMode: "static",
        reportFilename: "webpack-report.html",
        openAnalyzer: false,
    } ) );
}

module.exports = {
    mode: dev ? "development" : "production",
    context: path.join( __dirname, "src" ),
    devtool: dev ? "none" : "source-map",
    entry: {
        app: "./client.js",
    },
    resolve: {
        modules: [
            path.resolve( "./src" ),
            "node_modules",
        ],
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_ponents)/,
                loader: "babel-loader",
            },
        ],
    },
    output: {
        path: path.resolve( __dirname, "dist" ),
        filename: "[name].bundle.js",
    },
    plugins,
};
Share Improve this question edited Jul 14, 2019 at 6:58 Rahul Singh asked Jul 12, 2019 at 19:07 Rahul SinghRahul Singh 19.7k13 gold badges68 silver badges94 bronze badges 11
  • Can you share your webpack config ? – Ajay Varghese Commented Jul 14, 2019 at 6:55
  • @AjayVarghese i just did, but i have added all the loaders previously but i hope it works with your solutuon – Rahul Singh Commented Jul 14, 2019 at 6:57
  • Loader for CSS is missing in webpack config. – Ajay Varghese Commented Jul 14, 2019 at 7:34
  • @AjayVarghese i had added it but after it failed to work i removed it, if you check the isomorphic link it has the weboackconfig – Rahul Singh Commented Jul 14, 2019 at 7:35
  • Can you try adding this npmjs./package/css-loader ? – Ajay Varghese Commented Jul 14, 2019 at 7:37
 |  Show 6 more ments

2 Answers 2

Reset to default 4

Below configuration made CSS work
Packages installed:
babel-plugin-dynamic-import-node, babel-plugin-css-modules-transform, mini-css-extract-plugin, css-loader, style-loader

index.js

require( "babel-register" )( {
presets: [ "env" ],
plugins: [
    [
        "css-modules-transform",
        {
            camelCase: true,
            extensions: [ ".css", ".scss" ],
        }
    ],
    "dynamic-import-node"
],
} );
require( "./src/server" );

webpack.config.js

rules: [
        {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_ponents)/,
            loader: "babel-loader",
        },{
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader,
                },
                'css-loader'
            ],
        },
    ]

In webpack config, added following plugin

new MiniCssExtractPlugin({
    filename: "styles.css",
}),

In server.js, Added the following code inside head in htmlTemplate.

<link rel="stylesheet" type="text/css" href="./styles.css" />

Usage

import  "./../App.css";

<h2 className="wrapper">F1 2018 Season Calendar</h2>

I've went crazy trying to setup it up myself following all the mentioned approaches with no luck. In my case I'm using css-loader for create css modules syntax and SSR for React modules that aren't really big.

As someone mentioned because webpack will run twice you'll end with different class names which will make pop up some errors on the console saying that your server and client markups are different. To mitigate that you can create your own loader.

The idea is to store the value of the output from css-loader from one of the webpack pilations and use that for the next one. It might not be for what a loader is designed for but it does the job.

 /**
 * @typedef {Object} LoaderOptions
 * @property {"client" | "server"} type
 */

const mapContent = new Map();

/**
 * @param {LoaderOptions} options
 * @returns boolean
 */
const optionsValidator = (options) => {
  return (
    typeof options === 'object' &&
    'type' in options &&
    typeof options.type === 'string' &&
    (options.type === 'client' || options.type === 'server')
  );
};

module.exports = function (source) {
  /**
    @type import('./node_modules/webpack/types').LoaderContext<LoaderOptions>
   */
  const loader = this;
  const options = loader.getOptions();
  const logger = loader.getLogger();

  if (!optionsValidator(options)) {
    logger.error('css-ssr-replacer-loader. Only valid props are "type" with values of "client" or "server"');
  }

  const isClient = options.type === 'client';

  if (isClient) {
    mapContent.set(loader.resourcePath, Buffer.from(source));
  }

  return isClient ? source : mapContent.get(loader.resourcePath);
};

And then on your webpack you need to add something like the following

const webpackConfig = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'howEverYouWantToCallTheLoader',
            options: {
              type: 'client' || 'server'
            }
          },
          {
            loader: 'css-loader',
            options: {
              modules: {
                exportLocalsConvention: 'camelCase',
                localIdentName: '[local]_[hash:base64:8]',
                mode: 'local'
              }
            }
          }
        ]
      }
    ]
  },
  resolveLoader: {
    alias: {
      howEverYouWantToCallTheLoader: path.resolve(__dirname, 'pathToYourLoader.js')
    }
  }
};

本文标签: javascriptAdding CSS to React SSR ComponentsStack Overflow