In my last project I used gulp to concat all .scss files from several folders into one .scss file. Next I was using sass to compile that singe .scss file into css.
gulp.task('styles', function () {
gulp.src('styles/**/*.scss')
.pipe(concat('style.scss'))
.pipe(gulp.dest('production/'))
.pipe(sass({outputStyle: 'expanded'}))
.pipe(gulp.dest('production/'))
.pipe(sass({outputStyle: 'compressed'}))
.pipe(rename('style-min.css'))
.pipe(gulp.dest('production/'));
});
Now I want to create exactly the same 'building process' with Webpack.
entry: {
"style": "./styles/**/*.scss",
"style.min": "./styles/**/*.scss"
},
output: {
path: __dirname,
filename: "[name].css"
},
plugins: [
new ExtractTextPlugin('[name].css')
],
module: {
loaders: [
//Sass file
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('css!sass') }
]
}
Unfortunately Webpack don't understand ** and *.scss. Is there any solution to gain the same behavior?
PS I need to concat those files. I don't want to use any kind of Sass #imports etc.
For example, you could use node-glob package like this:
var glob = require('glob');
var styles = glob.sync('./styles/**/*.scss');
module.exports = {
entry: {
'style': styles,
...
You need to use loaders for all file types except javascript, to load using webpack. In your case you need sass-loader, css-loader, style-loader. Perform the below steps to make your scss work using webpack:
Install below dependencies
npm install sass-loader css-loader style-loader
Add the webpack.config.js
Webpack config
module.exports = {
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["style", "css", "sass?config=otherSassLoaderConfig"]
}
]
},
otherSassLoaderConfig: {
}
};
Now just require your scss file as require('./style.scss') and it will be loaded
For a detailed refrence you can also take a look at: https://stackoverflow.com/a/26876311/3878940
Related
I'm building a vue app with vue-cli 3. I'd like to include sass files in my webpack build but the vue-cli abstracts away the webpack.config.js file. Instead we are to create a vue.config.js file and configure it with a set of instructions.
If I were configuring webpack.config.js, the following would work:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
How should I configure my vue.config.js to achieve the same? Here is my best attempt:
module.exports = {
chainWebpack: config => {
config.module
.rule('scss')
.test(/\.scss$/)
.use('vue-style-loader')
.loader('vue-style-loader')
.use('css-loader')
.loader('css-loader')
.use('sass-loader')
.loader('sass-loader')
.end();
}
};
This fails with the message
ERROR TypeError: config.module.rule(...).test(...).use(...).loader(...).use is not a function
If you are using vue cli 3 then just run the following in your project root directory:
vue add style-resources-loader
I want to dig into modern frontend development using Webpack 2 and Materialize. Because I might customize the style, I want to #import the Materialize SASS file into my own SASS file, so I can overwrite stuff. However, if I do that, Webpack 2 can't compile my SASS file anymore because it doesn't find the Materialize fonts.
This is my current webpack.config.js, copypasted from all over the internet:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass = new ExtractTextPlugin({
filename: "style.css",
disable: process.env.NODE_ENV === "development"
});
module.exports = {
entry: './src/js/index.js',
output: {
path: __dirname + '/public/dist',
filename: 'app.js'
},
module: {
rules: [
{
test: /\.scss$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}, {
loader: "resolve-url-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=80000&mimetype=application/font-woff'
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader'
}
]
},
plugins: [
extractSass
]
};
I installed materialize-css via npm. If I put the following in my src/js/index.js file, the compilation works fine:
require('materialize-css/sass/materialize.scss');
I get the desired outputs in my public/dist directory (app.js, style.css and the font files that Materialize provides). But as I said, I want to import Materialize to my own SASS file, which looks something like this (src/scss/main.scss):
#import "~materialize-css/sass/materialize";
// ... overwrite some stuff here ...
Because of to the ~ in front of the filepath, the loader looks for the file in the node_modules directory, thus the materialize.scss file can be imported successfully.
I then have two possibilities to include my SASS file in my Webpack bundle: either change the require() call in my index.js to import that file instead of the materialize.scss file or change the entry key in my webpack.config.js to
entry: [
'./src/js/index.js',
'./src/scss/main.scss'
],
Either way, the compilation fails because Webpack cannot find the font files. This is one of the many errors that occur
ERROR in ./~/css-loader!./~/sass-loader/lib/loader.js!./~/resolve-url-loader!./src/scss/main.scss
Module not found: Error: Can't resolve '../fonts/roboto/Roboto-Thin.woff2' in 'C:\Users\Myname\Documents\Projects\webpack-test\src\scss'
# ./~/css-loader!./~/sass-loader/lib/loader.js!./~/resolve-url-loader!./src/scss/main.scss 6:75477-75521
# ./src/scss/main.scss
# multi ./src/js/index.js ./src/scss/main.scss
So this is where I am stuck. Why does the compilation work if I require() the Materialize SASS file directly? Why does it fail when I import the Materialize SASS file to my own SASS file? How do I have to change my Webpack config so that it can find the font files?
By accident I found out that materialize offers a variable to set the font path, so adjusting my own SASS file to this solved the problem
$roboto-font-path: "~materialize-css/fonts/roboto/" !default;
#import "~materialize-css/sass/materialize";
// ... my customizations ...
I found this code online to create a webpack for react.. what exactly is happening here? I need something like this to be able to use react right? I'm quite confused.
const path = require('path');
const SRC_DIR = path.resolve(__dirname, 'client');
const BUILD_DIR = path.resolve(__dirname, 'client');
module.exports = {
entry: path.resolve(SRC_DIR, 'client-app.js'),
output: {
filename: 'bundle.js',
path: BUILD_DIR
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'react'] }
}],
}
]
}
}
Why is it asking me to please add some context? I am trying to add more details so that this question can be posted
The code above does the following:
It resolves the client folder inside your projects folder and saves it to SRC_DIR and BUILD_DIR.
It tells webpack to look for a file named client-app.js in the resolved client folder from step 1.
It tells webpack to output the bundles Javascript into the client folder from step 1 with the file name bundle.js.
It tells webpack to look for any imported or required .js and .jsx files beginning at client-app.js inside your project folder (while excluding files from node_modules unless explicitly imported) and load them into the bundle using the babel-loader with the presets to compile the code from es2015 react to es5.
I'm starting VueJS, I started my code from the original Vue Loader Example and I tested running npm run dev or npm run build but a question emerge : Is there a way to place all the css from the components in one place (like styles.min.css).
I added bootstrap as dependencies in my package.json and but when I do a npm run build I can only find the build.js file in dist, that's all.
Thank you for your help.
There's a plugin for that
npm install extract-text-webpack-plugin --save-dev
and then configure it in your webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
// other options...
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
]
},
vue: {
loaders: {
css: ExtractTextPlugin.extract("css"),
// you can also include <style lang="less"> or other langauges
less: ExtractTextPlugin.extract("css!less")
}
},
plugins: [
new ExtractTextPlugin("style.css")
]
}
I'm trying out webpack for the first time and used this tutorial to get started and include react.js.
After finishing the steps and installing the style and css module I keep getting an error that the css module didn't return a function.
This is my index.jsx:
/** #jsx React.DOM */
'use strict';
require('../css/normalize.css');
var React = require('react');
var Hello = require('./Test/Hello');
React.render(<Hello />, document.getElementById('content'));
And my webpack config file:
module.exports = {
entry: './ui/src/index.jsx',
output: {
path: __dirname + '/build-ui',
filename: 'app.js', //this is the default name, so you can skip it
//at this directory our bundle file will be available
//make sure port 8090 is used when launching webpack-dev-server
publicPath: 'http://localhost:8090/assets'
},
module: {
loaders: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.scss$/,
loader: "style!css!sass"
}
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
When webpack tries to bundle the project it always states the following error:
ERROR in Loader /Users/Johannes/Documents/Development/holmes/node_modules/css/index.js didn't return a function
# ./ui/src/index.jsx 5:0-31
I don't know what to do about that. Has anyone encountered that issue? And how can I solve it?
EDIT: My directory looks as follows:
holmes/
ui/
css/
normalize.css
src/
Test/
Hello.jsx
index.jsx
index.html
package.json
webpack.config.js
This error is caused by a css module inside node_modules. Since you've specified the css-loader in your config, webpack tries to lookup that loader inside node_modules and finds another module called css which doesn't look like a loader (hence the error message).
To avoid confusion you should simply add the -loader postfix to each loader. Omitting the -loader postfix is just a convenience feature by webpack, but unfortunately it's the culprit of that error in your case.
loaders: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.scss$/,
loader: "style-loader!css-loader!sass-loader"
}
Update: Starting with webpack 2, you can't omit the -loader postfix anymore. We decided to do this to prevent errors like this.
I had a similar issue with react-flexbox-grid. In my case, the solution was installing css-loader and style-loader npm modules:
npm install css-loader style-loader --save-dev
I also came across a similar issue using node-noop.
Fortunately, using null as a replacement worked when I added enzyme and react-addons-test-utils to a project.