create-react-app: create-react-app sass sourcemaps not working

Sass sourcemaps shows only on yarn build

Can we have sourcemaps enabled by default in development ! yarn start

Environment

Node: v11.1.0 yarn: v1.12.1 npm: v6.4.1 Chrome: v70

image

image

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 22
  • Comments: 56 (6 by maintainers)

Commits related to this issue

Most upvoted comments

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

You can override the configuration by installing CRACO (https://github.com/sharegate/craco) in connection with the attached config files. Please note that this will enable sourcemaps in all circumstances, also in production builds:

craco.config.js

const sassSourcemapsPlugin = require("./craco-plugin-sass-sourcemaps");

module.exports = {
    plugins: [
        { plugin: sassSourcemapsPlugin }
    ]
};

craco-plugin-sass-sourcemaps.js

module.exports = {
    overrideWebpackConfig: ({ webpackConfig, cracoConfig, pluginOptions, context: { env, paths } }) => {
        function traverse(obj, callback) {
            if (Array.isArray(obj)) {
                obj.forEach(item => traverse(item, callback));
            } else if ((typeof obj === 'object') && (obj !== null)) {
                Object.keys(obj).forEach(key=>{
                    if (obj.hasOwnProperty(key)) {
                        callback(obj, key);
                        traverse(obj[key], callback);
                    }
                })
            }
        }

        traverse(webpackConfig, (node, key) => {
            if (key === "loader") {
                if (
                    (node[key].indexOf("sass-loader") !== -1) ||
                    (node[key].indexOf("postcss-loader") !== -1) ||
                    (node[key].indexOf("css-loader") !== -1)
                ) {
                    if (node.options) {
                        node.options.sourceMap = true;
                    }
                }
            }
        })

        return webpackConfig;
    }
};

The following did work for me:

  • open node_modules\react-scripts\config\webpack.config.js
  • replace “isEnvProduction” with “isEnvDevelopment” for the css-loader, css-module loader, sass loader and sass module loader (between lines 443 - 500)
  • start development process with “npm start” grafik

A couple updates

  1. I am working with a maintainer of style-loader to get this merged very soon, and I am told that it is now prioritized.

  2. Good news; this change will incidentally reduce repaints, which should improve performance during development.

    For instance, I enabled paint flashing in order to see if there would be any impacts from switching from the Link Blob (<link href=CSSBLOB />) strategy to the Inline Style <style>CSS</style> strategy.

    When I changed the color of some text, the Link Blob strategy sometimes caused the text and any of its containers affected by the same style sheet to unnecessarily repaint. When using the Inline Style strategy, only the text was repainted, and there were no additional, unnecessary repaints. 😄

Hi all! I think I know what is going on and how to fix it.

Background

The ability to enable source maps during development was originally added in #5713 and released in v2.1.4. Unfortunately, enabling source maps during development caused a flash of unstyled content (FOUC), which was reported in #6399. To resolve that issue, support for source maps during development was removed in #6399 and released in v2.1.6.

Cause

The FOUC occured because JS rendered before CSS. JS rendered before CSS because style-loader injected <link> tags instead of <style> tags whenever source maps were enabled, and <link> tags render asynchronously when injected with JS.

Faulty Workaround

So, why ever inject <link> tags instead of <style> tags? That technique was originally used to work around a bug that preventing source maps in <style> tag from working in Chrome, but that bug was fixed in 2015.

This is why the <link> workaround was removed from style-loader in 2017, and also removed from vue-style-loader in 2016. Unfortunately, the removal never made it into the master branch of style-loader, mostly likely due to a mistake in branch management.

Solution

The solution, I hope, is to share this history with the style-loader team and submit a PR to restore the original fix.

And here it is! https://github.com/webpack-contrib/style-loader/pull/383

How are we in 2019 and there isn’t a steadfast solution to this? This is one of the staples when debugging css issues.

I think i found the issue in react-script\config\webpack-config.js Line 503,517, 532 and 549 of style-loaders options: { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, }), // Don’t consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }), }, // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the // extensions .module.scss or .module.sass { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, ‘sass-loader’ ), // Don’t consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass { test: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }, ‘sass-loader’ ), }, // “file” loader makes sure those assets get served by WebpackDevServer. // When you import an asset, you get its (virtual) filename. // In production, they would get copied to the build folder. // This loader doesn’t use a “test” so it will catch all modules // that fall through the other loaders. { loader: require.resolve(‘file-loader’), // Exclude js files to keep “css” loader working as it injects // its runtime that would otherwise be processed through “file” loader. // Also exclude html and json extensions so they get processed // by webpacks internal loaders. exclude: [/.(js|mjs|jsx|ts|tsx)$/, /.html$/, /.json$/], options: { name: ‘static/media/[name].[hash:8].[ext]’, }, },

