require is working jsx file but url() resolve is not wroking in sass file - webpack - reactjs

I am facing this strange issue with Webpack. After spending hours couldn't find solution.
In my jsx file when I a try to set image source via this
let img = require('../../../img/imgN.png');
It is working perfectly but when I try to set the background image using scss via
$bg-img: url('../img/bg-img.png');
Image is not getting loading by webpack.
This is my webpack file
module.exports = {
devtool: 'source-map',
entry: {
main: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./src/index.js'
]
},
output: {
path: path.join(__dirname, 'public'),
publicPath: '/public/',
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
loader: 'react-hot!babel'
},
{
test: /\.scss$/,
include: path.join(__dirname, 'sass'),
loaders: ["style", "css?sourceMap", "sass?sourceMap"]
},
{
test: /\.(png|jpg)$/,
include: path.join(__dirname, 'img'),
loader: 'url-loader?limit=30000'
} // inline base64 URLs for <=30k images, direct URLs for the rest
]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
}

Problem was occurring because of using sourceMap with style-loader.
There is some issue on github for the same problem.
Solution:
1 . While source-maps is enabled
Style-loader uses a Blob, so it requires absolute urls to work.
Changed publicPath: '/public/', to
publicPath: 'http://localhost:8080/public/',
It worked.
Without source-maps
Just remove source map from style loaders.
Now style-loader will use an inline style tag, so there is no problem.
{
test: /\.scss$/,
include: path.join(__dirname, 'sass'),
loaders: ["style", "css", "sass"]
},

Can you try to see if $bg-img: url('~/img/bg-img.png'); would work? When I was trying out webpack in my bootstrap.scss files I had to modify the font url's using ~ (I think I read it somewhere but ya just giving you something to try)

Related

How to get Images from bundled app

I have a bundled app with webpack with this script. This script alsa exports files as well.
I import this app from another app. The bundled app works pretty well inside the paretn app but I couldn't find how to display and use this exported images in the parent app. They aren't shown. My guess is webpack doesn't see the images as module.
module.exports = {
devtool: 'source-map',
entry: './src/App.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js',
libraryTarget: 'commonjs2'
},
plugins: commonConfig.plugins.concat([
new webpack.optimize.OccurrenceOrderPlugin()
]),
resolve: commonConfig.resolve,
module: {
rules: commonConfig.module.rules.concat({
test: /\.less$/,
use: [
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!postcss-loader',
'less-loader'
]
})
},
externals: {
'react': 'commonjs react'
}
};
The solution I found for now is include images (small svg and png files) to bundle with this kind of configs. it may be a better solution with code splitting.
{
test: /.*\.(svg)$/i,
include: path.resolve(mainPath, 'ui/svg/inline'),
use: "svg-inline-loader"
},
{
test: /.*\.(svg)$/i,
include: path.resolve(mainPath, 'ui/svg/default'),
use: {
loader: "url-loader",
options: {
limit: 100000
}
}
},

Webpack production build file paths are off

