Again, this error popped up (node-version: v7.4.0)
ERROR in ./style/index.scss
Module build failed: Error: "extract-text-webpack-plugin" loader is used without the corresponding plugin, refer to https://github.com/webpack/extract-text-webpack-plugin for the usage example
at Object.module.exports.pitch (/project/node_modules/extract-text-webpack-plugin/loader.js:27:9)
@ ./js/components/App.jsx 8:0-34
@ ./~/html-webpack-plugin/lib/loader.js!./js/index.jsx
{
"devDependencies": {
"extract-text-webpack-plugin": "^2.0.0-rc",
"html-webpack-plugin": "^2.28.0",
"webpack": "2.2.0",
}
}
my webpack config
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['./js/index.jsx'],
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: ['css-loader', 'sass-loader']
})
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './js/index.jsx',
inject: false
}),
new ExtractTextPlugin({filename: '[name].css', allChunks: true}),
]
};
my template
import React from 'react';
import { render } from 'react-dom';
import { renderToString } from 'react-dom/server';
import App from './components/App.jsx';
class Html extends React.Component {
render() {
return <html lang="en">
<head>
<meta charSet="utf-8"/>
<link rel="stylesheet" href="/main.css"/>
</head>
<body>
<App />
<script async defer src="/bundle.js"></script>
</body>
</html>
}
}
// Client render (optional):
if (typeof document !== 'undefined') {
render(<Html/>, document);
}
// Exported static site renderer:
export default (locals, callback) => {
const html = '<!DOCTYPE html>'+ renderToString(<Html {...locals} />);
//server side rendering
if ('function' === typeof callback) {
callback(null, html);
} else {
//html-webpack-plugin
return html;
}
};
if i exclude the ExtractTextPlugin the rendering works fine...
any ideas?
Wow I am really impressed that you found out how to use this plugin for server side rendering.
There is no documentation at all for this feature (although it was developed over a year ago).
There are/were several webpack bugs which didn't get enough priority by the webpack core team:
__dirname does not work (https://github.com/webpack/webpack/issues/2978)__file does not work (https://github.com/webpack/webpack/issues/2978)As I always thought of this feature as a nice to have I stopped working on it.
Maybe we could ask @bebraw if we should pick up this topic again - now that webpack 2 got released and the webpack core team grew a lot.
Well it has nothing todo with SSR. I even dont use it in case of SSR because another plugin handles the generation of the index.html . Only use it for providing the index.html in dev Mode.
So the problem is somewhere else...
@digitalkaoz Can you set up a standalone project to study?
@digitalkaoz Instead of loader: ExtractTextPlugin.extract I would go with use: ExtractTextPlugin.extract.
new HtmlWebpackPlugin({
filename: 'index.html',
template: './js/index.jsx',
inject: false
}),
is rendered at build time not in browser - so this is server side rendering ;)
@bebraw thanks for picking this up 馃憤
We could establish a new term for this: CTR (Compile-Time Rendering) :wink:
@sokra Haha unfortunately ctr is already used :)
This feature could boost the initial perceived load time of many react apps a lot without much work for the developer.
@markdalgleish built a plugin which also uses webpack to render at buit time https://github.com/markdalgleish/static-site-generator-webpack-plugin
See his talk at reactive conf on that topic https://www.youtube.com/watch?v=ovIrOMBbWrc
I added an example for this a while back: https://github.com/jantimon/html-webpack-plugin/tree/master/examples/javascript
To get the same error like @digitalkaoz just add a require statement to a css file in https://github.com/jantimon/html-webpack-plugin/blob/master/examples/javascript/universial.js
@pirelenito also created a unit test for the extract-text-webpack-plugin in pr #201 (1 year ago for webpack 1)
BTR: Build-Time Rendering?
Hi there! I have the same issue.
My webpack.config.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
loaders: [
{
test: /\.ejs$/,
loader: 'ejs-loader'
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: 'css-loader'
})
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: 'index.ejs'
}),
new ExtractTextPlugin({
filename: "css/[name].css?[hash]-[chunkhash]-[contenthash]-[name]",
disable: false,
allChunks: true
})
]
}
index.ejs:
<!DOCTYPE html>
<html>
<head>
<% require('./style.css') %>
</head>
<body>
<h1>It works</h1>
</body>
</html>
If I remove <% require('./style.css') %>, it works fine.
@mdnsk Yeah, after removing <% require('./style.css') %> it won't trigger extract-text-plugin logic. The question is, why does it fail to wire it up properly in this case.
@jantimon but there was no resolution #201
@bebraw using use instead of loader doesnt change anything
here is the example project which causes this bug:
https://github.com/digitalkaoz/digitalkaoz.github.io/tree/html_webpack
but as @jantimon stated, just require a css file in your JS to trigger the bug... im a bit confused as it looks like it works in the provided examples in this repo (but its using webpack1)?!
@bebraw
The question is, why does it fail to wire it up properly in this case.
I mean the same question. I need it to use in my partial ejs templates. For example, components/header/header.ejs:
<% require('./header.css') %>
<header class="<%- classes.join(' ') %>">
It is header.
<%= require('../nav-menu/nav-menu.ejs')({classes: ['header__menu']}) %>
</header>
@mdnsk Yup. That was more of a question which we should study. I have to get a little demo up and running to say anything more.
The problem is require to styles in a html-plugin template.
What you want it probably to specify other module.rules for css in the child compilation. i. e. use the null-loader while rendering the html-plugin template. But this is not possible currently.
One possible solution is the add a rule condition for compilation name.
{
test: /\.css$/,
oneOf: [
{ compilation: /html-webpack-plugin/, use: "null-loader" },
{ use: ETP. ... }
]
}
@bebraw you can use the examples in this repo:
To get the same error like @digitalkaoz just add a require statement to a css file in https://github.com/jantimon/html-webpack-plugin/blob/master/examples/javascript/universial.js
The root problem is that the extract text plugin uses kind of a hack to communicate between loader and plugin. (See here https://github.com/webpack-contrib/extract-text-webpack-plugin/blob/master/index.js#L216-L227 and here https://github.com/webpack-contrib/extract-text-webpack-plugin/blob/master/loader.js#L26)
This hack works only in the main compilation however the html-webpack-plugin is using a child compilation.
The null loader seems to be a work a round - imho we should add a feature request for the extract-text-plugin to support child compilations.
This might add a feature request for the webpack core (easier communication between loaders and plugins)
@digitalkaoz thanks - we understood that - #201 shows the problem but has no solution to the problem as it can't be solved in the html-webpack-plugin.
as @bebraw seems active in both projects he seems to be the right person to investigate :)
@digitalkaoz Tobias likely knows this area the best. By the sound of it, it's going to require a bigger change to pull this off properly. The way extract-text-plugin handles communication is the problem and that would have to change in order to fix this. Perhaps a plugin/loader should know something about its compilation context so it doesn't default to the root one?
@sokra the compilation seems not existing on Rule options... https://webpack.js.org/configuration/module/#rule or am i missing something?
can you provide a correct example to me?
@digitalkaoz That was a potential solution that needs to be implemented still. compilation field doesn't exist yet.
Maybe we can move this part of the discussion to the extract-text-webpack-plugin:
https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/389
ok, i have it working somehow:
everything depends on this patch: https://github.com/webpack-contrib/extract-text-webpack-plugin/pull/390
thanks @sokra for the hint on Rules!
webpack.config.js
{
module: {
rules: [
{
test: /\.scss$/,
oneOf: [
{test: /html-webpack-plugin/, use: "null-loader"},
{
use: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: ['css-loader', 'sass-loader']
})
}
]
},
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './js/index.jsx',
}),
new ExtractTextPlugin({filename: '[name].css'}),
]
}
index.jsx
import React from 'react';
import Document from './components/Document.jsx';
const styles = [];
const scripts = [];
// Client Rendering
if (typeof document !== 'undefined') {
const Dom = require('react-dom');
const App = require('./components/App.jsx').default; //lazy because of window dep
Dom.render(<App />, document.getElementById('app'));
}
export default (locals, callback) => {
const Server = require('react-dom/server');
// Serverside Rendering
if ('function' === typeof callback) {
const App = require('./components/App.jsx').default; //render the full app
callback(null, '<!DOCTYPE html>'+ Server.renderToString(<Document app={<App />} scripts={ scripts } styles={ styles }/>));
} else {
// Build-Time Rendering
return '<!DOCTYPE html>'+ Server.renderToStaticMarkup(<Document />);
}
};
Document.jsx
import React from 'react';
export default class extends React.Component {
static defaultProps = {
scripts: [],
styles: [],
app: null
};
render() {
return <html lang="en">
<head>
{ this.props.styles.map((s) =>{ return <link rel="stylesheet" key={s} href={s} type="text/css" /> })}
</head>
<body>
<div id="app">{ this.props.app }</div>
{ this.props.scripts.map((s) =>{ return <script key={s} src={s}></script> })}
</body>
</html>
}
}
Thank you @digitalkaoz and @sokra ! I have it working now.
Also I've added my ejs templates to the entry property to gather css dependencies of all the templates:
entry: {
'bundle': './index.js',
'__page-index': './pages/index.ejs',
'__page-contacts': './pages/contacts.ejs'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
...
plugins: [
new HtmlWebpackPlugin({
title: 'Index Page',
filename: 'index.html',
template: './pages/index.ejs'
}),
new HtmlWebpackPlugin({
title: 'Contacts Page',
filename: 'contacts.html',
template: './pages/contacts.ejs'
}),
new ExtractTextPlugin('style.css')
]
@mdnsk ExtractTextPlugin works when adding templates as entry.However,it seems the link tags are not inserted automatically.Have you figured it out?
It still doesn't work in my project @mdnsk
The project repo:
https://github.com/lastingman/webpack-project.git
After struggeling for 3 days with this issue, I've found out, that I only get it when using the terminal plugin in my Atom editor. When running "npm run dev" from the windows cmd app, it works fine.
Hope this is of any help for others.
@kirschkern Can you provide more information? Do you understand why Atom breaks it?
Sorry, I have no idea why it doesn't work from inside the terminal plugin. I can only offer this "workaround" so far.
Terminal plugin is: https://github.com/platformio/platformio-atom-ide-terminal
the same issue.
This is my environment:
webpack 3.0.0
html-webpack-plugin 2.29.0
extract-text-webpack-plugin 2.1.2
When i added extract-text-webpack-plugin, It's fine
// webpack.config.js
var ExtractTextPlugin = require('extract-text-webpack-plugin');
{
module: {
rules: [
// css loader
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins:[
new ExtractTextPlugin('css/[name]-[contenthash:8].css')
]
}
I couldn't find the solution for using this plugin alongside extractTextPlugin. Adding the template to entries doesn't seem like a good solution for me.
@HosseinAgha your issue is not related to the above, please open a new issue or ask your question on stackoverflow, in the meantime, check this simple example: https://github.com/jantimon/html-webpack-plugin/blob/master/examples/javascript/webpack.config.js~~
@mastilver thank you for your response.
I think I have the same issue here. As I understand what everybody want to do here is generating html statically using html-webpack-plugin and using css inside templates then extract all required css modules as a separate file.
I want to do this because I want to have a light compile time rendered page that eventually loads my main bundle.
I want html-webpack-plugin to generate the final html using my template because I use chunkhash for caching my js files so I need a plugin to inject files to it.
So correct me if I'm wrong. I don't think I can achieve above with a plugin like static-site-generator-webpack-plugin.
btw. you can configure different loaders depending on compilation:
rules: [
{
test: /\.css$/,
compiler: { not: /^html-webpack-plugin/ },
use: ExtractTextPlugin.extract(...)
}
]
@sokra This throws an error for me seems like webpack 2.7.0 does not understand compiler: not: RegExp option. The outputs is:
```
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
test: /\.styl$/,
compiler: {
not: /^html-webpack-plugin/
},
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[emoji]_[path]_[name]_[local]_[hash:base64:3]'
}
},
{ loader: 'stylus-loader' }
]
share a correct way~
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [{
loader: 'css-loader',
options: {
importLoaders: 1,
}
},{
loader: 'postcss-loader',
options: {
plugins: (loader) => [precss, autoprefixer({
browsers: [
"> 1%",
"last 5 versions",
"ie 6"
]
})]
}
}
]
})
}
]
},
plugins:[
// ...
new ExtractTextPlugin('[name]/styles.[contenthash].css')
],
Finally what is the right answer?
_I've never seen more counter-intuitive and error-prone thing then webpack.config... cannot do single bit without running into mysterious issues and googling around for hours. There is no plugin once you just added the plugin... enough for today_
I am still waiting for this to be fixed :(
So....what is the right answer? @digitalkaoz
It's the same as https://github.com/webpack-contrib/mini-css-extract-plugin/issues/219
The html-webpack-plugin picks up the main compiler configuration but the mini-css-extract-plugin and the extract-text-plugin loaders get confused somehow.
It's probably because of the way the loader and plugin communicate using the this[ns] hack.
@jantimon do u have some ways to filter html-webpack-plugin not to handle with mini-css-extract-plugin loader ? I have tried some ways from above but it was still not work well .
https://blog.csdn.net/simplehouse/article/details/78408679
I solved this problem with this statement $env:NODE_ENV="development"

It should be a bug of Atom package: platformio-ide-terminal ,cause windows cmd app works.
Add the statement in this package setting -> Core -> Auto Run Command
anyone searching for a solution, this is the right one:
drop this plugin and do it with the extract-loader + file-loader:
https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/50#issuecomment-368282653
@digitalkaoz Thank you for the workaround. Using extract-loader + file-loader seems to prevent the error and a CSS files is generated, but it looks like this file isn't added automatically to my index.html inside <head>.
finally i am ok!when i add
fallback:'style-loader'
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
This issue had no activity for at least half a year. It's subject to automatic issue closing if there is no activity in the next 15 days.
Most helpful comment
_I've never seen more counter-intuitive and error-prone thing then webpack.config... cannot do single bit without running into mysterious issues and googling around for hours. There is no plugin once you just added the plugin... enough for today_