Webpack 3.5.5 error loading CSS and SASS - javascript

I am currently updating my nodejs packages and updated webpack to 3.5.5 and the build is now failing on trying to load css and sass. This is how my loaders look.
loaders: [
{test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel-loader']},
{test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/, loader: "file-loader" },
{test: /\.(jpe?g|png|gif)$/i, loader: 'file?name=[name].[ext]-loader'},
{test: /\.ico$/, loader: 'file?name=[name].[ext]-loader'},
{test: /(\.css|\.scss)$/, loaders: ['style-loader', 'css?sourceMap-loader', 'postcss-loader', 'sass?sourceMap-loader']},
]
I am wondering if I need to change anything so that these loaders will work?
The error I am getting is
BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders. You need to specify 'css-loader' instead of 'css', see webpack.js.org/guides/migrating/… `

Now that webpack loaders must include the -loader prefix, the correct modification from css?sourceMap is not to css?sourceMap-loader but instead to css-loader?sourceMap.
Similarly, sass?sourceMap must become sass-loader?sourceMap.
In both cases, sourceMap acts in a similar way to a query string parameter in a URL, and the adjustment from css to css-loader is akin to a resource moving from example.com/css to example.com/css-loader.

Related

How to include all CSS files in node_modules to be built by css-loader?

I am trying to extract all the CSS files found in the node_modules directory into a single file. My Webpack config is as follows:
{ // node_modules css in /node_modules/**/*.css
test: /\.css$/,
include: /node_modules/,
// extract to the node modules css file
use: ExtractTextPluginNodeMods.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: false,
},
},
],
}),
}
Unfortunately, none of the CSS files in the node_modules directory are being bundled into the file specified with ExtractTextPluginNodeMods. I have another ExtractTextPlugin instance that is successfully extracting CSS from my src directory. Any idea why I cannot get extraction of CSS from node_modules?
For reference, my other ExtractTextPlugin/Webpack config (which is bundling all of my CSS is here:
{
// OUR css in /src/
// the css output from sass loader will be caught here
// fonts are imported by css loader
// after transpiling of sass -> css, css-loader in webpack should take care of this
// https://github.com/webpack-contrib/css-loader
test: /\.css$/,
exclude: /node_modules/,
// extract to our css file
use: ExtractTextPluginSrc.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
// create modular css with the '[name]__[local]___[hash:base64:5]'
options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
'postcss-loader',
],
}),
}
Webpack won't include the CSS files unless you explicitly import them from your javascript code. So you'll need:
import 'some_package/css/component.css';
in the part of your app that uses the CSS.
Alternatively you could use something like glob-loader to do
import 'glob-loader?node_modules_pattern_file';
and then have your "node_modules_pattern_file" include a glob like
../node_modules/**/*.css
...but I don't recommend this approach because you'll end up pulling in loads of files you don't need and it will be hard to maintain.

How to NOT resolve paths with Webpack?

I'm working on a ReactJs project with Webpack and sass-loader, css-loader & url-loader.
I would like to not resolve the font-face paths and keep it exactly how it was set in the SASS file.
The issue:
If I call an absolute path (ie: http://fonts.com/my-font.eot or /path/to/my-font.eot), the path is not resolved.
However, if I use a relative path (ie: my-font.eot or path/to/my-font.eot), url-loader tries to resolve the path.
In my case, I need to use a relative path (even if it generates a 404 error).
What I tried:
I tried to exclude all font extensions in the url-loader, but Webpack doesn't know what to do with this type of file even if the file potentially doesn't exist.
Here the error I get:
Module parse failed: C:....\fonts\my-font.eot Unexpected character '
' (1:1) You may need an appropriate loader to handle this file type.
I also tried to disable the "url" option of css-loader, but absolutely nothing happens. I guess it is highly possible that I didn't add the option correctly:
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
options: { url: false }
},
Here is what my current code looks like :
module: {
loaders: [
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.scss$/,
/\.json$/,
/\.svg$/
],
loader: 'url',
query: {
limit: 10000,
name: 'path/dist/[name].[hash:8].[ext]'
}
},
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
},
...
]
},
...
}
This question might be a little old, but I still want to correct the answer.
When you want to use the array syntax, you basically define all the options for every single loader. In order to do so you have to use an object for the loader in the array. So instead of
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
options: { url: false }
},
You have to write
{
test: /\.scss$/,
loaders: [
"style-loader",
{
loader:'css-loader',
options: {
url: false
}
},
"sass-loader"],
},
I found the solution. I wasn't adding the css-loader option properly.
Because I didn't find a way to add options directly using the array syntax, I had to switch to the string syntax.
This code doesn't work:
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
options: { url: false }
},
This code works:
{
test: /\.scss$/,
loader: 'style!css?url=false!sass'
}

How to configure font file output directory from font-awesome-webpack in webpack?

I just installed font-awesome-webpack. I import it using: require("font-awesome-webpack");
My webpack config includes the following in my module loaders array:
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
Problem is I am getting this error in developer console:
localhost/:1 GET http://localhost/mysite/app/db812d8a70a4e88e888744c1c9a27e89.woff2
localhost/:1 GET http://localhost/mysite/app/a35720c2fed2c7f043bc7e4ffb45e073.woff
localhost/:1 GET http://localhost/mysite/app/a3de2170e4e9df77161ea5d3f31b2668.ttf 404 (Not Found)
The problem is, those files are created at the root (within the mysite directory). How do I configure such that those woffs and ttf are output within the mysite/app directory?
I've recently wanted to use font awesome with webpack v1, I've installed the npm module font-awesome not font-awesome-webpack
You must install few loaders before :
npm i css-loader file-loader style-loader url-loader
and add use them in your webpack.config.js :
module: {
loaders: [{
test: /\.css$/,
loader: 'style!css?sourceMap'
}, {
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff"
}, {
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff"
}, {
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/octet-stream"
}, {
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: "file"
}, {
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=image/svg+xml"
}]
}
Now if you include in your entry.js :
require('font-awesome/css/font-awesome.css');
You normally be able to use font-awesome in your template :
<i class="fa fa-times"></i>
This gist helped me : https://gist.github.com/Turbo87/e8e941e68308d3b40ef6
As of Feb. 2016 this seems to be a common question with webpack, so I hope this provides some help. If you add this to the loader: '&name=./path/[hash].[ext]', that specifies where to look for those files. For example:
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff&name=./[hash].[ext]'
}
This places the correct URL to the fonts within the generated CSS file.
I recommend this method when dealing with anything other than css/scss. Hope this helps.
In addition to the above answers, I
I had to specify a path in output to get it working like so to specify the hosted location and not write the assets to the root path:
output: {
filename: "./bundle.js",
path: “./client”
},
module: {
loaders[
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff&name=./webpack-assets/[name]/[hash].[ext]"
}, {
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff&name=./webpack-assets/[name]/[hash].[ext]"
}, {
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/octet-stream&name=./webpack-assets/[name]/[hash].[ext]"
}, {
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: "file?&name=./webpack-assets/[name]/[hash].[ext]"
}, {
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=image/svg+xml&name=./webpack-assets/[name]/[hash].[ext]"
}
] // loaders
} // module
{
test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=100000'
}
This schema helped me
This is my case, because of my script path is like below:
script(src='/javascripts/app.js')
So, I have to add '&name./javascripts/[hash].[ext]' to all font files like:
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff&name=./javascripts/[hash].[ext]"
}, {
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff&name=./javascripts/[hash].[ext]"
}, {
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=application/octet-stream&name=./javascripts/[hash].[ext]"
}, {
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: "file?name=./javascripts/[hash].[ext]"
}, {
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: "url?limit=10000&mimetype=image/svg+xml&name=./javascripts/[hash].[ext]"
}
Just as a note, I came across a similar fault using the font-awesome-loader.
Where the directory would not be set correct, regardless of any of the changes above.
To correct this, the option publicPath can be added to output:
output: { path: config.outputPath, filename: '[name].js', publicPath: '/assets/' },
The folder /assets/ will be changed to wherever you actually store your fonts.
Hopefully this helps.
I had font-awesome-webpack working on my PC, but it wouldn't work on my Mac. I think my PC was still throwing the 404s for the .woff2, .woff, and .tiff, but the icons displayed properly, so I ignored the problem.
My Mac, however, would not display the icons. While reading this Q&A, I tried a bunch of things. Here's what lead to my solution:
On my http://localhost:8080/View/ page, I was getting 404s that looked like the link below:
I entered http://localhost:8080/View/e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2 into the browser, and confirmed the 404.
I tried going to http://localhost:8080/e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2 (removing the extra path before the font file), and was able to access the file.
I modified Paul's answer to remove the . that made the file request relative.
For example, Paul suggested:
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&minetype=application/font-woff&name=./[hash].[ext]'
}
Take note of the &name parameter, that uses ./[hash].[ext]. I dropped the leading . and now there are no 404s (the browser correctly requests the files from the root of the site):
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&minetype=application/font-woff&name=/[hash].[ext]'
}
Conclusion: If your entry point is NOT at your web root, and you're able to access the font files at the web root, you probably just need to use this name configuration to fix the path.
Same issue faced.
Fixed it using the below syntax,
loader: "file?name=./fonts/[hash].[ext]"
fonts is the directory name, replace it with your own directory name.
Example:
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url?name=/build/[hash].[ext]&limit=8192&mimetype=application/font-woff"
}

Using Webpack and Babel to convert ES6 to AMD

I'm using webpack in my app, and have babel converting my js/jsx files from es6 to es5.
I'd like to have babel convert the module loading in these files to AMD. I see how to do this with grunt-babel:
Using Babel to convert ES6 modules to ES5 AMD modules, not working as expected
How would I do this if I want webpack to handle the babel conversion?
For example, in webpack.config.js I have:
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel'
}
}
Can I set an option in there for Babel to use AMD?
You can set an options for babel with query key:
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
modules: 'amd'
}
}
}
For all available options take a look here: http://babeljs.io/docs/usage/options/
If you want to generate the whole bundle as AMD module, you can set it in the "output.libraryTarget" config:
{
output: {
libraryTarget: "amd"
}
}
See here, in "output.libraryTarget":
https://webpack.github.io/docs/configuration.html

Can css-loader return just a string?

In my webpack config if I wanted to use css-loader to then use file-loader how can I get css-loader to do it's magic and then still return what file-loader wants so it can save it as a .css
Example config
{
test: /\.scss$/,
loaders: [
'file-loader?name=[name].css',
'css-loader',
'autoprefixer-loader',
'sass-loader'
]
}
Can it be done?

Categories