Skip to content
This repository was archived by the owner on Mar 17, 2021. It is now read-only.

output images are in parent folder when useRelativePath option is true #149

Closed
aamirshahx opened this issue Apr 9, 2017 · 20 comments
Closed

Comments

@aamirshahx
Copy link

aamirshahx commented Apr 9, 2017

My webpack file

import CleanWebpackPlugin from 'clean-webpack-plugin';
import StyleLintPlugin from 'stylelint-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import combineLoaders from 'webpack-combine-loaders';
import {modulesRoot, root, staticRoot} from './helpers';

const projectRootPath = root('.');
const modulesPath = modulesRoot();
const buildPath = staticRoot();

export default (env) => {
	let proMode = env.toLowerCase() !== 'production';

	return {
		devtool: proMode ? 'source-map' : 'eval',

		entry: {
			'css/web/home/styles': 'css/web/home/styles.pcss'
		},

		output: {
			path: buildPath,
			publicPath: buildPath,
			filename: proMode ? '[name].[chunkhash].css' : '[name].css',
			sourceMapFilename: proMode ? '[name].[chunkhash].map' : '[name].map'
		},

		resolve: {
			modules: [projectRootPath, modulesPath, root('images')],
			extensions: ['.pcss']
		},
		module: {
			rules: [
				{
					test: /\.(jpe?g|png|webp|svg|gif|cur)$/i,
					loader: 'file-loader',
					options: {
						name: '[path][name].[hash].[ext]',
						publicPath: '../../'
					}
				},
				{
					test: /\.pcss$/,
					loader: ExtractTextPlugin.extract({
						use: combineLoaders([
							{
								loader: 'css-loader',
								options: {
									importLoaders: 1,
									sourceMap: proMode,
									url: true
								}
							},
							{
								loader: 'postcss-loader',
								options: {
									sourceMap: proMode ? undefined : 'inline'
								}
							}
						])
					})
				}
			]
		},
		plugins: [
			...(env === 'watch' ? [] : [new CleanWebpackPlugin(['build'], {root: projectRootPath, verbose: true})]),
			new StyleLintPlugin({files: 'css/**/*.pcss'}),
			new ExtractTextPlugin({filename: (proMode ? '[name].[chunkhash].css' : '[name].css'), allChunks: true})
		],
		stats: {
			assets: true,
			children: false,
			chunks: true,
			chunkModules: true,
			chunkOrigins: true,
			colors: true,
			errors: true,
			errorDetails: false,
			hash: false,
			modules: false,
			reasons: false,
			source: true,
			timings: true,
			version: true,
			warnings: true
		},
		node: {
			global: true,
			crypto: 'empty',
			process: true,
			module: false,
			clearImmediate: false,
			setImmediate: false
		}
	};
};

My folder structure

|-
|----css/
|--------web/
|-------------home/
|-------------------style.pcss
|-------------app/
|-------------------app.pcss
|------------desktop/
|-------------------desktop.pcss
|----images/
|-------------home/
|-------------------image1.jpg
|-------------app/
|-------------------image2.jpg
|------------desktop/
|-------------------image3.jpg

`

when i am building my project with above config
my build folder structure is

|-
|----build/
|---------css/
|--------------web/
|-------------------home/
|-------------------------style.css
|-------------------app/
|-------------------------app.css
|--------------desktop/
|-----------------desktop.css
|---------images/
|--------------web/
|-------------------home/
|-------------------------image1.jpg
|-------------------app/
|-------------------------image2.jpg
|--------------desktop/
|-------------------------image3.jpg

`

but since i am specifying public path ('../../')
background: url(../../image/desktop/image3.jpg) in my desktop.css are working correctly

but web/home/style.css
background: url(../../image/web/home/image1.jpg) in style.css is not correct (correct path should be ../../../image/desktop/image3.jpg)

then i tried


				{
					test: /\.(jpe?g|png|webp|svg|gif|cur)$/i,
					loader: 'file-loader',
					options: {
						name: '[name].[hash].[ext]',
						useRelativePath: true,
						publicPath: url => url
					}
				}

then the css files are creating correct paths
for desktop background: url(../../image/desktop/image3.jpg)
for web/home background: url(../../image/web/home/image1.jpg)

but images folder is not in build directory
desktop images are in the project's parent folder (../../)
and web/home images in project's parent's parent folder (../../../)

How to create images folder in build/ and have the same paths as with useRelativePath?

@aamirshahx aamirshahx changed the title output images are in parent folder when use useRelativePath output images are in parent folder when useRelativePath option is true Apr 9, 2017
@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Apr 11, 2017

@nopantsmonkey You can't use .css files as entry points, webpack entries are JS only

@michael-ciniawsky
Copy link
Member

