How to load library source maps using webpack?
I am using create-react-app
and this is how I Fixed it (without running eject
cmd)
Note : If your app is already overriding
webpack config
usingreact-app-rewired
you can ignore first three steps.
npm i react-app-rewired -D
- This will help you to overridewebpack
configuration.package.json
- change your scripts, replacereact-scripts
withreact-app-rewired
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
}
config-overrides.js
- create this file in the parent level of the app.npm i source-map-loader -D
- To load source maps (assuming that your lib's dist has source map file). It doesn't matter which build tool(ex:Rollup
,webpack
orparcel
) you use to generatesourcemap
.Copy below code in
config-overrides.js
module.exports = {
webpack: (config, env) => {
// Load source maps in dev mode
if (env === 'development') {
config.module.rules.push({
test: /\.(js|mjs|jsx|ts|tsx)$/,
use: ['source-map-loader'],
enforce: 'pre',
});
// For `babel-loader` make sure that sourceMap is true.
config.module.rules = config.module.rules.map(rule => {
// `create-react-app` uses `babel-loader` in oneOf
if (rule.oneOf) {
rule.oneOf.map(oneOfRule => {
if (
oneOfRule.loader &&
oneOfRule.loader.indexOf('babel-loader') !== -1
) {
if (oneOfRule.hasOwnProperty('options')) {
if (oneOfRule.options.hasOwnProperty('sourceMaps')) {
// eslint-disable-next-line no-param-reassign
oneOfRule.options.sourceMaps = true;
}
}
}
});
}
return rule;
});
}
return config;
},
};
- Restart your app (if it's already running).
source files
get loaded in different locations, based on path in map file. Check all folders patiently :)
Note : 1. Your source maps get loaded in one of the folder(ex :
localhost:3000
orwebpack:///
) based on path it reads from xxx.js.map file. 2. If you are usingrollup
for your libs, please make sure you give proper path in the configuration file (output.sourcemapPathTransform ), This will help to loadsourcemaps
in the proper location.
I finally figured out my issue...
Thanks to @BinaryMuse for the tip on source-map-loader. This indeed was the right way to go, though it wasn't working for me initially.
What I eventually realized is that I need to enable the source-map-loader
for webpack in both "my-lib" and "my-ui". Without source-map-loader
in "my-lib" webpack config, the source-map-loader
inside "my-ui" errors (with a warning message sadly) because it cannot locate source maps for transitive dependencies of "my-lib". Apparently the source maps are so good that source-map-loader
is able to peek at all aspects of the dependency tree.
Also of note, I ran into an issue using source-map-loader
in conjunction with react-hot-loader
. See, react-hot-loader
does not include source maps. When source-map-loader
tries to find them (because it's just scanning everything), it cannot and aborts everything.
Ultimately, I'd like source-map-loader
to be more fault tolerant, but when set up correctly, it does work!
devtool: 'source-map',
module: {
preLoaders: [
{test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/},
{test: /\.jsx?$/, loader: 'source-map', exclude: /react-hot-loader/}
],
loaders: [
{test: /\.jsx?$/, loader: 'raect-hot!babel', exclude: /node_modules/}
]
}