Skip to content

Source Maps generating wrong file paths #280

Closed
@cevou

Description

@cevou

When creating source maps with the CSS loader the file paths that are generated are wrong and don't follow the format which is used for JavaScript files.

CSS Loader defines a sourceRoot (webpack://) for the source map. Additionally webpack:// is added a second time within the SourceMapDevToolPlugin when the file names are generated using ModuleFilenameHelpers. This finally results in this file path for the css file: 'webpack:///webpack:///components/Test.css'

See this simple Example:

src
-- components
-- -- Test.css
-- -- Test.js
-- app.js
webpack.config.js

with Test.js:

import React, { Component, PropTypes } from 'react';
import './Test.css';

export default class Test extends Component {
    render() {
        return (
            <div className="test"></div>
        );
    }
}

and app.js:

import React from 'react';
import { render } from 'react-dom';
import Test from './components/Test'

render(<Test />,  document.getElementById('demo'))

and webpack.config.js:

import path from 'path';
import ExtractTextPlugin from 'extract-text-webpack-plugin';

const srcPath = path.join(__dirname, 'src');
const buildPath = path.join(__dirname, 'dev');

module.exports = {
    context: srcPath,
    entry: [
        './app.js'
    ],
    output: {
        filename: '[name].bundle.js',
        chunkFilename: '[name].chunk.js',
        path: buildPath
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loaders: ['babel-loader']
            },
            {
                test: /\.css/,
                loader: ExtractTextPlugin.extract('style', ['css?sourceMap'])
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('[name].style.css')
    ],
    devtool: 'source-map'
};

If you skip into the source map creation you can see that moduleFileNames in SourceMapDevToolPlugin is correct for the JS files:

[
  'webpack:///./components/Test.js',
  'webpack:///./components/Test.css'
]

However, if you look at the moduleFileNames for the source map from the CSS Loader you get:

[
  'webpack:///webpack:///components/Test.css'
]

This is obviously wrong. I would expect the same path that was generated for the JS files.

While digging a little bit deeper into it I found out that the JS source maps that are processed always contain the absolute path to the JS file and an empty sourceRoot property.

This could be easily changed in the loader. Just return the absolute path and don't pass a sourceRoot property.

var moduleJs;
if(query.sourceMap && result.map) {
    // add a SourceMap
    map = result.map;
    if(map.sources) {
        map.sources = map.sources.map(function(source) {
            return source.split("!").pop();
        }, this);
        map.sourceRoot = "";
    }
    map.file = map.file.split("!").pop();
    map = JSON.stringify(map);
    moduleJs = "exports.push([module.id, " + cssAsString + ", \"\", " + map + "]);";
} else {
    moduleJs = "exports.push([module.id, " + cssAsString + ", \"\"]);";
}

By doing this moduleFileNames now contains the correct path.

[
  'webpack:///./components/Test.css'
]

The source maps that are generated by this change are correct and work as expected. I have not yet submitted a pull request because I first wanted to check with you if this change might have any other implications that I am not aware of.

This might also help to fix #194

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