I am using webpack to transpile my reactjs code. When I run it locally on webpack dev server, I can see my background image. However when I deploy it to the server the image doesn't show. I figure it must be some kind of path issue.
css
.centerbg {
background: url(/images/centerbg.jpg) no-repeat;
}
jsx
<div className="centerbg">
</div>
webpack loader
{
test: /\.(woff|ttf|eot|svg|png|jpg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader',
options: {
limit: 10000
}
}
File paths
build/main.js
images/centerbg.jpg
index.html
This is a bug usually dued to output.publicPath config not being explicitely declared.
Set it to the path where your assets will be served from. For basic scenarios this is enough:
output: {
publicPath: '/',
//...
},
Related
Using Vite/React/Tailwind, I am trying to set dev/prod workflow so that images stored in 'public' directory has the correct path when deployed to gh-pages. Below is my Tailwind config starting point where 'backgroundImages' property is referencing an image file stored in 'public'.
module.exports = {
mode:'jit',
content: ["./src/**/*.{html,jsx}"],
theme: {
screens: {
sm: '480px',
md: '768px',
lg: '976px',
xl: '1440px',
},
colors: {
'splash-hex': '#6BD1D2',
'splash-rgba': 'rgba(107, 209, 210,1.0)',
'splash-hsla': 'hsla(181, 53%, 62%, 1.0)',
},
fontFamily: {
sans: ['Graphik', 'sans-serif'],
serif: ['Merriweather', 'serif'],
},
backgroundImages:{
'default':'url("./10475996-3x2-940x627.jpeg")'
},
extend: {
spacing: {
'128': '32rem',
'144': '36rem',
},
borderRadius: {
'4xl': '2rem',
}
}
},
prefix: 'tw-',
plugins: [],
}
In dev this works fine.
http://localhost:3000/10475996-3x2-940x627.jpeg
In 'dist' folder, it looks correct as well when 'build' is run.
When deployed to gh-pages, the path changes to /assets/ and the image is no longer served from root as I expected according to Vite.
https://unevenartwork.com/assets/10475996-3x2-940x627.jpeg
Is there a configuration that would suppress the /assets/ on deploy or another solution?
The solution to this issue has two parts.
First, as shown in this answer, on build or deploy command, Rollup will create the output directories when set in the config. Just place the image assets in src/img folder as a target for Rollup to output to dist folder.
Then, in Tailwind config, be sure to make a reference to the parent directory in the asset path - ../img/10475996-3x2-940x627.jpeg instead of ./img/10475996-3x2-940x627.jpeg. This helps Vite make the correct path association to the parent directory.
It appears this is effective for properties defined in Tailwind theme extensions. No issues experienced with img src attribute values.
my angular app ends up being deployed to web server with different virtual paths such as:
http://website.com/app1/
http://website.com/app2/
To get them both work properly, at the build stage I change angular's <base href=> and webpack's publicUrl options to match specific virtual path app1 or app2.
The urls in my index.html are properly changed from
<img src='hello.png'/> to <img src='app1/hello.png'/> but the urls inside the css and sass are not changed at all.
I use style-loader, css-loader and sass-loader plugins like that:
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
include: [helpers.root('src', 'styles')],
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: [helpers.root('src', 'styles')]
}
And lets say my css is:
body {
background-image: url(bg.png);
}
Can I force webpack to add publicUrl to bg.png and load it from url(app1/bg.png)?
UPD:
There is no way to use Angular CLI
Something like this could work (not tested):
webpack.config.js
...
{
loader: "sass-loader",
options: {
data: "$baseUrl: " + process.env.baseUrl + ";"
}
}
...
scss:
body {
background-image: url($baseUrl + 'bg.png');
}
this way you could also change process.env.baseUrl in the build stage
So I am trying to add some css style to my react components but failed.
My webpack.config.js looks like:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, './build');
var APP_DIR = path.resolve(__dirname, './src/client');
const config = {
entry: {
main: APP_DIR + '/index.js'
},
output: {
filename: 'bundle.js',
path: BUILD_DIR,
},
module: {
rules: [
{
test: /\.css$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader?modules=true&camelCase=true"
}]
},
{
test: /\.(jsx|js)?$/,
use: [{
loader: "babel-loader",
options: {
cacheDirectory: true,
presets: ['#babel/preset-react']
}
}]
}
],
}
};
module.exports = config;
My client code folder looks like:
Client
--style
----index.css
--index.js
index.css looks like:
body{
color: #555;
background: #f85032;
margin: 10px 30px;
}
Inside index.js, I am loading the css file using
import css from './style/index.css';
Then I do:
npx webpack
npm start
There's no error message in console output. The webpage shows up but there's no css style. Can someone please help me with this? Thanks!
It appears that if I do some inline css in index.html then it works? Any suggestion why this happens? Thanks!
Change to import './style/index.css'; and see if that works
I am just guessing here, since i can not see your index.js
From your webpack file i can see that you are using css modules.
This means that you can not just assign classes as you would usually do it, but you must get them from the css you imported.
Hence
'<div className="className">'
Becomes
'<div class=Name"' + css.className + '">'
The reason is thay css modules is doing some clever naming to always make the imported css unique to ensure you are not having any global scoping and conflicts (which is what you want with css modules)
UPDATE
I have tried to create a local setup with your webpack config. You can download it here (It is just a zip file).
Unzip and enter folder then run npm install and npm run webpack. You can now open build/index.html and see the result.
Maybe then you can see what you are doing differently?
When you're using the create-react-app package you're able to have .scss-files compiled into .css-files as you type in them. You can then do import './Header.css'; in your React component files and the styles are applied. It's easy to use your dev-tools and see where the styles are coming from.
Next.js tried to get everyone to use Styled-JSX to have your stylesheets inline inside your JSX files, similar to how web components (or Polymer) do it. I personally strongly dislike that approach.
Other problems:
Styled-JSX isn't supported in my IDE (Webstorm) (even the work-around looks awful);
Styled-JSX isn't supported in my dev-tools (Chrome) - there is no reference to what line the style is defined at;
It makes my source code look like a garbled mess;
How do I include 3rd party CSS solutions with Styled-JSX? Am I now supposed to add a <link> to my <head>? For everything external? How is that optimal usage of bandwidth? Referencing to files inside of node_modules feels awkward and bad, too.
So, just add rules to next.config.js, right?
module.exports = {
webpack: (config, { dev }) => {
config.module.rules.push(
{
test: /\.(css|scss)/,
loader: "style-loader!css-loader"
}
);
return config
}
};
And then just import './Page.scss'; (Don't worry, it's valid CSS, not even SASS yet, I know I did not include the sass-loader here just yet. I try to keep it simple first.)
Refresh the page (Server Side Rendered): does NOT work;
Save the file (dynamically loaded after saving the file): it does work (until you reload the page);
Keeps complaining the file can't be found, plenty of Google hits there, too. No real solutions that work today.
So, why doesn't it work with SSR?
Note that v5 of next.js will support CSS/Sass/Less almost out of the box:
For importing .css .scss or .less we’ve created modules which have sane defaults for server side rendering.
Until then, the following set of rules worked for me (assuming the .sass files are in /styles dir):
config.module.rules.push(
{
test: /\.(css|sass)/,
loader: 'emit-file-loader',
options: {
// this path is relative to the .next directory
name: 'dist/[path][name].[ext]'
}
},
{
test: /\.css$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader']
},
{
test: /\.sass$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader',
{ loader: 'sass-loader',
options: {
includePaths: ['styles', 'node_modules']
.map((d) => path.join(__dirname, d))
.map((g) => glob.sync(g))
.reduce((a, c) => a.concat(c), [])
}
}
]
}
)
I'm using Webpack to process my CSS files. I want to rewrite url()s in CSS files to keep referencing the original assets, just changing the URL.
For example this file:
/* src/main.css */
body {
background-image: url('image.png');
}
should compile to this
/* bundle/main.css */
body {
background-image: url('../src/image.png');
}
I found the rewrite-url-loader but this just does not work at all for me, it does nothing.
I've got the feeling that file-loader may be able to do just what I want to do but I can't figure out how.
Anyone got an idea?
That was actually really easy.
I had to set Webpack's context option to point to my project root.
Then I could easily just use file-loader like this: file?emitFile=false&name=[path][name].[ext]&publicPath=../.
For Webpack 2 and Webpack 3:
use: [{
loader: 'file-loader',
options: {
context: path.resolve(__dirname, 'src')
name: '[path][name].[ext]'
},
},
For a full answer with example and explanation: https://stackoverflow.com/a/46931670/1049693