Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird source map paths when used together with css-loader #529

Closed
woldner opened this issue Jan 6, 2018 · 5 comments
Closed

Weird source map paths when used together with css-loader #529

woldner opened this issue Jan 6, 2018 · 5 comments

Comments

@woldner
Copy link

woldner commented Jan 6, 2018

Original bug report webpack-contrib/css-loader#652
(also reported here because I'm unsure where it belongs.)

Do you want to request a feature or report a bug?
Bug report

What is the current behavior?
Wrong source map/resource paths using css-loader together with sass-loader as shown below:

Examples of source map paths using the plugin
The actual app.scss path is ./src/styles/app.scss

ex1

However the source map path for the file becomes ./src/styles/src/styles/app.scss and the absolute resource path:
C:/Users/m51n/source/repos/source-map-path/src/styles/src/styles/app.scss (does not exist)

ex2

If the current behavior is a bug, please provide the steps to reproduce.
I've created a sample project here-- using the source map example from the sass-loader docs and code from the extract-text-webpack-plugin docs here

With the sample project above I used devtool: "inline-source-map".

What is the expected behavior?
Expected source map path returned by the plugin in this case would be ./src/styles/app.scss and absolute resource path as it exist on disk:
C:/Users/m51n/source/repos/source-map-path/src/styles/app.scss

Related issues for reference
#484

Please mention other relevant information such as your webpack version, Node.js version and Operating System.

webpack v3.10.0
node v9.2.0
os: windows 10

@alexander-akait
Copy link
Member

@jwldnr thanks for issue, in near future i investigate this 👍

@woldner
Copy link
Author

woldner commented Jan 6, 2018

Fantastic! thanks @evilebottnawi

@alexander-akait
Copy link
Member

@jwldnr yep, problem in css-loader, sass-loader return good source map. Close issue here.

@npetruzzelli
Copy link

npetruzzelli commented Jul 27, 2018

@evilebottnawi - I'd like to suggest reopening this issue.

I'll try to put together a pull request soon, but I think I have found the cause and the solution.

The following is the culprit:

options.sourceMap = path.join(process.cwd(), "/sass.map");

and the solution looks like this:

     if (options.sourceMap) {
         // Deliberately overriding the sourceMap option here.
-        // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
-        // In case it is a string, options.sourceMap should be a path where the source map is written.
-        // But since we're using the data option, the source map will not actually be written, but
-        // all paths in sourceMap.sources will be relative to that path.
-        // Pretty complicated... :(
+        // If it is a boolean value, force it to exist in the same directory as the code it represents.
-        options.sourceMap = path.join(process.cwd(), "/sass.map");
+        options.file = resourcePath;
+        options.sourceMap = resourcePath + '.map';
         if ("sourceMapRoot" in options === false) {
             options.sourceMapRoot = process.cwd();
         }
         if ("omitSourceMapUrl" in options === false) {
             // The source map url doesn't make sense because we don't know the output path
             // The css-loader will handle that for us
             options.omitSourceMapUrl = true;
         }
         if ("sourceMapContents" in options === false) {
             // If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
             // when exported by webpack-extract-text-plugin.
             options.sourceMapContents = true;
         }
     }

Why this works:

The highlighted line makes sass think that the sourcemap will be written to the current working directory and the css file will be written to the same directory as the .sass or .scss file.

Since this loader is not responsible for writing the file or the source map, it should not be changing the relationship between the file and the sourcemap.

options.file = resourcePath; removes the need to handle stdout in sources. While it isn't strictly needed for this issue, it does help to prevent some unexpected output in source maps. File and Data can both be used at the same time. Data is used as the content and file is used to resolve pathing.

options.sourceMap = resourcePath + '.map'; is where the magic happens. This keeps the the map file in the same directory as the sass file. This means that its relationship to sources is also the same. This could be taken a step further by changing the extension from .s[ac]ss.map to .css.map, but the important part is that it is in the same directory. Since this plugin doesn't write the source maps, its doesn't affect the filename derived by something like the ExtractTextPlugin, MiniCssExtractPlugin, or webpack.SourceMapDevToolPlugin plugins.

Sources is an array of URLs relative to the map (not the css file it represents). In this case they end up being file system paths, but discussing that falls outside the scope of this issue.

If you previously tested this on a sass file in the current working directory, then you wouldn't have seen the symptoms described by this issue, because the map file would just happen to be in the same directory as the sass file.

@npetruzzelli
Copy link

css-loader will also need some fixes, which I am nearly done with and will open a PR there as well.

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

No branches or pull requests

3 participants