-
-
Notifications
You must be signed in to change notification settings - Fork 431
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
Apply other loaders when updating files in watch mode #1115
Conversation
I need help... 😢 One test failed in Travis CI + Node.js v10 + TypeScript v3.8.2, while all tests passed in Travis CI + Node.js v12 + TypeScript v3.8.2 and AppVeyor + Node.js v10 + TypeScript 3.8.2. The first comparison test with
I don't understand why |
Comparison tests are somewhat flaky - requeued |
Thanks for the PR! We really appreciate your time. I can see this adds a dependency to https://github.com/webpack/loader-runner#readme I don't know much about Can you provide some details about what loader-runner does, and some details around whether you believe it has a bright future? I ask as webpack 5 is on the horizon and I am curious as to whether loader-runner remains relevant. I have looked at the loader-runner repo but there aren't tons of docs. You may want to reach out to @sokra and see if he can advise. |
Thank you @johnnyreilly ! All tests have passed.
It applies webpack loaders to a resource and returns a result. webpack uses it internally to apply loaders (lib/NormalModule.js@4.43.0). So it is the best way to run loaders in the same manner as webpack. I think it has a good future. webpack v5.0.0-beta.16 also depends on loader-runner (lib/NormalModule.js@5.0.0-beta.16). Changelog of webpack 5 explicitly says loader-runner was upgraded (link). We can expect it to be used by upcoming webpack 5. |
src/watch-run.ts
Outdated
.slice(loaderIndex + 1) | ||
.map(l => ({ loader: l.path, options: l.options })), | ||
context: {}, | ||
readResource: fs.readFile.bind(fs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this will create a new instance of readFile
each time updateFile
runs. Would it be more performant to create this once and reuse it? In fact is the bind
necessary at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be a bit efficient to cache the result of fs.readFile.bind(fs)
as you say.
I think bind
is necessary, because there is no guarantee that fs.readFile
does not use this
internally.
... In the first place, readResource
is not necessary, because it is optional and defaulted to readFile
. As @types/loader-runner does not mark it as optional, I pass the default value explicitly to avoid a type error.
This may be better:
runLoaders(
{
resource: ...,
loaders: ...
} as loaderRunner.RunLoaderOption,
src/watch-run.ts
Outdated
@@ -27,7 +37,7 @@ export function makeWatchRun(instance: TSInstance) { | |||
} | |||
|
|||
lastTimes.set(filePath, date); | |||
updateFile(instance, filePath); | |||
promises.push(updateFile(instance, loader, loaderIndex, filePath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the significance of making this array of Promise
s vs just calling updateFile
there and then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runLoaders
called in updateFile
is an async function. We must wait for all of them to finish before calling callback
.
To implement waiting for multiple async functions, I think Promise.all
is a good way.
Instead of using loader-runner directly, use |
Thanks @sokra - really appreciate you advising 🌻🥰 |
@sokra However, {
test: /\.ts$/,
use: ['ts-loader', 'preprocess-ts-loader']
} I want a result of 'preprocess-ts-loader'.
I can understand it, but I expect simply running |
Put a stringify loader in front to make it valid js. JSON.parse the result. This has been done before in some css related loader. |
@sokra I really appreciate your kindness. The "stringify loader" approach is working well for my problem. |
@johnnyreilly I replaced (Please ignore the second commit, in which I tried raw-loader as a stringify loader) |
) { | ||
return new Promise<void>((resolve, reject) => { | ||
if ( | ||
loaderIndex + 1 < loader.loaders.length && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you put a comment here to clarify the purpose of the 2 code branches here please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will.
Added a comment to |
} | ||
} | ||
|
||
callback(); | ||
Promise.all(promises) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember if we've discussed this already, are there any issues with us moving to a Promise
(ie async) approach instead of the current approach? Given we're dealing with callbacks I suspect not, but I wanted to check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are no new issues introduced by the 'async' approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update the package.json
version number and add an entry to the CHANGELOG.md
please?
May I "thank myself" in the changelog?
|
That's the tradition! |
Updated |
Will ship with https://github.com/TypeStrong/ts-loader/releases/tag/v7.0.5 - thanks for your help! 🌻 |
Fix #1111
Currently watch-run does not apply loaders other than ts-loader to TypeScript files when updating them in watch mode.
This behavior may lead to complication errors when files are "preprocessed" by other loaders (e.g. ifdef-loader).