sourcemaps never get enabled in developement environement. why **shouldUseSourceMap** variable isn’t enough for sourcemaps control? FIX: modify those lines as: sourceMap: shouldUseSourceMap just get rid of isEnvProduction.

Alternatively, you may use this script to manipulate the webpack config - doesn’t require CRACO or its huge config.

  • add this script to scripts/enable-css-sourcemaps.js
const { writeFileSync, existsSync, readFileSync } = require('fs');

const path = 'node_modules/react-scripts/config/webpack.config.js';

const find = /(sourceMap: isEnvProduction && shouldUseSourceMap)/g;
const replace = 'sourceMap: isEnvDevelopment && shouldUseSourceMap';

if (existsSync(path)) {
  const buffer = readFileSync(path)
    .toString()
    .replace(find, replace);

  try {
    writeFileSync(path, buffer);
    console.info('enable-css-sourcemaps: active');
  } catch (e) {
    console.error(`enable-css-sourcemaps: ${path} manipulation failed!`);
  }
} else {
  console.warn(`enable-css-sourcemaps: ${path} does not exist`);
}
  • add this script to your package.json scripts: "postinstall": "node ./scripts/enable-css-sourcemaps.js"

Our team is also interested by a workaround or a fix, it will be very useful !

Any Updates on this ? Is there a working workaround ?

Any official word on this? thanks!

@syden10, we have #5713 that should fix this.