and please add the ``` around the code it's very hard to read atm 😛

@aamirshahx
Copy link
Author

i 've created a repo for you with the issue
and added both options that i am using with file-loader
please toggle options and check i 've also added some description with options

Commands

npm run build
npm run build:prod

Repo URL:
file-loader-relative-path-issue

@michael-ciniawsky
Copy link
Member

@nopantsmonkey kk i will take a look into it soon

@adriancmiranda
Copy link
Contributor

adriancmiranda commented Apr 13, 2017

@nopantsmonkey It's a knowed issue. I'm solving this, can you test this version, please?
https://bitbucket.org/adriancmiranda/pr-file-loader/src

EDIT
https://bitbucket.org/adriancmiranda/pr-file-loader/src/489f5e70002496b4098a283b1a794643ee0869e7/?at=file-loader-relative-path-issue

This version seems to work. Can you confirm for me if it working as expected?

@aamirshahx
Copy link
Author

aamirshahx commented Apr 15, 2017

yes @adriancmiranda it is working as expected.

@michael-ciniawsky
Copy link
Member

@nopantsmonkey If #150 contains this, it's likely to land soon :)

@aamirshahx
Copy link
Author

aamirshahx commented Apr 15, 2017

should i close this issue now or you 'll close it after the release of file-loader with #150

EDIT:
btw Thanks Guys! @michael-ciniawsky @adriancmiranda

@michael-ciniawsky
Copy link
Member

@nopantsmonkey I will close it when #150 lands :)

@aamirshahx
Copy link
Author

@adriancmiranda i think there is some problem between the repo you asked me to verify and the code in #150
because if i am changing the local file-loader in the above code with the file-loader of #150 (adriancmiranda/file-loader) and renaming textOutputPath: '' with cssOutputPath: '' it is not creating the same urls as it was creating with the above code

images paths using above repo
../../images/desktop/spacer.ed280a0ea3cc38f3cbbc747acfbef47d.gif

images path with (adriancmiranda/file-loader:master)
images/desktop/spacer.ed280a0ea3cc38f3cbbc747acfbef47d.gif

@adriancmiranda
Copy link
Contributor

adriancmiranda commented Apr 15, 2017

@nopantsmonkey No, that's right, at line 18 we changed the defaults to empty and we also change the line 75.
In master, we have two CSS files with a single output (most of the cases).
In yours, we have multiple outputs (and multiple output path too)

So, we have two ways of dealing with this case.
The first is using a multi-compiler for your webpack.config and another is ignoring this statement with cssOutputPath: undefined, for example

It's likely that you haven't any output at the root of build for your CSS files without issue on your assets with the second approach (also isn't a problem if you put all your CSS files on styles, for example, i.e. cssOutputPath: 'styles')

@aamirshahx
Copy link
Author

aamirshahx commented Apr 16, 2017

it is working for me with cssOutputPath: undefined

@doomsbuster
Copy link

I am running into similar challenge and no combination of flags seems to fix the issue. My setup is like this:

// Project folder structure
root-app-dir
  |_ public
      |_ style
  |_ui
     |_ images
        |_ science.jpg
     |_ styles
        |_main.less

My file-loader config is as below:

// webpack.config.js
{
	test: /\.(png|jpe?g|gif|svgz?)$/i,
	include: path.resolve(__dirname, 'ui/images'),
	use: {
		loader: 'file-loader',
		options: {
			useRelativePath: true
		}
	}
}
//public/style/main.less
.content-container {
	padding: 24px;
	background-image: url(../images/science.jpg);
	background-size: cover;
	background-position: fixed;
}

This copies the images directory under the root-app-dir instead of copying it to public/images directory. No combination of outputPath, useRelativePath or context seem to fix the issue. If i remove the useRelativePath, it creates images directory in correct location, but it changes the CSS rule to background-image: url(images/science.jpg); and the UI gets a 404 since the images directory is one level up.

@adriancmiranda
Copy link
Contributor

@doomsbuster loader: 'file-loader' probably isn't the correct version 'cause I'm waiting for a review yet.

@doomsbuster
Copy link

I am using "file-loader": "^0.11.1" in my project.

@adriancmiranda
Copy link
Contributor

@doomsbuster I mean, this is the fixed version tested here at this thread. There's no merge for it yet.

@Cap32
Copy link

Cap32 commented Oct 31, 2017

I have the same problem.

Here's my temporary solution inspired by #150 (comment)

{
	test: /\.(png|jpe?g|gif|svgz?)$/i,
	include: resolve('src'),
	use: [
		
		// Don't emit file here, just override the url below
		{
			loader: 'file-loader',
			options: {
				useRelativePath: true,
				publicPath: '',
				name: '[name].[ext]',
				emitFile: false,
			},
		},

		// Just emit file here, the compiled url would be overridden
		{
			loader: 'file-loader',
			options: {
				publicPath: '',
				context: resolve('src'),
				name: `[path][name].[ext]`,
			},
		},
	],
},

It is ugly, but it works

@adriancmiranda
Copy link
Contributor

@Cap32 I think that is not right, I mean, your HTML is always rendered at the root, so your path should be images/1.jpg, doesn't?

@alexander-akait
Copy link
Member

Option useRelativePath was removed. Why #261 (comment)

@BehnamCoding
Copy link

I have the same problem.

Here's my temporary solution inspired by #150 (comment)

{
	test: /\.(png|jpe?g|gif|svgz?)$/i,
	include: resolve('src'),
	use: [
		
		// Don't emit file here, just override the url below
		{
			loader: 'file-loader',
			options: {
				useRelativePath: true,
				publicPath: '',
				name: '[name].[ext]',
				emitFile: false,
			},
		},

		// Just emit file here, the compiled url would be overridden
		{
			loader: 'file-loader',
			options: {
				publicPath: '',
				context: resolve('src'),
				name: `[path][name].[ext]`,
			},
		},
	],
},

It is ugly, but it works

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants