I am trying to get css requires to work in webpack using the ExtractTextPlugin but with no success
I want a separate css file rather than inlining any css.
Here is my webpack config:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./scripts/index'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js',
publicPath: '/scripts/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin('styles/styles.css', {
allChunks: true
})
],
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'scripts')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
}]
}
};
index.js:
import React from 'react';
import App from './App';
React.render(<App />, document.getElementById('root'));
App.js:
import React from 'react';
require('../styles/app.css');
export default class App extends React.Component {
render() {
return (
<h1>Hello, world.</h1>
);
}
}
index.html:
<html>
<head>
<link rel="stylesheet" href="/styles/styles.css">
</head>
<body>
<div id='root'></div>
</body>
<script src="/scripts/bundle.js"></script>
</html>
styles.css is returning 404
Any idea what could be going wrong here. If I don't use the ExtractTextPlugin and just do this in config:
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" }
]
}
then I get the css applied to the page correctly but obviously this is not coming from a css file
This is my first attempt at using webpack so probably doing some noob mistake
Any ideas?
ExtractTextPlugin
needs to be added in two spots: in the Loader, and as a Plugin. Here's the example pulled from the stylesheets documentation.
// webpack.config.js var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { // The standard entry point and output config entry: { posts: "./posts", post: "./post", about: "./about" }, output: { filename: "[name].js", chunkFilename: "[id].js" }, module: { loaders: [ // Extract css files { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }, // Optionally extract less files // or any other compile-to-css language { test: /\.less$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader") } // You could also use other loaders the same way. I. e. the autoprefixer-loader ] }, // Use the plugin to specify the resulting filename (and add needed behavior to the compiler) plugins: [ new ExtractTextPlugin("[name].css") ] }
I have modified your config filenames and how you include them in page
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./scripts/index'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'scripts/bundle.js',
publicPath: '/scripts/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin('styles/styles.css', {
publicPath: '/styles/',
allChunks: true
})
],
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'scripts')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
}]
}
};
Following is the html page
<html>
<head>
<link rel="stylesheet" href="build/styles/styles.css">
</head>
<body>
<div id='root'></div>
</body>
<script src="build/scripts/bundle.js"></script>
</html>
Using css-loader
and style-loader
together first parse your CSS, then turn it into style nodes, which can be imported in Webpack just like code. I don't understand why you'd want this artificial relationship built between your JavaScript and your CSS.
The above approach emits CSS again in the end. Why put your code through a round trip like that? Use raw-loader
and add your main CSS file to your entry points. You lose any error-checking that css-loader
performs, but your compilation happens much faster. But if you're using something like sass-loader
, you'll still get all the error checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With