Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

style-loader not working for Webpack2

I had simplified my webpack2 configuration. But still this is not working ( with no errors and warnings ).

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const svgDirs = [
  require.resolve('antd-mobile').replace(/warn\.js$/, ''),
  path.resolve(__dirname, 'src/assets/svg'),
];

module.exports = {
  entry: path.join(__dirname, 'src/index.js'),
  resolve: {
    modules: ['node_modules', path.join(__dirname, 'src')],
    extensions: ['.web.js', '.js', '.json'],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
      {
        test: /\.less$/,
        exclude: /node_modules/,
        loaders: ['style-loader', 'css-loader', 'less-loader'],
      },
      {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader'],
      },
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
      {
        test: /\.(svg)$/i,
        use: 'svg-sprite-loader',
        include: svgDirs,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      hash: true,
    }),
  ],
};

I tired to log these styles out. But all empty objects!

import styles1 from './Styles1.less';
import styles2 from './Styles2.css';
console.log(styles1); // empty object!
console.log(styles2); // empty object!
<div className={styles1.class1}></div> // not working

Below is my package.json and .babelrc if you need to check out.

package.json

{
  "private": true,
  "scripts": {
    "start": "cross-env NODE_ENV=development webpack-dev-server --hot --port 8000",
    "build": "webpack -p --progress --colors",
    "lint": "eslint --ext .js src test"
  },
  "dependencies": {
    "antd-mobile": "^1.1.0",
    "lodash": "^4.17.4",
    "moment": "^2.18.1",
    "react": "15.4.2",
    "react-dom": "15.4.2",
    "react-native": "0.42.3",
    "react-redux": "^5.0.4",
    "react-router": "^4.1.1",
    "react-router-redux": "^4.0.8",
    "redux": "^3.6.0",
    "redux-saga": "^0.14.8",
    "regenerator-runtime": "^0.10.3"
  },
  "devDependencies": {
    "autoprefixer": "^6.7.7",
    "babel-core": "^6.24.1",
    "babel-eslint": "^7.2.3",
    "babel-loader": "^7.0.0",
    "babel-plugin-import": "^1.1.1",
    "babel-plugin-react-transform": "^2.0.2",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "cross-env": "^4.0.0",
    "css-loader": "^0.28.0",
    "eslint": "^3.19.0",
    "eslint-config-airbnb": "^14.1.0",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jsx-a11y": "^4.0.0",
    "eslint-plugin-react": "^6.10.3",
    "extract-text-webpack-plugin": "^2.1.0",
    "html-loader": "^0.4.5",
    "html-webpack-plugin": "^2.28.0",
    "less": "^2.7.2",
    "less-loader": "^4.0.3",
    "postcss": "^5.2.17",
    "postcss-loader": "^1.3.3",
    "postcss-pxtorem": "^4.0.0",
    "react-transform-catch-errors": "^1.0.2",
    "react-transform-hmr": "^1.0.4",
    "redbox-react": "^1.3.6",
    "style-loader": "^0.16.1",
    "svg-sprite-loader": "^0.3.1",
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.5"
  }
}

.babelrc

{
  "env": {
    "development": {
      "presets": ["react", "es2015", "stage-0"],
      "plugins": [
        [
          "react-transform",
          {
            "transforms": [
              {
                "transform": "react-transform-hmr",
                "imports": ["react"],
                "locals": ["module"]
              }, {
                "transform": "react-transform-catch-errors",
                "imports": ["react", "redbox-react"]
              }
            ]
          }
        ],
        ["import", { "style": "css", "libraryName": "antd-mobile" }],
        ["transform-decorators-legacy"]
      ]
    }
  }
}
like image 237
Kim Avatar asked Apr 27 '17 15:04

Kim


People also ask

How do I use CSS modules with Webpacks?

In the following code block, css-loader and style-loader are used together. Similar to babel-loader , we can load CSS files to style our pages like so: module: { rules: [ { test: /\\. js$/, loader: "babel-loader", exclude: "/node_modules/", }, // CSS rules { test: /\\.

How does style-loader work?

style-loader takes CSS you've imported in your JavaScript files, and injects them as <style></style> tags into the DOM. It's particularly useful for inlining Critical CSS into the <head> of your page.

Which loaders can be used to process style sheets?

css-loader is the npm module that would help webpack to collect CSS from all the css files referenced in your application and put it into a string. And then style-loader would take the output string generated by the above css-loader and put it inside the <style> tags in the index. html file.

What is VUE style-loader?

This is a fork based on style-loader. Similar to style-loader , you can chain it after css-loader to dynamically inject CSS into the document as style tags.


1 Answers

The style-loader works correctly, but it doesn't do what you think it does. All it does is inject your CSS into a <style> tag at runtime.

The actual issue is that you expect the imports to behave like CSS modules, but you are not actually using CSS modules. With your current setup you can import the CSS and the classes will be available globally, so you use that class name on your element. For example:

import './Styles1.less';

<div className="class1">Hello World</div>

By enabling CSS modules (on the css-loader), you will receive an object with the class names mapped to the actual identifier of the class, when you import any CSS. You need to change the respective rules.

{
  test: /\.less$/,
  exclude: /node_modules/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        modules: true,
        importLoaders: 1,
      },
    },
    'less-loader'
  ],
},
{
  test: /\.css$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        modules: true,
      },
    },
  ],
},

With that you'll be able to use them as you wanted.

import styles1 from './Styles1.less';

<div className={styles1.class1}>Hello World</div>

The actual DOM element will look like this:

<div class="_3Rxg00d8E5vC1LOyJvBzl2">Hello World</div>
like image 57
Michael Jungo Avatar answered Oct 01 '22 03:10

Michael Jungo