source-map-loader icon indicating copy to clipboard operation
source-map-loader copied to clipboard

Double reload because sourceURL is added to webpack watched files

Open vespakoen opened this issue 5 years ago • 17 comments

  • 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 =)

vespakoen avatar Jan 04 '21 10:01 vespakoen

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

alexander-akait avatar Jan 04 '21 13:01 alexander-akait

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.

vespakoen avatar Jan 05 '21 11:01 vespakoen

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?

alexander-akait avatar Jan 05 '21 12:01 alexander-akait

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...

vespakoen avatar Jan 05 '21 12:01 vespakoen

Why do not use:

watchOptions: {
    ignored: [path.resolve(__dirname, './build')]
}

In this case?

alexander-akait avatar Jan 05 '21 12:01 alexander-akait

Or you can ignore ts files, because they compiled by ts, not webpack:

 watchOptions: {
    ignored: [path.posix.resolve(__dirname, './src/**/*.tsx')]
  }

alexander-akait avatar Jan 05 '21 12:01 alexander-akait

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

alexander-akait avatar Jan 05 '21 12:01 alexander-akait

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 avatar Jan 19 '21 16:01 MangelMaxime

@MangelMaxime Should work, can you provide repo/example?

alexander-akait avatar Jan 19 '21 16:01 alexander-akait

@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 avatar Jan 19 '21 17:01 MangelMaxime

@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 of path.resolve(). For join too

alexander-akait avatar Jan 21 '21 13:01 alexander-akait

haxe/**/*.hx is /^haxe\/((?:[^/]*(?:\/|$))*)([^/]*)\.hx(?:$|\/)/ regexp ./haxe/**/*.hx is /^\.\/haxe\/((?:[^/]*(?:\/|$))*)([^/]*)\.hx(?:$|\/)/ regexp

maybe we need doc it

alexander-akait avatar Jan 21 '21 13:01 alexander-akait

or you can use **/haxe/**/*.hx, because it is glob and we pass absolute paths here

alexander-akait avatar Jan 21 '21 13:01 alexander-akait

~~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 avatar Jan 21 '21 13:01 alexander-akait

@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

MangelMaxime avatar Jan 21 '21 14:01 MangelMaxime

I think we need document it here

alexander-akait avatar Jan 21 '21 15:01 alexander-akait

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.

davidclark87 avatar Sep 03 '21 22:09 davidclark87