Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.
This repository was archived by the owner on May 29, 2019. It is now read-only.

publicPath parameter doesn't work? #246

Closed

Description

@yugasun

When I use extract-text-webpack-plugin output css file into a folder, the image url is wrong, my webpack config is below:

"use strict";
var path = require('path');
var webpack = require('webpack');

// webpack plugins
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');


module.exports = {
    entry: path.resolve(__dirname, 'app/scripts/main.js'),
    output: {
        path: path.resolve(__dirname, "build"),
        //publicPath: path.resolve(__dirname, "build"),
        filename: 'js/[name]-[hash].js'
    },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,   
                loader: 'babel',    
                exclude: /(node_modules|bower_components)/,
                query: {
                    presets: ['react', 'es2015']
                }
            },
            {
                test: /\.scss$/,
                exclude: /(node_modules|bower_components)/,
                loader: ExtractTextPlugin.extract('style', 'css!sass!postcss')
            },
            {
                test: /\.css$/,
                exclude: /(node_modules|bower_components)/,
                loader: ExtractTextPlugin.extract('style', 'css!postcss')
            },
            {
                test: /\.(woff|woff2|svg|eot|ttf)/,
                loader: 'url?prefix=font/&limit=10000'
            },
            {
                test: /\.(png|jpe?g|gif|svg)$/,
                loaders: [
                    'file?name=images/[name].[ext]',
                    //'image-webpack'
                ]
            }
        ]
    },

    // image handle
    //imageWebpackLoader: {
    //    progressive: true,
    //    optimizationLevel: 3,
    //    interlaced: false,
    //    pngquant: {quality: "65-70", speed: 4}
    //},

    postcss: [
        require('autoprefixer')
    ],

    plugins: [
        new webpack.BannerPlugin('This file is created by yugasun'),
        new HtmlWebpackPlugin({
            title: 'RedChild',
            template: __dirname + '/app/template/index.tmpl.html'
        }),
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin(),
        new ExtractTextPlugin('css/[name]-[hash].css')
    ]
};

my output 'build' folder tree like this:

.
├── css
│   └── main-72c33a6c0ad73a5a0403.css
├── images
│   ├── arrow.png
|   |.....
│   └── wrong_title.png
├── index.html
└── js
    └── main-72c33a6c0ad73a5a0403.js

But in my output css file the image url is 'images/arrow.png', what I want is like '../images/arrow.png'.

Then I add the extract-text-webpack-plugin options like below:

Change:

new ExtractTextPlugin('css/[name]-[hash].css')

To:

new ExtractTextPlugin('css/[name]-[hash].css', {
            publicPath: '../'
        })

But the parameter 'publicPath' doesn't work, in my output css file the image url is still 'images/arrow.png'.

My package.json is like bellow:

{
  "name": "h5-webpack-template",
  "version": "1.0.0",
  "description": "H5 Develop template.",
  "main": "bundle.js",
  "scripts": {
    "dev": "webpack-dev-server --progress --colors --content-base build --port 8014 --host 0.0.0.0",
    "build": "NODE_ENV=production webpack --config ./webpack.production.js --progress"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/yugasun/H5%2Bwebpack.git"
  },
  "keywords": [
    "webpack",
    "ES6",
    "HTML5"
  ],
  "author": "yugasun",
  "license": "MIT",
  "devDependencies": {
    "autoprefixer": "^6.4.0",
    "babel-core": "^6.13.2",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-react": "^6.11.1",
    "clean-webpack-plugin": "^0.1.10",
    "css-loader": "^0.21.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.5",
    "html-webpack-plugin": "^2.22.0",
    "image-webpack-loader": "^2.0.0",
    "imagemin-webpack-plugin": "^1.0.8",
    "node-sass": "^3.4.2",
    "normalize.css": "^4.2.0",
    "postcss-loader": "^0.9.1",
    "sass-loader": "^3.1.2",
    "style-loader": "^0.13.0",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.15.2",
    "webpack-spritesmith": "^0.2.6"
  },
  "bugs": {
    "url": "https://github.com/yugasun/H5%2Bwebpack/issues"
  },
  "homepage": "https://github.com/yugasun/H5%2Bwebpack#readme",
  "dependencies": {
    "weui": "^0.4.3"
  }
}

