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
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. Additionallywebpack://is added a second time within theSourceMapDevToolPluginwhen the file names are generated usingModuleFilenameHelpers. This finally results in this file path for the css file:'webpack:///webpack:///components/Test.css'See this simple Example:
with
Test.js:and
app.js:and
webpack.config.js:If you skip into the source map creation you can see that
moduleFileNamesinSourceMapDevToolPluginis correct for the JS files:However, if you look at the
moduleFileNamesfor the source map from the CSS Loader you get: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
sourceRootproperty.This could be easily changed in the loader. Just return the absolute path and don't pass a
sourceRootproperty.By doing this
moduleFileNamesnow contains the correct path.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