Webpack inline CSS background images - javascript

I'm trying to get webpack to load images and can't seem to get it working. My configuration looks like this:
var config = {
entry: APP_DIR + '/index.jsx',
output: {
path: BUILD_DIR,
publicPath: "/build/",
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?/,
include: APP_DIR,
loader: 'babel'
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test : /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
loader : 'url-loader'
},
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader'
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
And I am trying to use as an inline CSS background image like this:
<div class="inner-panel"
style="background-image: url("/common/img/split-image/image.jpg");">
</div>
Also it doesn't work as an inline image:
<img src="/common/img/split-image/image.jpg">

Problem is with your image paths, not with your webpack config.
Try putting a ./ at the start of your path like so
"./common/img/split-image/image.jpg"
Other then that you should look at your file requires as well and make sure there are placing them where you want to place them.
Since you are using file-loader (and I think React as well), an example of how you would use it would be:
//CJS
var file = require("file!./file.png");
//ES6
import file from "file!./file.png";
//Later inside a React component
const inStyle = {
background-image: 'url(' + file + ')'
}
<div style={inStyle}/>
(React takes objects rather then strings for the style attribute)
url-loader should be the same. Hope this helps.

Related

How to merge bundles with webpack

I'm developing a few React components with the intention of adding them to our Webflow site. For that, I've added an entry for each component in my webpack.config.js file. Now, it looks like this:
const path = require("path");
module.exports = {
entry: {
component_a: "./src/components/a.js",
component_b: "./src/components/b.js",
component_c: "./src/components/c.js",
},
mode: "production",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(pdf|jpg|png|gif|svg|ico)$/,
use: [
{
loader: "url-loader"
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
}
]
},
resolve: {
extensions: ["*", ".js", ".jsx"]
},
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "bundle_[name].js"
},
devServer: {
static: {
directory: path.join(__dirname, "dist")
}
}
};
This generates me a few bundle_<component_name>.js files, which works great!
But then, there was a need of adding react-map-gl for some of those components, and that's where the issue began: I was having an issue with react-map-gl when doing npm run build and this solved it. But at the same time, a new bundle_mapbox-gl-csp-worker.worker.js is generated for me and all of my built components that depend on it have something like this:
{return new Worker(i.p+"bundle_mapbox-gl-csp-worker.worker.js")}
Although it works fine for our container deployment (because it will always look for bundle_mapbox-gl-csp-worker.worker.js on the same origin and this file will exist), whenever I try to add <script src="https.../bundle_my_component.js"> to Webflow, it will look for https://my-webflow.domain/bundle_mapbox-gl-csp-worker.worker.js, which doesn't exist.
I've tried to replace i.p+"bundle_mapbox-gl-csp-worker.worker.js" to somewhere this script is known to exist, but then I get Script at 'https://.../bundle_mapbox-gl-csp-worker.worker.js' cannot be accessed from origin 'https://some.other.origin'.
I wonder if there's a way of merging my component and the bundle_mapbox-gl-csp-worker.worker.js somehow, either through webpack or something. Or any other workaround for this.

React reusable component library styles not loading

hey people I need help with the following:
am creating React UI component library
I am using webpack and dev build works great, scss files are loaded and components are displayed correctly
on production build, JS bundle is created as well as CSS (I use SCSS) bundle
BUT when I install the library in another React project and import the component, CSS is not loaded (cmp is not styled), JS works fine and the component is rendered yet styles are not loaded...
EDIT
Apparently this approach requires manual loading of CSS in parent app project. Which I want to avoid. Is there alternative way which can provide scenario in which styles will be resolved on the level on component without need for manual loading?
Here is my production webpack config:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, '../lib'),
libraryTarget: 'commonjs',
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader']
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {}
}
}
]
},
externals: {
'react': 'commonjs react',
'react-dom': 'commonjs react-dom',
},
resolve: {
modules: [
path.resolve('./src'),
path.resolve('./node_modules')
]
},
plugins: [
new ExtractTextPlugin({
filename: 'ui-library.css'
})
]
};
You could simply not use ExtractTextPlugin.
The whole purpose of Webpack is to group assets not based on file type but by a component perspective.
So, if you remove ExtractTextPlugin, your CSS will be included in your .js bundle.

Correctly bundled image could not be loaded