Seems the PR above (https://github.com/facebook/create-react-app/pull/7114) is closed now, just posted to see if we can bring attention back to it.

After 8 months, an official word on this would be appreciated, if there is no interest in providing a fix in the short term, please make us aware.

Thank you.

Are there any updates on this? This seems to still be an issue on Chrome even with CRA 3.0.0

Do we have any updates on this?

I suspect the team isn’t moving particularly fast on this (btw team you are doing an excellent job!), because the react approach favours component level styling over a sass approach. However if sass is being support then source maps probably should be too. I’d certainly find it useful!

Any news on this?

Anybody have temporarily solution ? 😦

We merged style-loader in #7473, so I think we may be able to re-try merging #5713. Anyone interested should give it a shot.

Thanks for being patient and sorry for the slowness. Personally I’m not keen on providing a solution that would cause issues when turned on even when it’s behind a flag. People would just raise more issues against these problems. If you really need this feature you can use a third party solution like react-app-rewired.

Would love to have this functionality on a current project

It not just the sass, the css also inline the page, this is difficult to debugger. image Is there any way to link this app.css? image @bugzpodder I need help, thank you.

Would it be ok to have SCSS source maps as opt-in in dev mode via an environment-variable until #8910 is resolved? I could create a MR.

Then developers could at least chose between SCSS source maps and working JS breakpoints.

This will only be available after https://github.com/webpack/webpack/issues/8910 is resolved, please follow along there.

EDIT: This is actually a different issue (for chrome sourcemaps debugging). I’ll file another one for this later.

A workaround would be very important for us !

@hqman So, no plans on bringing back Sourcemaps in an upcoming update? Is there a workaround in the current version?

latest version can’t work , but 2.1.5 can work.

Any estimate for an official fix on this? Thanks.

Hey, seems like there hasn’t been any action on this thread in a while. I just submitted a PR with (I think) the changes discussed above #8638

@bugzpodder Can you please show an example of How to use react-app-rewired to enable sourcemaps ?

Once other problems like #6399 no longer manifests we will revisit this issue. Currently I am not aware of any upstream PRs that would fix any of these problems.

@bugzpodder Could you point to an upstream bug thats causing this? We could keep an eye on that to look for when it could be merged in. Source map support is one of those basic things that any web application development framework, plugin or tool should support. If it is not supported, it should be clearly mentioned in the README somewhere so people are sure what they’re investing their personal/company resources in and how painful it would be to work with, don’t you think?

This will be reverted because of #6399.

The following did work for me:

  • open node_modules\react-scripts\config\webpack.config.js
  • replace “isEnvProduction” with “isEnvDevelopment” for the css-loader, css-module loader, sass loader and sass module loader (between lines 443 - 500)
  • start development process with “npm start”

@agairing Those changes would be lost on every npm install so I would advice against ever editing anything inside node_modules

So to officially move this forward does someone need to make a pull request that re-applies the changes from #5713?

We’ve attempted to release this change before, it isn’t that it doesn’t work (it does), but turns out it causes other significant problems like FOUC and perf degrading. If we release the same change behind a flag, these issues will inevitably be raised again.

Jack thanks so much for the reply!

Just to clarify from your post, a fix without breaking other stuff would not be feasible? Also sorry for the ignorance, but how come it was working accordingly on older versions? Has a proper fix for this issue been considered by the team at some point at all?

Thanks again.

@ianschmitz Thanks so much for the reply!

Tried updating to 2.1.3 yesterday but still wasn’t working, would be up on next release?

@ianschmitz THANK YOU Will it be available in next release ? or is it available now !

I just saw, that there are also 2 more spots in the “webpack.config.js” configuration file where I did replace isEnvProduction with isEnvDevelopment: grafik

I tried the solution from @agairing - but the source maps all point to main.scss and not the individual scss files. So there is still something missing.

[edit] process.env.GENERATE_SOURCEMAP needed to be set to true.

@NotAmaan Right. It’s just intended as a temporary solution (if you need working source maps - like myself…).

I think i found the issue in react-script\config\webpack-config.js Line 503,517, 532 and 549 of style-loaders options: { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, }), // Don’t consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See webpack/webpack#6571 sideEffects: true, }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }), }, // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the // extensions .module.scss or .module.sass { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, ‘sass-loader’ ), // Don’t consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See webpack/webpack#6571 sideEffects: true, }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass { test: sassModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }, ‘sass-loader’ ), }, // “file” loader makes sure those assets get served by WebpackDevServer. // When you import an asset, you get its (virtual) filename. // In production, they would get copied to the build folder. // This loader doesn’t use a “test” so it will catch all modules // that fall through the other loaders. { loader: require.resolve(‘file-loader’), // Exclude js files to keep “css” loader working as it injects // its runtime that would otherwise be processed through “file” loader. // Also exclude html and json extensions so they get processed // by webpacks internal loaders. exclude: [/.(js|mjs|jsx|ts|tsx)$/, /.html$/, /.json$/], options: { name: ‘static/media/[name].[hash:8].[ext]’, }, },

sourcemaps never get enabled in developement environement. why **shouldUseSourceMap** variable isn’t enough for sourcemaps control? FIX: modify those lines as: sourceMap: shouldUseSourceMap just get rid of isEnvProduction.

This fixed it for me for the moment. How can i avoid this problem in future projects?

@PsiRadish No, you’re fine, just validate that the issue that caused it to be reverted is actually fixed! I’ll commit to reviewing 😃

@zhuoli99 Would you consider resending your PR to fix this issue? Can be quite a pain for quite a lot of people.

@jonathantneal that’s awesome! Appreciate your effort here and hopefully we can find a resolution for this soon!

Please follow #5713 for updates.