webpack-contrib / sass-loader

Compiles Sass to CSS
MIT License
3.9k stars 428 forks source link

Webpack 2 + CSS modules + sass-loader example? #329

Closed DanielRamosAcosta closed 7 years ago

DanielRamosAcosta commented 7 years ago

I'm trying to port my previus project to Webpack 2, but I'm having some issues with the sass-loader. Is there any full example with Webpack 2, and if possible with CSS modules?

Thanks!

sai-prasanna commented 7 years ago

I too have problems porting , Here is my webpack 2 conf

const webpack = require('webpack');
const path = require('path');

const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');

const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';

const jsSourcePath = path.join(__dirname, './source/js');
const buildPath = path.join(__dirname, './build');
const imgPath = path.join(__dirname, './source/assets/img');
const sourcePath = path.join(__dirname, './source');

// Common plugins
const plugins = [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: Infinity,
    filename: 'vendor-[hash].js',
  }),
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: JSON.stringify(nodeEnv),
    },
  }),
  new webpack.NamedModulesPlugin(),
  new HtmlWebpackPlugin({
    template: path.join(sourcePath, 'index.html'),
    path: buildPath,
    filename: 'index.html',
  }),
  new webpack.LoaderOptionsPlugin({
    options: {
      postcss: [
        autoprefixer({
          browsers: [
            'last 3 version',
            'ie >= 10',
          ],
        }),
      ],
      context: sourcePath,
    },
  }),
];

// Common rules
const rules = [
  {
    test: /\.(js|jsx)$/,
    exclude: /node_modules/,
    use: [
      'babel-loader',
    ],
  },
  {
    test: /\.(png|gif|jpg|svg)$/,
    include: imgPath,
    use: 'url-loader?limit=20480&name=assets/[name]-[hash].[ext]',
  },
];

if (isProduction) {
  // Production plugins
  plugins.push(
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false,
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        if_return: true,
        join_vars: true,
      },
      output: {
        comments: false,
      },
    }),
    new ExtractTextPlugin('style-[hash].css')
  );

  // Production rules
  rules.push(
    {
      test: /\.scss$/,
      loader: ExtractTextPlugin.extract({
        fallbackLoader: 'style-loader',
        loader: 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass-loader',
      }),
    }
  );
} else {
  // Development plugins
  plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new DashboardPlugin()
  );

  // Development rules
  rules.push(
    {
      test: /\.scss$/,
      use: [
        'style-loader',
        // Using source maps breaks urls in the CSS loader
        // https://github.com/webpack/css-loader/issues/232
        // This comment solves it, but breaks testing from a local network
        // https://github.com/webpack/css-loader/issues/232#issuecomment-240449998
        // 'css-loader?sourceMap',
        'css-loader?importLoaders=1&modules&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
        'postcss-loader',
        'sass-loader',
      ],
    }
  );
}

module.exports = {
  devtool: isProduction ? 'eval' : 'source-map',
  context: jsSourcePath,
  entry: {
    js: './index.js',
    vendor: [
      'babel-polyfill',
      'es6-promise',
      'immutable',
      'isomorphic-fetch',
      'react-dom',
      'react-redux',
      'react-router',
      'react',
      'redux-thunk',
      'redux',
    ],
  },
  output: {
    path: buildPath,
    publicPath: '/',
    filename: 'app-[hash].js',
  },
  module: {
    rules,
  },
  resolve: {
    extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
    modules: [
      path.resolve(__dirname, 'node_modules'),
      jsSourcePath,
    ],
  },
  plugins,
  devServer: {
    contentBase: isProduction ? './build' : './source',
    historyApiFallback: true,
    port: 3000,
    compress: isProduction,
    inline: !isProduction,
    hot: !isProduction,
    host: '0.0.0.0',
    stats: {
      assets: true,
      children: false,
      chunks: false,
      hash: false,
      modules: false,
      publicPath: false,
      timings: true,
      version: false,
      warnings: true,
      colors: {
        green: '\u001b[32m',
      },
    },
  },
};
borela commented 7 years ago

@DanielRamosAcosta https://github.com/ctrine/webpack-settings/blob/master/packages/shared/src/rules/sass-module.js

RaphaelHadjadj commented 7 years ago

I made a simple minimalist sample project. https://github.com/RaphaelHadjadj/webpack2-cssmodules-sass

