DaveCodes
DaveCodes

Reputation: 41

Webpack sass to css specify a specific folder?

I've been looking over the docs and checking other people's questions but I can't find the simple answer to how to compile all my sass down to a simple css file and specify the directory I want the resulting css file to output to.

For quick context: I have a public directory with a stylesheets directory and a build directory in it. webpack compiles the app into build, and I'd like to have the sass compile style.css into the stylesheets directory.

Here's a screenshot of my public directory:

public dir img

I'd like to be able to do something like this in my webpack.config.js (only showing pertinent code for brevity):

const ExtractTextPlugin = require('extract-text-webpack-plugin');

...

// To be called in plugins:
const cssOutput = new ExtractTextPlugin('./public/stylesheets/style.css');

inside module loaders:

  {
    test: /\.scss$/,
    loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader'),
  },

In plugins:

  plugins: [
    .
    .
    .
    cssOutput,
  ],

I'd like to be able to access the output file with this line in my index.html file located in the public directory:

  <link rel="stylesheet" href="/stylesheets/style.css" />

I'm currently doing this using gulp and it works fine, I'm just trying to transition everything into webpack. Any help would be greatly appreciated!

Upvotes: 2

Views: 9855

Answers (4)

Luki B. Subekti
Luki B. Subekti

Reputation: 911

Recent solution, you can use mini-css-extract-plugin, css-loader, and sass-loader. mini-css-extract-plugin can create a CSS file per JS file which contains CSS.

Install dependencies:

npm i -D mini-css-extract-plugin css-loader sass-loader

For example, your main JS file that includes a style is ./src/index.js:

...
import './src/style.scss';
...

Configure webpack.config.js:

...
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  ...
  entry: {
    main: './src/index.js',
  },
  plugins: [
    new MiniCssExtractPlugin(),
  ],
  ...
  module: {
    rules: [
      ...
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader",
        ],
      },
      ...
    ]
  },
  resolve: {
    modules: ["node_modules", path.resolve(__dirname, "src")],
    extensions: ['.js', '.scss', ...]
  }
}

Then, you can check your output directory, there will be main.css. The plugin set default name to [name].css (entry name).

Upvotes: 0

Subhankar Jana
Subhankar Jana

Reputation: 151

Work for Me::

webpack.config.js

module.exports = {
   entry: ['./src/app.ts', './src/sass/style.scss'],
   module:{
          rules: [
          {
            test: /\.ts$/,
            use: 'ts-loader',
            include: [path.resolve(__dirname, 'src', 'src/class')]
          },
          {
            test: /\.scss$/,
            use: [
            {
              loader: 'file-loader',
              options: {
                name: '/css/[name].css'
              }
             },
             {
               loader: 'extract-loader'
             },
             {
               loader: 'css-loader?-url'
             },
             {
               loader: 'postcss-loader'
             },
             {
               loader: 'sass-loader'
             }
           ],
           include: [path.resolve(__dirname, 'src/sass')]
         }
     ]
 },
 output: {
     filename: 'js/app.js',
     path: path.resolve(__dirname, 'public')
  }
}

postcss.config.js

module.exports = {
 plugins: {
    'autoprefixer': {}
 }
}

package.json

{
  "name": "tsscript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  "nov": "webpack",
  "test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
  "autoprefixer": "^9.8.5",
  "css": "^3.0.0",
  "css-loader": "^3.6.0",
  "extract-loader": "^5.1.0",
  "postcss-loader": "^3.0.0",
  "sass": "^1.26.10",
  "sass-loader": "^9.0.2",
  "style-loader": "^1.2.1",
  "ts-loader": "^8.0.0",
  "typescript": "^3.9.6",
  "webpack": "^4.43.0",
  "webpack-cli": "^3.3.12"
 }
}

Directory Snap:

enter image description here

Upvotes: 2

DaveCodes
DaveCodes

Reputation: 41

Turns out you can just set the output file like this:

const cssOutput = new ExtractTextPlugin('../stylesheets/style.css', { allChunks: true });

I made the noob mistake of forgetting to add:

require('_scss/style.scss');

in my index.jsx file.

For anyone who runs into this issue, I still had trouble with fonts and images, so inside module loaders in the webpack.config.js I had to add:

  {
    test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif)(\?\S*)?$/,
    loader: 'file',
  },

and since this output everything into my build directory, I just changed the css to output everything in the build directory as well to prevent path errors. I changed it to this:

const cssOutput = new ExtractTextPlugin('style.css', { allChunks: true });

Hopefully this helps someone else who runs into this type of issue!

Upvotes: 2

highFlyingSmurfs
highFlyingSmurfs

Reputation: 3039

Have you take a look at https://www.npmjs.com/package/extract-text-webpack-plugin? you'll probably need it.

Upvotes: 0

Related Questions