webpack 2 + extract-text-webpack-plugin: parsing errors - sass

I'm trying to make a webpack config for my project with some scss. Some of it comes from the root project and some scss I want to load from dependencies e.g. from node_modules. I'm running into a strange error where if I don't include the node_modules in the module, it get's built including some scss that I have in the root project. But if I add include: path.resolve(__dirname, 'node_modules') or any other folder (eve one that doesn't exist) it fails but on file that is in root project and not in node_modules, the same files that it was extracting before with no errors.
Here is the webpack config:
const extractCSS = new ExtractTextPlugin({ filename: 'style.css', disable: false, allChunks: true });
module: {
rules: [
{
test: /\.scss$/,
include: path.resolve(__dirname, 'node_modules'),
use:extractCSS.extract({
fallbackLoader: 'style-loader',
loader: ['css-loader', 'sass-loader'],
})
},
]
}
So if I comment out the line with include it works but doesn't include node_modules and if I leave the line uncommented I get the error:
Unexpected character '#' (1:0) You may need an appropriate loader to handle this file type. in all of the scss files that are in the root project.
What am I doing wrong?

Related

How to get webpack to inline css into the generated html file

I'm trying to get webpack to inline some scss into the generated html file to use as my app-shell css.
The idea is to get webpack bundle any scss file ending in '-file.scss' into a css file and to inline any scss in files ending '-shell.scss'.
This way I would get my app-shell to style before react or anything else loads.
By inline I mean to put it in STYLE tags in the generated html file.
The css part of my webpack is:
{
test: /\.css$/,
include: [paths.appSrc, paths.appNodeModules],
// Disable autoprefixer in css-loader itself:
// https://github.com/webpack/css-loader/issues/281
// We already have it thanks to postcss.
loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss')
},
{
test: /-shell\.scss$/,
include: paths.appSrc,
loaders: ['style', 'css', 'sass'],
},
{
test: /-file\.scss$/,
include: paths.appSrc,
loader: ExtractTextPlugin.extract('style', 'css!sass'),
},
I had thought that removing the ExtractTextPugin loader from "test: /-shell.scss$/" would do it but it doesn't put those styles into STYLE tags in the generated html build file.
I've adapted the Create React App setup from https://github.com/facebookincubator/create-react-app

Webpack 2 - compile scss to css and miniffy, together with sourcemaps

I'm completely new to webpack (been using gulp since... forever).
However, I've just decided to use webpack. Decided to go with webpack 2 (2.1.0-beta.20 currently).
Been looking all over, still couldn't do a simple task as "give webpack my bootstrap.scss file (which imports all other bootstrap partial scss files needed) and have returned bootstrap.custom.min.css and bootstrap.custom.min.css.map".
I have my own bootstrap.scss file which only imports what I need from bootstrap (not using all of it), but after a custom custom-variables.scss file imported at the top, to overwrite some default bootstrap variables - like colors, grid columns etc. Anyway, I'm sure this is not relevant... The issue is compiling scss to css with custom output file name and sourcemap.
Not that it would make any difference, but to start with, here's my custom bootstrap.scss:
#import "custom-variables"; // to overwrite default bootstrap variables
/**
* Twitter Bootstrap
* This is actually copy/paste from the original bootstrap file, just changed paths
*/
// Core variables and mixins
#import "../../../../node_modules/bootstrap/scss/variables";
#import "../../../../node_modules/bootstrap/scss/mixins";
// and so on... only what I need. I don't need tables, forms and a few other.
In addition to this, I also have my own style.scss for which I need to do the same (to have returned style.min.css and style.min.css.map).
As for my webpack.config.js file, this is all I have:
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const sassLoaders = [
'css-loader',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname, './dev')
];
const config = {
entry: {
'bootstrap.custom.min': ['./wp-bootstrap'], // this file only contains 1 line: require('./dev/css/overwrite/bootstrap/bootstrap.scss');
'style.min': ['./wp-style'], // this file also contains 1 line: require('./dev/css/style.scss');
},
module: {
loaders: [
{
test: /\.scss$/,
loader: 'file',
// or, other examples I've found said to use:
// loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loaders: 'css!sass' }),
// but if I try like that, I get: "Cannot read property 'query' of undefined"
query: {
name: '[name].css'
}
}
]
},
plugins: [
new ExtractTextPlugin('[name].css')
],
postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
resolve: {
modules: [
path.resolve('./'),
'node_modules'
]
}
};
module.exports = config;
These are all the related packages I have installed:
"devDependencies": {
"autoprefixer": "^6.4.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^2.0.0-beta.3",
"node-sass": "^3.8.0",
"postcss-loader": "^0.9.1",
"sass-loader": "^4.0.0",
"style-loader": "^0.13.1",
"webpack": "^2.1.0-beta.20"
}
If I use a version of extract-text-webpack-plugin which is <2.x, then I get other errors, it's not compatible with webpack 2.
So, baby steps in the code above... Simply tried to at least obtain my bootstrap.scss and style.scss transformed into 2 separate css files: bootstrap.custom.min.css and style.min.css (don't know what to do about sourcemaps yet).
This is all I could come up with after searching google and trying to follow some examples. No solid tutorial out there that could make me understand how to use webpack for what I need to accomplish. I'm only guessing here, blind-folded.
But when I type webpack in the console and hit Enter, I don't get any css file, instead I get the following 3 files:
bootstrap.css - with the exact same content as the source
bootstrap.scss, like it just copies the file content over, instead of compiling scss to css;
bootstrap.custom.min.js which has a bunch of javascript code in
it;
style.min.js - which also has a bunch of javascript code in it.
I've been stuck here for days, didn't even get to all the rest I need (sourcemaps and a destination folder of my choosing for the css files and css.map files).

Webpack 2.1.0-beta.6 config file not picking up loaders for styling on windows

I'm trying to get webpack 2.1.0-beta.6's style, css, less, and file loaders to catch on Windows Server 2008, Babel 6, and Node 4.3. If webpack has this loader configuration:
loaders: [
{
test: /\.less$/,
loaders: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /.gif$/,
loader: 'file'
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015-native-modules']
}
}
The import require('../styling/my-style.less') fails with
ERROR in ../styling/my-less.less Module parse failed:
.../my-style.less
Unexpected character '#' (1:0) You may need an appropriate loader to
handle this file type. | #import "other.css";
./my-js.js 8:0-38
require('style!css!less!../styling/my-style.less') sort of works though. At least until it gets to a .gif file.
ERROR in ../styling/themes/base/images/animated-overlay.gif Module
parse failed:
..\styling\themes\base\images\animated-overlay.gif
Unexpected character ' ' (1:7) You may need an appropriate loader to
handle this file type. (Source code omitted for this binary file) #
./~/css-loader!./~/less-loader!../styling/my-style.less
10:46994-47046
My webpack config is in with my src directory and styles is a parallel directory
src
webpack.config.js
my-js.js // file doing the import from styling
styling
my-style.less
None of my loaders were getting picked up because under module.exports, I didn't have a module wrapping my loaders.
module.exports.loaders //doesn't work and require acts like there aren't loaders associated with the file type
module.exports.module.loaders //works

Webpack SASS-loader include statement breaks SASS #import statemetns

So for background originally I was excluding the node_modules directory in my Webpack config, which was working fine for my sass #import statements, but made it very difficult to include things from the node_modules directory. So I switched the SASS loader to the following
{
test: /\.scss$/,
include: [path.resolve(__dirname, "/src/client"), path.resolve(__dirname, "/node_modules/angular-material/")],
loader: 'style-loader!css-loader!autoprefixer-loader!sass-loader'
},
Please also note I tried with and without the trailing slash on client.
All my src files including the sass files are in ./src/client directory including sub-directories. The problem now is when I run Webpack all my import statements are no longer functional. and I end up with the following error whenever I try to import one of my own sass files:
ERROR in ./src/client/app/app.scss
Module parse failed: /Users/mikedklein/development/vncuxf/src/client/app/app.scss Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| #import 'common/common';
| #import 'general';
|
# ./src/client/app/app.module.es6 85:0-21
If I comment out the include statement all is well, but I know this is not a good approach. For reference I have also included my resolve statement from my config:
// Resolves so require statements don't need extentions
resolve: {
extensions: ['', '.js', '.es6', '.scss', '.css', '.html', '.json'],
alias: {
angular_material_scss: __dirname + "/node_modules/angular-material/angular-material.scss"
}
}
So I think I solved this
module: {
loaders: [
{
test: /\.(es6|js)$/,
exclude: /node_module/,
loader: 'babel-loader'
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader!autoprefixer-loader'
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!autoprefixer-loader!sass loader'
}
]
},
// This is the key need to have include paths in the sass loader option.
sassLoader: {
includePaths: [path.resolve(__dirname, './src/app'), path.resolve(__dirname, '/node_modules/angular-material')]
}
One thing I am still curious about is whether this is the most efficient approach, when sass files are stored in multiple directories.

using d3.js as an external in webpack

I'm using this tutorial to setup a React.js project with webpack. The webpack.config.js below is almost an exact copy (except that I'm using an app and 'dist' folder), and I am also adding d3.js as an external. Because React is added as an external it lets me do require('react') in any of my app files without including it in the bundle. I wish to do the same with d3.js and have installed it as a node_module, and listed it in the externals area of my webpack config, but when I do require('d3') i get an error message that it's not available.
How can I use d3 (or jQuery for that matter) as an external if I have it installed as a node_module?
this is my project setup
/app
/dist
/node_modules
package.json
webpack.config.js
module.exports = {
entry: './app/index.jsx',
output: {
path: './dist',
filename: 'bundle.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'
}
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React',
'd3': 'd3'
},
resolve: {
modulesDirectories: ['app', 'node_modules'],
extensions: ['', '.js', '.jsx']
}
}
I know this question has been open a while, but hopefully this answer is still useful!
If you have installed d3 (or jQuery) as a node_module, you can use the webpack ProvidePlugin to tie an arbitrary key to a module.
The key will be then be available to require anywhere in your webpack app.
E.g. webpack.config.js
{
...lots of webpack config here...
...
plugins: [
new webpack.ProvidePlugin({
d3: 'd3',
$: 'jquery'
})
]
...
}
Then in my-file.js
var d3 = require('d3')
Hope that helps!

Resources