alexander-akait commented 7 years ago

@michael-ciniawsky what do you think about docs/recipes directory as in gulp https://github.com/gulpjs/gulp/tree/master/docs/recipes, maybe it is not bad idea?

joshwiens commented 7 years ago

Please submit support requests and questions to StackOverflow using the tag [webpack]. StackOverflow is better suited for this kind of support though you may also inquire in Webpack Gitter. The issue tracker is for bug reports and feature discussions. See also our CONTRIBUTING guidelines.

Maseeharazzack commented 6 years ago

My code works perfectly in dev environment when I try npm run build I get the following error:

ERROR in ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./node_modules/extract-text-webpack-plugin/dist/loader.js? {"omit":0,"remove":true}!./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/app/communication-center/comm-center .component.scss Module build failed: .all-common-grid { ^ Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex" in D:\dev\Greater_Giving\CommunicationCenter\src\app\communication-center\comm-center.component.scss (line 1, column 1) @ ./src/app/communication-center/comm-center.component.scss 2:21-317 @ ./src/app/communication-center/comm-center.component.ts @ ./src/app/communication-center/comm-center.module.ts @ ./src/app/app-routing.module.ts @ ./src/app/app.module.ts @ ./src/app/main.ts

ERROR in ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./node_modules/extract-text-webpack-plugin/dist/loader.js? {"omit":0,"remove":true}!./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/assets/style.scss Module build failed: / Imported Stylesheet / ^ Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex" in D:\dev\Greater_Giving\CommunicationCenter\src\assets\style.scss (line 1, column 1) @ ./src/assets/style.scss 2:21-286

Following is my code

webpack.config.common.js

var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CopyWebpackPlugin = require('copy-webpack-plugin'); var helpers = require('./helpers'); var webpack = require('webpack');

module.exports = { entry: { 'app': './src/app/main.ts', 'polyfills': './src/polyfills.ts', 'styles' : './src/assets/style.scss' }, resolve: { extensions: ['.ts', '.js'] }, module: { rules: [ { test: /.ts$/, use: [ { loader: 'awesome-typescript-loader', options: { transpileOnly: true } }, { loader: 'angular2-template-loader' }, { loader: 'angular-router-loader' } ] }, { test: /.html$/, loaders: ['html-loader'] }, { test: /.scss$/, exclude: [ /node_modules/, helpers.root('src', 'style.scss') ], use: [ 'to-string-loader', 'css-loader', 'sass-loader' ] }, { test: /.scss$/ , use: ExtractTextPlugin.extract({ use: 'css-loader!sass-loader' }) }, { test: /.(png|jpe?g|gif|svg|woff|woff2|otf|ttf|eot|ico)$/, use: 'file-loader?name=assets/[name].[hash].[ext]' } ], exprContextCritical: false }, plugins: [ new ExtractTextPlugin({ // define where to save the file filename: 'styles/[name].bundle.css', allChunks: true, }), new HtmlWebpackPlugin({ template: 'src/index.html' }), new CopyWebpackPlugin([ { from: 'node_modules/froala-editor/css/', to: 'assets/froala-editor/css/', }, { from: 'node_modules/font-awesome/css/font-awesome.min.css', to: 'assets/font-awesome/css/font-awesome.min.css', }, { from: 'node_modules/font-awesome/fonts', to: 'assets/font-awesome/fonts' } ]), new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ] };

webpack.config.prod.js var path = require('path'); var webpack = require('webpack'); var webpackMerge = require('webpack-merge'); var commonConfig = require('./webpack.config.common'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, { output: { path: path.resolve(__dirname, 'dist'), publicPath: '/', filename: '[name].[hash].js', chunkFilename: '[id].[hash].chunk.js' }, plugins: [ new webpack.NoEmitOnErrorsPlugin(), new webpack.optimize.UglifyJsPlugin({ mangle: { keep_fnames: true } }), new ExtractTextPlugin('styles.[hash].css'), new webpack.DefinePlugin({ 'process.env': { 'ENV': JSON.stringify(ENV) } }), new webpack.LoaderOptionsPlugin({ options: { htmlLoader: { minimize: false // workaround for ng2 } } }), new UglifyJSPlugin() ] });

alexander-akait commented 6 years ago

@Maseeharazzack don't create multiple issues in closed issue, please create new issue and create minimum reproducible test repo, thanks!