I'm running this command to try & generate a production webpack build:
rimraf ./build/* && webpack -p --progress --config webpack.production.js
However, when I open up the build/index.html, it's failing to load a lot of files because the locations are off.
It fails to put the correct location for the bundle.js file. It loads it like this: /bundle.js. However the bundle.js file is actually in the same directory as the index.html file in the build folder so it should load it like this ./bundle.js
If I correct the bundle.js path, it's still putting an incorrect route for the assets:
What's interesting is that my app currently works with the webpack dev server when I run: webpack-dev-server --inline --progress --config webpack.dev.js.
Here is what my current webpack.production.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
entry: [
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
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 HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: true
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
]
}
And just in case, this is what my current webpack.dev.js file looks like:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-source-map',
devServer: {
historyApiFallback: true, // This will make the server understand "/some-link" routs instead of "/#/some-link"
},
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
'./src/scripts' // This is where Webpack will be looking for the entry index.js file
],
output: {
path: path.join(__dirname, 'build'), // This is used to specify folder for producion bundle
filename: 'bundle.js', // Filename for production bundle
publicPath: '/'
},
resolve: {
modules: [
'node_modules',
'src',
path.resolve(__dirname, 'src/scripts'),
path.resolve(__dirname, 'node_modules')
], // Folders where Webpack is going to look for files to bundle together
extensions: ['.jsx', '.js'] // Extensions that Webpack is going to expect
},
module: {
// Loaders allow you to preprocess files as you require() or “load” them.
// Loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle frontend build steps.
loaders: [
{
test: /\.jsx?$/, // Here we're going to use JS for react components but including JSX in case this extension is preferable
include: [
path.resolve(__dirname, "src"),
],
loader: ['react-hot-loader']
},
{
loader: "babel-loader",
// Skip any files outside of your project's `src` directory
include: [
path.resolve(__dirname, "src"),
],
// Only run `.js` and `.jsx` files through Babel
test: /\.jsx?$/,
// Options to configure babel with
query: {
plugins: ['transform-runtime', 'transform-decorators-legacy'],
presets: ['es2015', 'stage-0', 'react'],
}
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
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 HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
hash: false
})
]
}
Any ideas what I'm doing wrong?
faced a similar issue. setting output.publicPath: "/" in webpack.dev.js and output.publicPath: "./" in webpack.prod.js, did the trick for me.
Got the same error when running npm run watch, local dev still worked, but after deploying to demo server the app crashed on wrong js-file url.
Cause:
Some changes in my webpack.mix.js started compiling a index.html file that was found by the browser, instead of the app.blade I was using.
Fixed the paths by setting: publicPath: './public/'
(Note that it's a relative path). Also, I removed the generated url by setting inject: false, in the HtmlWebpackPlugin({ section and used the asset('/...') logic.

"Modules" is not allowed Error

Webpack 2 comes with the new resolve setting and when I try to modify the setting in config, as follows, webpackValidator throws an error saying
"Modules" is not allowed"
const config = webpackValidator({
context: resolve('src'),
entry: './app.js',
output: {
filename: 'bundle.js',
path: resolve('dist'),
publicPath: '/dist/',
pathinfo: ifNotProd(),
},
devtool: ifProd('source-map', 'eval'),
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel'],
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.js'],
modules: [
resolve(__dirname, 'src'),
resolve(__dirname, 'node_modules')
]
},
plugins: [
new DashboardPlugin()
]
})
As mentioned on the webpack-validator project's readme (npm & github), you should seriously consider giving up the use of this package...
Note: webpack v2 has built-in validation for configuration. Due to this, webpack-validator is unlikely to make significant changes. While pull requests will be reviewed and can be merged, project maintainers are unlikely to put a lot of much effort into the maintenance of the project.
I had the same issue and finally gave up its use : Webpack 2 introduced breaking changes that surely won't be followed by the webpack-validator project.
The new built-in validation for configuration in Webpack 2 is now good enough.
By the way, your config may need a few improvements :
const config = {
context: resolve('src'),
entry: './app.js',
output: {
filename: 'bundle.js',
path: resolve('dist'),
publicPath: '/dist/',
pathinfo: ifNotProd(),
},
devtool: ifProd('source-map', 'eval'),
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.js'],
modules: [
resolve(__dirname, 'src'),
resolve(__dirname, 'node_modules')
]
},
plugins: [
new DashboardPlugin()
]
}
module.loaders becomes module.rules
module.loaders.loaders becomes module.rules.use
You can't use the shortcut 'babel' instead of 'babel-loader' any more, unless you specify it (resolveLoader.moduleTemplates property).

Webpack with babel-loader for react corrupts image files

I am using webpack with babel-loader to transform .jsx react files.
However, adding a file-loader or style- and css-loader does not correctly process the images required() in the react components or style sheets.
They get recognized by webpack and copied to the dist folder. The path to the image file is correct, I've verified this in the css and js output.
The server is also able to display the files, I've checked with some manually copied ones.
What is happening is that the images themselves get corrupted. No image viewer nor the browser can display the image which results in an invisible image in the browser.
What I've tried so far:
using only babel-loader as suggested in: https://github.com/webpack/file-loader/issues/35, results in Error: No handler for file type.
using file-loader directly
using image-webpack-loader (which seems to be using file-loader under the hood)
using IsomorphicLoaderPlugin (https://github.com/jchip/isomorphic-loader) which seems to be a simpler alternative to webpack-isomorphic-tools
using css background-images with url() and ExtractTextPlugin('style-loader", 'css-loader')
All of the above steps resulted in either errors with webpack not finding an appropriate handler or corrupted image files.
Here is my current webpack config for reference (I've included all of it in case there are any problems/conflicts I am overlooking):
var ExtractTextPlugin = require('extract-text-webpack-plugin'),
webpack = require('webpack');
IsomorphicLoaderPlugin = require("isomorphic-loader/lib/webpack-plugin");
module.exports = {
context: __dirname + '/client',
entry: ['babel-polyfill', './index.jsx'],
output: {
filename: 'app.js',
path: __dirname + '/dist',
publicPath: '/'
},
resolve: {
ignore: /node_modules/,
extensions: ['', '.js', '.jsx']
},
devtool: 'source-map',
plugins: [
new ExtractTextPlugin('styles.css'),
new IsomorphicLoaderPlugin({ keepExistingConfig: false }),
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
],
module: {
preLoaders: [
{
loaders: ['isomorphine']
}
],
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties', 'transform-object-rest-spread'],
presets: ['react', 'es2015', 'stage-0']
}
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file!isomorphic"
}
]
}
};

How to get sourcemaps working for React Css Modules?

I'm trying to setup a React project with react-css-modules, webpack and Hot Module Replacement. Everything is working like a charm but I can't get the CSS sourcemaps to work.
I followed this guide to make HMR work. It involves a BrowserSync setup to update the css file after Webpack writes it to disk.
I use (as suggested by react-css-modules) the ExtractTextPlugin to extract all of the css:
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
But if I change this to sourcemaps, as suggested here
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass-loader outputStyle=expanded&sourceMap=true&sourceMapContents=true')
I get the error: "root" CSS module is undefined. in my browser console.
You can find my example repo here, but here's the full webpack config I'm using for development.
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WriteFilePlugin = require('write-file-webpack-plugin').default;
module.exports = {
entry: {
bundle: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'./index.js'
]
},
devtool: 'cheap-module-source-map',
debug: true,
devServer: devServer,
context: path.resolve(__dirname, './src'),
output: {
path: path.resolve(__dirname, './builds'),
filename: '[name].js',
publicPath: '/builds/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.OldWatchingPlugin(),
new WriteFilePlugin(),
new ExtractTextPlugin('[name].css', {
allChunks: true
})
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['react-hot', 'babel-loader'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
]
},
resolve: {
extensions: ['', '.js', '.json']
}
};
How to make the sourcemap work?
Use this:
ExtractTextPlugin.extract('style','css?sourceMap&modules&importLoaders=1&localI‌​dentName=[name]__[local]___[hash:base64:5]!sass?sourceMap')
i.e. add the sourceMap param to both css & sass loaders. It said so in sass-loader docs.
This is how I have my css modules set up:
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!',

Resources