Double reload because sourceURL is added to webpack watched files
- Operating System: macOS
- Node Version: any
- NPM Version: any
- webpack Version: 5.11.1
- source-map-loader Version: 2.0.0
Expected Behavior
Source files not added to webpack's dependencies
Actual Behavior
Source files are added
My question
I am using react-refresh and HMR and noticed that my code reloads twice, I am using typescript seperately from webpack, and use tsc --watch in the background which compiles typescript to JS (and also generated the sourcemaps).
In another process, I have a very simple webpack config with a react refresh plugin and source-map-loader with the entry point pointing to the (typescript) compiled index.js file.
Now, I found that source-map-loader adds the source files (e.g. .tsx and .ts files) to webpack's dependencies (and thus they are watched as well). Now, when I change a source file, webpack watch triggers, and when the typescript compiler finishes, webpack is triggered again because the compiled file is (naturally) in webpacks dependencies as well.
I wonder what can be done to improve this situation, perhaps we should add an option to this plugin to not add the source files as a dependency? I also wonder what the actual use case of adding the sourceURL as a dependency is.
Hope anyone can show me the light =)
Something wrong with pipeline, I can't answer, because i don't know it, no new options, this loader will be part of core and adding sourceURL will be by default, otherwise recompiling source maps will not run webpack compilations, what will be wrong, unfortunately, you most likely have to present a complex configuration, otherwise I cannot help, sorry
I uploaded an example repository over here:
https://github.com/vespakoen/webpack-sourcemap-loader-issue-repo
To test it out, install yarn, and run:
yarn
yarn start
Then visit http://localhost:8080 and change the "Hello" string in src/App.tsx to something else, it will reload twice since webpack is watching for src/App.tsx (added by source-map-loader) and build/App.js.
I understand that the "normal usage" is using ts-loader or similar tools, but since I have had a lot of trouble with them, and would like to keep my setup as simple as possible, I would like to not use those tools, however, the double reload is a bit annoying, and I still wonder why source-map-loader has to add the sourceURL to the webpack compilation, since when using ts-loader / a "normal setup", those source files should already be in webpacks compilation dependencies. Also, when changing a source file in a dependency, I don't think webpack should be aware of it, since the compilation should only use the compiled file.
I guess I would just like to understand why the sourceURL is added to webpack, because I think it is not needed.
I guess I would just like to understand why the sourceURL is added to webpack, because I think it is not needed.
What about if you don't use ts-loader or other tools?
That actually IS the use case right here, I am only using the source-map-loader and webpack is only used for bundling the already compiled by typescript files. however, the source map loader adds the typescript source files to the webpack watch process (which I dont want webpack to be aware of) causing a double reload.
Hope this makes sense...
Why do not use:
watchOptions: {
ignored: [path.resolve(__dirname, './build')]
}
In this case?
Or you can ignore ts files, because they compiled by ts, not webpack:
watchOptions: {
ignored: [path.posix.resolve(__dirname, './src/**/*.tsx')]
}
source-map-loader should always add sourceURL and sources in dependencies, other solution setup to ts compiler using data: URL, so nothing will be in dependencies
Hello @alexander-akait,
I am facing a similar issue because I am using Haxe to transpile to JavaScript.
I tried adding the directory with the source code to the ignored list as you proposed. However, Webpack still detects changes on the files under the src directory.
@MangelMaxime Should work, can you provide repo/example?
@alexander-akait
Sure, I made a reproduction available here: https://github.com/MangelMaxime/SourceMapLoaderProblemReproductionHaxe
The instruction are in the README. If you need more information don't hesitate :)
@MangelMaxime simple:
watchOptions: {
ignored: [
path.posix.resolve(__dirname, './haxe/**/*.hx')
]
},
if you want to construct a glob pattern from path components, you need to use
path.posix.resolve()instead ofpath.resolve(). Forjointoo
haxe/**/*.hx is /^haxe\/((?:[^/]*(?:\/|$))*)([^/]*)\.hx(?:$|\/)/ regexp
./haxe/**/*.hx is /^\.\/haxe\/((?:[^/]*(?:\/|$))*)([^/]*)\.hx(?:$|\/)/ regexp
maybe we need doc it
or you can use **/haxe/**/*.hx, because it is glob and we pass absolute paths here
~~But I think we should respect context (in your case it is process.cwd()) and ignored, I am investigating~~ Unfortunately, this is not entirely possible, because files can be out of context and it will problem with configuration of globs... Right now you can use path.posix.resolve/path.posix.join or **/haxe or **/haxe**/**/*.hx
https://github.com/webpack/webpack.js.org/issues/4463
@alexander-akait Thank you for your help **/haxe/**/*.hx works and when tested I missed the fact that you used path.posix.resolve and not path.resolve
I think we need document it here
I hit the same issue as @vespakoen described. My app imports some JS files which have sourcemaps referencing TS files. When using source-map-loader, webpack watches the *.ts files and recompiles if I modify them. Setting watchOptions.ignored is a good workaround. But it seems odd to me that webpack is trying to watch the TS files in the first place - those TS files are not being imported anywhere in the app, so I would not expect webpack to recompile when they change. I'd expect it only to recompile if the JS file changes.