Activity

  1. heylookltsme commented on Sep 22, 2016

    @heylookltsme

    I'm running into this same issue.

  2. toomuchdesign commented on Sep 23, 2016

    @toomuchdesign

    Think you should set the overriding publicPath directly into the extracting loader, like:

    loader: ExtractTextPlugin.extract('style',['css'],{publicPath:'./fonts/'})

    See: #212

  3. nblackburn commented on Oct 16, 2016

    @nblackburn

    Tried numerous configurations, none of which work.

    At this point, i am reasonably confident it doesn't do anything.

  4. adamgotterer commented on Nov 11, 2016

    @adamgotterer

    I've played with the config and tens of combinations for hours without even a hint of it doing anything. Any work arounds?

  5. heylookltsme commented on Nov 11, 2016

    @heylookltsme

    I ended up using a textTransformLoader and fixed the urls myself with a regex. Seems totally unnecessary, but whaddya gonna do. ¯_(ツ)_/¯

  6. heylookltsme commented on Nov 11, 2016

    @heylookltsme

    Here's some code in case it's helpful:

    textTransformLoader: {
        fixPaths: {
            transformText: function(content) {
                // Internal production builds (gh-pages for internal repo) require a
                // path prefix for all urls.
                if (flags.production && flags.internal) {
                    content = content.replace(/(url\(\\?['"])(\/.+?\))/g, '$1/' + config.internalPathPrefix + '$2');
                }
    
                return content;
            },
        },
    },
  7. githoniel commented on Dec 9, 2016

    @githoniel

    @heylookltsme i have met the same problem, could you expain how you config textTransformLoader?
    tried for a long time , but none of which work.

  8. heylookltsme commented on Dec 9, 2016

    @heylookltsme

    Ah, sure thing. Yeah, there's a missing puzzle piece here. I'm using it with the ExtractTextPlugin.

    So the relevant portions of the config look like this:

            module: {
                loaders: [
                    {
                        test: /\.scss$/,
                        loader: ExtractTextPlugin.extract(
                            flags.production ? 'style' : 'style?sourceMap',
                            flags.production ?
                                'text-transform?pack=fixPaths!css!postcss!sass' :
                                'text-transform?pack=fixPaths!css?sourceMap!postcss!sass?sourceMap'
                        ),
                    },
                ],
            },
            textTransformLoader: {
                fixPaths: {
                    transformText: function(content) {
                        // Internal production builds (gh-pages for internal repo) require a
                        // path prefix for all urls.
                        if (flags.production && flags.internal) {
                            content = content.replace(/(url\(\\?['"])(\/.+?\))/g, '$1/' + config.internalPathPrefix + '$2');
                        }
    
                        return content;
                    },
                },
            },
            plugins: [
                new ExtractTextPlugin('index.css', {
                    allChunks: true,
                }),
            ],

    Notice the fixPaths reference in the ExtractTextPlugin config for .scss files. That's the delicate, hidden thread tying it all together.

    I hope that's helpful! Let me know if you're still having trouble.

  9. githoniel commented on Dec 11, 2016

    @githoniel

    @heylookltsme thank you very much and it works perfect~~~

  10. yugasun commented on Dec 14, 2016

    @yugasun
    Author

    @heylookltsme thank you very much, I have solve the problem by redefine publicPath for file-loader, as below config:

    module: {
         loaders: [
                {
                    test: /\.(png|jpe?g|gif)$/,
                    loader: 'file',
                    query: {
                        limit: 8192,
                        name: 'img/[name].[ext]',
                        publicPath: '/build/'
                    }
                },
          ]
    },
    ...
    plugins: [
            ...
            new ExtractTextPlugin('css/[name]-[hash].css'),
            
    ],
                
    

    PS: Maybe this bug has been fixed by the PR #305

  11. bebraw commented on Feb 19, 2017

    @bebraw
    Contributor

    Can you confirm this against webpack 2?

  12. yugasun commented on Feb 21, 2017

    @yugasun
    Author

    @bebraw I haven't use webpack 2, the config is for webpack 1.14.

  13. bebraw commented on Feb 21, 2017

    @bebraw
    Contributor

    Ok. Note that you can set publicPath at extract-text-plugin itself. That will likely fix your issue.

    If you can confirm it's broken with webpack 2, please re-open.

  14. a1isaeed commented on Jun 12, 2017

    @a1isaeed

    my config that worked looks like this:

        rules: [
          // Extract all .global.css to style.css as is
          {
            test: /\.global\.css$/,
            use: ExtractTextPlugin.extract({
              use: 'css-loader',
              fallback: 'style-loader',
              publicPath: './',
            })
          },
          // Pipe other styles through css modules and append to style.css
          {
            test: /^((?!\.global).)*\.css$/,
            use: ExtractTextPlugin.extract({
              use: {
                loader: 'css-loader',
                options: {
                  modules: true,
                  importLoaders: 1,
                  localIdentName: '[name]__[local]__[hash:base64:5]',
                }
              },
              publicPath: './',
            }),
          },
          // Add SASS support  - compile all .global.scss files and pipe it to style.css
          {
            test: /\.global\.scss$/,
            use: ExtractTextPlugin.extract({
              use: [
                {
                  loader: 'css-loader'
                },
                {
                  loader: 'sass-loader'
                }
              ],
              fallback: 'style-loader',
              publicPath: './',
            })
          },
    
    
  15. bobrosoft commented on Jun 14, 2017

    @bobrosoft

    Solved similar problem just by disabling of url(...) processing in css-loader by setting url option to false.

    {loader: 'css-loader', options: {url: false}}
    

    Before I had issue during SCSS compilation when writing background: url('assets/... so needed to write background: url('/assets/... which is not working for non-root baseUrl (tried all publicPath stuff I can find). Now I can use relative url('assets/... paths in CSS.

  16. leebenson commented on Oct 18, 2017

    @leebenson

    I'm having a similar problem to the one that originally started this thread. Here's my folder structure:

    ├── assets
    │   ├── css
    │   │   ├── style.css
    │   │   └── style.css.map
    │   └── fonts
    │       └── barbershop.8791f5128e84171e9aa3543f533db26b.ttf
    
    

    What I'd like to happen is that all calls inside of assets/css/style.css will load paths relative to assets/css. So for example, to load the hashed Barbershop font file, I'd expect to see:

    url(../fonts/barbershop.8791f5128e84171e9aa3543f533db26b.ttf);
    

    Instead, by default, I'm seeing:

    url(assets/fonts/barbershop.8791f5128e84171e9aa3543f533db26b.ttf);
    

    ... which then means the browser is looking for assets/css/assets/fonts/..., which is clearly wrong.

    The obvious answer is just to set publicPath: '/', so that it's always pulling from the root. However, I'm using this in a framework where users can mount the app at any point, so I want to keep paths relatively to the CSS file, and not to the web root.

    The closest I've been able to get to solving it is setting to publicPath: '../../', which yields:

    url(../../assets/fonts/barbershop.8791f5128e84171e9aa3543f533db26b.ttf)
    

    ... and works well. But - those unnecessary ../../assets bytes are bugging me, when I should be able to just replace those with ../.

    The text-transform-loader seems like the perfect solution to the above, but in Webpack 3 and with the current version of Extract Text Plugin, putting them at the front of my loaders yields a content block that looks like the following (instead of the expected final output):

    exports = module.exports = require("../node_modules/css-loader/lib/css-base.js")(true);
    // imports

    // module
    exports.push([module.id, "@font-face{font-family:Barbershop;src:url(" + require("./barbershop.ttf") + ") format("truetype")}html{font-family:Barbershop}", "", {"version":3,"sources":["/Users/leebenson/dev/sandbox/reactql-fonts/styles.global.css"],"names":[],"mappings":"AAAA,WACE,uBAA0B,oDACoB,CAC/C,KAGC,sBAAwB,CACzB","file":"styles.global.css","sourcesContent":["@font-face {\n font-family: "Barbershop";\n src: url("barbershop.ttf") format('truetype');\n}\n\nhtml {\n font-family: Barbershop;\n}\n"],"sourceRoot":""}]);

    // exports

    Does anyone know of either:

    a) A way to have Extract Text Plugin compare the current output path with the url() block, and call a file relatively

    or (probably more likely):

    b) Get text-transform-plugin working with the latest version of both Extract and Webpack 3, to modify the final output instead of the garble above.

    Any pointers would be appreciated. And sorry for digging up a closed/old issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions