Webpack 2/React: cannot get style to work - reactjs

I've been stuck here for hours now - can't include my style in development mode with webpack.config.js, and can't bundle my styles when I build my project with webpack.config.prod.js - or inject the style link into the generated index-template.html. Instead, no css file is generated - and the generated html file does not include style tag:
I've done this in other React/Webpack projects with no problems, where identical configuration results in both style tag and bundled css file:
I don't understand where I am going wrong .. this is my folder structure:
This is my webpack.config.js file:
const webpack = require('webpack');
const path = require('path');
const entry = [
'babel-polyfill',
'webpack-dev-server/client?http://127.0.0.1:8080', // Specify the local server port
'webpack/hot/only-dev-server', // Enable hot reloading
'./scripts/index.js' // Where webpack will be looking for entry index.js file
];
const output = {
path: path.join(__dirname, 'dist'), // This is used to specify folder for producion bundle
publicPath: '/dist',
filename: 'bundle.min.js' // Filename for production bundle
}
const plugins = [
new webpack.HotModuleReplacementPlugin(), // Hot reloading
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
})
]
const config = {
context: path.join(__dirname, 'src'),
entry: entry,
devtool: 'inline-source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
output: output,
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
{
test: /\.(sass|scss)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
]
},
plugins: plugins
}
module.exports = config;
and this is my webpack.config.prod.js file:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const entry = [
'./scripts' // Where webpack will be looking for entry index.js file
];
const output = {
path: path.join(__dirname, 'dist'), // This is used to specify folder for producion bundle
publicPath: '/dist',
filename: 'bundle.min.js' // Filename for production bundle
}
const plugins = [
new webpack.HotModuleReplacementPlugin(), // Hot reloading
new webpack.NoEmitOnErrorsPlugin(), // Webpack will let you know if there are any errors
// Declare global variables
new webpack.ProvidePlugin({
React: 'react',
ReactDOM: 'react-dom',
_: 'lodash'
}),
new ExtractTextPlugin({
disable: false,
filename: 'bundle.css',
allChunks: true
}), // extract you css into seperate file files to serve your webpack bundles
new HtmlWebpackPlugin({
filename: 'index.html',
template: './index.html',
hash: false,
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'bundle',
filename: 'bundle.common.js'
})
]
const config = {
context: path.join(__dirname, 'src'),
entry: entry,
devtool: 'source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
output: output,
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
{
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: (loader) => [ require('autoprefixer')() ]
}
},
'sass-loader',
]
})
}
]
},
plugins: plugins
}
module.exports = config;
I am so effing thankful for any input <3

As #margaretkru said, I had forgotten to import my app.scss in my index.js file!

Related

webpack4 hot reloading not working for some files

I have a problem with react webpack4 when i try to hot reload the changes fom certain files. And those files where the ones i modified from its original path (/from /src/containers to /src/components)
Rest of files reloading working well...
Code of my webpack config file is below:
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const Dotenv = require('dotenv-webpack');
const htmlWebpackPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
});
module.exports = {
output: {
path: path.join(__dirname, './'),
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: "[name]_[local]_[hash:base64]",
sourceMap: true,
minimize: true
}
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new Dotenv()
],
devServer: {
historyApiFallback: true,
}
};
If you can share the error log, I may tell what is the real problem. But current config is missing for an entry point. If your application is a single page app, do it like the following code;
module.exports = {
entry: path.join(__dirname, "src", "index.js"),
...
}
if you are building multi page application do it like the following code;
module.exports = {
entry: {
pageOne: path.join(__dirname, "src", "pageOne", "index.js"),
pageTwo: path.join(__dirname, "src", "pageTwo", "index.js"),
pageThree: path.join(__dirname, "src", "pageThree", "index.js")
}
...
}
For anyone arriving here and having this issue, I had this exact problem where files in my 'src/components' directory weren't hot reloading.
I was able to fix it when I saw in the log that webpack was looking for the directory 'src/Components' for some reason, so I changed the name of the components directory to something totally different like 'placeholder' then changed it back to 'components' and ran a fresh install.

material-ui.dropzone: You may need an appropriate loader to handle this file type

Integrating material-ui-dropzone in my React app, I got this error:
./~/material-ui-dropzone/src/index.jsx Module parse failed:
...\client\node_modules\material-ui-dropzone\src\index.jsx Unexpected
token (123:26) You may need an appropriate loader to handle this file
type. SyntaxError: Unexpected token (123:26)
Here is my webpack configuration:
const Path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const Webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = (options) => { const ExtractSASS = new ExtractTextPlugin(`/styles/${options.cssFileName}`);
const webpackConfig = {
devtool: options.devtool,
entry: [
`webpack-dev-server/client?http://localhost:${+ options.port}`,
'webpack/hot/dev-server',
Path.join(__dirname, '../src/app/index'),
],
output: {
path: Path.join(__dirname, '../dist'),
filename: `/scripts/${options.jsFileName}`,
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
module: {
loaders: [{
test: /.jsx?$/,
include: Path.join(__dirname, '../src/app'),
loader: 'babel',
}],
},
plugins: [
new Webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(options.isProduction ? 'production' : 'development'),
},
"global.GENTLY": false
}),
new HtmlWebpackPlugin({
template: Path.join(__dirname, '../src/index.html'),
}),
],
node: {
__dirname: true,
},
};
if (options.isProduction) {
webpackConfig.entry = [Path.join(__dirname, '../src/app/index')];
webpackConfig.plugins.push(
new Webpack.optimize.OccurenceOrderPlugin(),
new Webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
},
}),
ExtractSASS
);
webpackConfig.module.loaders.push({
test: /\.scss$/,
loader: ExtractSASS.extract(['css', 'sass']),
}); } else {
webpackConfig.plugins.push(
new Webpack.HotModuleReplacementPlugin()
);
webpackConfig.module.loaders.push({
test: /\.scss$/,
loaders: ['style', 'css', 'sass'],
});
webpackConfig.devServer = {
contentBase: Path.join(__dirname, '../'),
hot: true,
port: options.port,
inline: true,
progress: true,
historyApiFallback: true,
stats: 'errors-only',
}; }
return webpackConfig;
};
Babel config file is:
{
"presets": ["react", "es2015", "stage-1"]
}
It is the only library I had problems with. Any idea where might be the problem?
if you are using webapck#3.x
Try to modify your babel loader to
module: {
rules: [
{
test: /\.jsx?$/,
include: Path.join(__dirname, '../src/app'),
use: {
loader: 'babel-loader',
options: {
presets: ["react", "es2015", "stage-1"],
}
}
}
]
}
You can reference here https://webpack.js.org/loaders/babel-loader/
Noted that in your loader config, write babel-loader instead of just babel. Also make sure if you have npm install the right babel npm packages to the devDependencies, which depends on your webpack version.
If it does not solve your problem, paste your package.json file so i can get to know your webpack version.
Cheers.

React, WebPack and Babel for Internet Explorer 10 and below produces SCRIPT1002: Syntax error

I've read multiple threads regarding similar issues and tried some propositions, but had no results.
I've followed few tutorials related to React.js and WebPack 3. As the result the application is working well on all browsers (at this moment) except IE 10 and below. The error points to bundle.js (once I'm using the configuration Nr.1):
SCRIPT1002: Syntax error and the line - const url = __webpack_require__(83);
With configuration Nr2., on local server - : SCRIPT1002: Syntax error - line with eval()
And the same configuration, but running on remote server produces a bit different error:
SCRIPT5009: 'Set' is undefine
WebPack configuration Nr1.:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.json$/,
exclude: /node_modules/,
loader: 'json-loader'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
}
],
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react']
}
}
}
]
},
devServer: {
historyApiFallback: true,
contentBase: './'
},
plugins: [HtmlWebpackPluginConfig]
}
WebPack configuration Nr2.:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const StyleExtHtmlWebpackPlugin = require('style-ext-html-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const autoprefixer = require('autoprefixer');
const staticSourcePath = path.join(__dirname, 'static');
const sourcePath = path.join(__dirname);
const buildPath = path.join(__dirname, 'dist');
module.exports = {
stats: {
warnings: false
},
devtool: 'cheap-eval-source-map',
devServer: {
historyApiFallback: true,
contentBase: './'
},
entry: {
app: path.resolve(sourcePath, 'index.js')
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[chunkhash].js',
publicPath: '/'
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
modules: [
sourcePath,
path.resolve(__dirname, 'node_modules')
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[chunkhash].js',
minChunks: Infinity
}),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer({
browsers: [
'last 3 version',
'ie >= 10'
]
})
],
context: staticSourcePath
}
}),
new webpack.HashedModuleIdsPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
path: buildPath,
excludeChunks: ['base'],
filename: 'index.html',
minify: {
collapseWhitespace: true,
collapseInlineTagWhitespace: true,
removeComments: true,
removeRedundantAttributes: true
}
}),
new PreloadWebpackPlugin({
rel: 'preload',
as: 'script',
include: 'all',
fileBlacklist: [/\.(css|map)$/, /base?.+/]
}),
new webpack.NoEmitOnErrorsPlugin(),
new CompressionPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
threshold: 10240,
minRatio: 0.8
})
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react', 'es2015'],
plugins: ["transform-es2015-arrow-functions"]
}
},
include: sourcePath
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: { minimize: true } },
'postcss-loader',
'sass-loader'
]
})
},
{
test: /\.(eot?.+|svg?.+|ttf?.+|otf?.+|woff?.+|woff2?.+)$/,
use: 'file-loader?name=assets/[name]-[hash].[ext]'
},
{
test: /\.(png|gif|jpg|svg)$/,
use: [
'url-loader?limit=20480&name=assets/[name]-[hash].[ext]'
],
include: staticSourcePath
}
]
}
};
Here additionally I've added the es2015 to presets: ['env', 'react', 'es2015'] and plugins: ["transform-es2015-arrow-functions"] but it made no sense.
Well in case when the babel loader won't work at all of misconfiguration or something else, I think that the whole application won't start. I believe that something should be done with presets or their order... Need advice from experienced developer
UPDATE
I've changed devtool to inline-cheap-module-source-map and got error point to overlay.js -> const ansiHTML = require('ansi-html');
In your package.json file
change the version of webpack-dev-server to version "2.7.1" (or earlier).
"webpack-dev-server": "2.7.1"
Then do a npm install et voilĂ .
That solved the problem for me.
All versions after 2.7.1 gives me an error similar to yours.
Simply add devtools : "source-map" to your Webpack config like this:
const path = require('path');
module.exports = {
devtool: "source-map",
entry: ['babel-polyfill', path.resolve(__dirname, './js/main.js')],
mode: 'production',
output: {
path: __dirname+'/js/',
filename: 'main-webpack.js'
}
};
This will remove eval and change your source map to be supported by IE.
UPDATE I've changed devtool to inline-cheap-module-source-map and got error point to overlay.js -> const ansiHTML = require('ansi-html');
And to support ES6 syntax you have to compile your JavaScript code with Babel.

Hot reloald webpac-dev-server when changing sass

i have simple webpack build with webpack-dev-server. It's work, and when i changing .js file its autorefreshingin browser. But when i changhing .sass nothing happens. Here is my webpack.confing
const { resolve } = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
const config = {
devtool: 'cheap-module-eval-source-map',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./main.js',
'./assets/sass/main.sass',
],
output: {
filename: 'bundle.js',
path: resolve(__dirname, 'dist'),
publicPath: '/',
},
context: resolve(__dirname, 'app'),
devServer: {
hot: true,
contentBase: resolve(__dirname, 'dist'),
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
loaders: [
'babel-loader',
],
exclude: /node_modules/,
},
{
test: /\.sass$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'sass-loader',
query: {
sourceMap: false,
},
},
],
}),
},
{ test: /\.(png|jpg)$/, use: 'url-loader?limit=15000' },
{ test: /\.eot(\?v=\d+.\d+.\d+)?$/, use: 'file-loader' },
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/, use: 'url-loader?limit=10000&mimetype=application/octet-stream' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=10000&mimetype=image/svg+xml' },
]
},
plugins: [
new ExtractTextPlugin({ filename: 'style.css', disable: false, allChunks: true }),
new CopyWebpackPlugin([{ from: 'vendors', to: 'vendors' }]),
new OpenBrowserPlugin({ url: 'http://localhost:8080' }),
new webpack.HotModuleReplacementPlugin(),
],
};
module.exports = config;
Also, please tell me how to make the files get in the right folders during the build (.css to dist/css, js to dist/js), 'cuz rigth now they all go to the root of dest folder.
Hot reloading doesn't work with extract-text-webpack-plugin. You should not use it in development and you can easily disable it by setting the disable option to true in development. You can use an environment variable like so:
new ExtractTextPlugin({
filename: 'style.css',
disable: process.env.NODE_ENV !== 'production',
allChunks: true
}),
This will only extract the CSS in production mode, so you'd need to run your production build with:
NODE_ENV=production webpack [options]
Or if you are on windows:
set NODE_ENV=production && webpack [options]
There is also cross-env if you look for a cross platform solution.
For getting the JavaScript files to dist/js and the CSS file to dist/css you could set output.path to dist/js and then tell extract-text-webpack-plugin to generate the file into ../css/style.css.
output: {
filename: 'bundle.js',
path: resolve(__dirname, 'dist/js'),
publicPath: '/',
},
plugins: [
new ExtractTextPlugin({
filename: '../css/style.css',
disable: process.env.NODE_ENV !== 'production',
allChunks: true
}),
// other plugins
]