I have a very simple React component, that is supposed to display an image.
I am also using Webpack for bundling.
It's probably worth noting that I am using ReactJS.NET.
Although the webpack bundle builds properly, and the .jpg generated by webpack is viewable (using Windows Photo Viewer, for example), the image does not display in my View.
When I take a peek into inspector, the html structure is built properly, but I am getting:
"Could not load the image" - when I hover over the image path.
I made sure that the image path is correct.
Below is my react component:
var React = require('react');
var BackgroundImg = require('./Images/img_fjords.jpg');
class Login extends React.Component {
render() {
return (
<img src={BackgroundImg} />
);
}
componentDidMount() {
console.log("Mounted");
}
}
module.exports = Login;
Webpack config:
var path = require('path');
var WebpackNotifierPlugin = require('webpack-notifier');
module.exports = {
context: path.join(__dirname, 'App'),
entry: {
server: './server',
client: './client'
},
output: {
path: path.join(__dirname, 'Built/'),
publicPath: path.join(__dirname, 'Built/'),
filename: '[name].bundle.js'
},
plugins: [
new WebpackNotifierPlugin()
],
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
},
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' },
{ test: /\.jsx$/, loader: 'jsx-loader?harmony' }
]
},
resolve: {
// Allow require('./blah') to require blah.jsx
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
}
};
The problem was solved thanks to help from #Luggage.
The webpack.config was wrong, it should have been:
output: {
path: path.join(__dirname, 'Built/'),
publicPath: 'Built/',
filename: '[name].bundle.js'
},
Well, I can't see your webpack config, but I'm assuming your using all the correct loaders (file-loader, extract-loader, html-loader, url-loader)? The way I handle it is using the webpack-copy-plugin to copy over my images folder so relative paths still work.

Webpack img-loader can not load image

I am tring to load image locally, the image file is in the same folder of jsx file. The webpack.config.js is looks like this:
path = require('path');
module.exports = {
context: __dirname,
entry: "./app/entry.jsx,
output: {
path: path.join(__dirname, 'lib'),
filename: "bundle.js",
devtoolModuleFilenameTemplate: '[resourcePath]',
devtoolFallbackModuleFilenameTemplate: '[resourcePath]?[hash]'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['react']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader?root=."
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'url?limit=10000!img?progressive=true'
}
]
},
devtool: 'source-map',
resolve: {
extensions: ["", ".js", ".jsx" ]
}
};
and the jsx is like this
var loadingImg = require('url!img!./loading.gif');
the error shows in console is:
ERROR in Loader app/node_modules/url/url.js didn't return a function
# app/components/session/login.jsx 5:17-49
How should I load this image?
Nothing is jumping out at me as incorrect in your webpack config file. I would take a look at the way you're calling the image in your code, doesn't look right to me. I'm not sure where you're trying to use the code, but you could do something like;
<img src={require("../../images/some-filepath/some-image.png")} />
or:
<Image source={{uri: '../../images/some-filepath/some-image.png'}} />
I did make a tutorial a while ago for using the image-webpack-loader, if you want to take a look.
Anyway, hope this helps!

Webpack only generates JS, no CSS file from SCSS

In my project I use Webpack with React and NodeJS. I want to generate a bundle.js and style.css file. Currently I've got the following code:
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
path: 'public',
filename: 'bundle.js',
publicPath: ''
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
},
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('css!sass') }
]
},
plugins: [
new ExtractTextPlugin('public/style.css')
]
}
But when I run webpack only the JS file is created in the ./public map:
Asset Size Chunks Chunk Names
bundle.js 844 kB 0 [emitted] main
+ 222 hidden modules
Following examples/tutorials it's only oriented on CSS files, or obvious mistakes where made like not implementing ExtractText.
I've also downloaded the packages sass-loader node-sass. In some examples I did found those packages where included, in some they weren't.
EDIT (require style in index.js):
import React from 'react'
import { render } from 'react-dom'
import { Router, browserHistory } from 'react-router'
import routes from './modules/routes'
require('./public/style.css')
render(
<Router routes={routes} history={browserHistory} />,
document.getElementById('app')
)
EDIT (webpack.config.js):
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
},
{
test : /\.scss$/,
include : path.join(__dirname, './public/sass'),
loaders : ["style", "css", "sass"]
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass')
}
]
},
sassLoader: {
includePaths: [path.join(__dirname, './public/sass')]
},
plugins: [
new ExtractTextPlugin(path.join(__dirname, './public/style.css'))
]
My folder structure looks like this:
webpack.config.js
index.js
/public
index.html
bundle.js (generated)
/sass
style.scss
basics.scss (imported in style.scss)
Make sure that you require your style file.
e.g.
require('../sass/app.scss');
and I think you need style loader as well
e.g.
{
test : /\.scss$/,
include : path.join(__dirname, 'sass'),
loaders : ["style", "css", "sass"]
}
These three loaders perform following operations
Turn your scss files into plain CSS with the sass loader
Resolve all the imports and url(...)s in the CSS with the help of CSS loader
Insert those styles into the page with the style loader
You need a combination of the ExtractTextPlugin and the style loader.
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader'),
},
],
}
...
plugins: [
new ExtractTextPlugin(path.join(__dirname, 'public', 'style.css')),
],
In my working configs, I also have a possibly extraneous entry in resolve:
resolve: {
loaders: [
{
test: /\.(css|scss)$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),
},
],
},
The other error might be how you're including it in index.js. You're using require('./public/style.css') rather than require('./public/style.scss').

Categories