Configure react webpack for deploy

need a little help.
We had tried to deploy a react project, but we are unable to configure it.
We use: es6, webpack, redux, react, babel.
this is webpack base:
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
export default {
entry: './app/app.js',
output: {
path: './app/App/dist',
filename: '/bundle.js',
},
module: {
loaders: [
{
test: /\.json$/,
loader: 'json',
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass'),
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('css!sass'),
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.svg$/,
loader: 'babel?presets[]=es2015,presets[]=react!svg-react',
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './app/App/index.html',
}),
new ExtractTextPlugin('/app/App/css/default.css', {
allChunks: true,
}),
],
};
webpack dev:
import webpack from 'webpack';
import baseConfig from './webpack.config.base';
const config = {
...baseConfig,
debug: true,
devtool: 'cheap-module-eval-source-map',
plugins: [
...baseConfig.plugins,
new webpack.HotModuleReplacementPlugin(),
],
devServer: {
colors: true,
historyApiFallback: true,
inline: true,
hot: true,
},
};
export default config;
webpack prod:
import webpack from 'webpack';
import baseConfig from './webpack.config.base';
const config = {
...baseConfig,
plugins: [
...baseConfig.plugins,
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: {
screw_ie8: true,
warnings: false,
},
}),
],
};
export default config;
This is our actual webpack, we are trying to deploy the project with it, but does not work.
Does anyone have an idea how to configure it?
So, it's a server problem probably. You need a HTTP server in order to server the static files (your app basically). I recommend the Ngxin, very easy to configure and use.
After install nginx, delete the /etc/nginx/sites-enable/default file and create a new one (you can use whatever name you want here). Here's the config I use:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
root /var/html/myProject/;
try_files $uri /index.html;
}
}
after that, restart nginx and should be ready to go.
for webpack, I have a simpler config that works well:
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const isProd = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() == 'production';
const plugins = [
new ExtractTextPlugin(isProd ? 'bundle.[hash].css' : 'bundle.css', { allChunks: true }),
new HtmlWebpackPlugin({
template: 'index.html',
inject: 'body',
filename: 'index.html'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
];
const prodPlugins = [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.AggressiveMergingPlugin()
];
module.exports = {
devtool: isProd ? 'cheap-module-source-map' : 'eval',
entry: [
'./src/index.jsx'
],
output: {
path: isProd ? path.join(__dirname, 'dist') : __dirname,
publicPath: '/',
filename: isProd ? 'bundle.[hash].js' : 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{
test: /\.(scss|css|sass)$/,
loader: ExtractTextPlugin.extract('css!sass')
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url'
},
{
test: /\.html$/,
loader: 'html'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
},
plugins: isProd ? prodPlugins.concat(plugins) : plugins
};
A few points:
I'm using SASS
Check the path's before run anything
To compile for production, just run NODE_ENV=production webpack -p
I'm using a few plugins for Uglify JS and compress files.
I think that's it! Cheers!
sure I think the fastest way to solve your problem is to click on this link:
React starter kit
and select any starters that matches your technologies!
I think you are looking for this one : react-boilerplate

Resources