-
Notifications
You must be signed in to change notification settings - Fork 51
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
Doesn't seem to work with Webpack 4 #9
Comments
According to this resolver plugins should be compatible:
I have not tried it myself yet. I'll in look into it and see what is going on. |
I made a webpack4 branch here: https://github.com/dividab/tsconfig-paths-webpack-plugin/tree/webpack4 In this branch I updated the included example to webpack 4. It seems to work (webpack emits some warnings but it still runs). You can clone this branch and try it with @bushmango Perhaps you can post a more detailed description of the problems you are experiencing? |
hello, some webpack 4 / webpack-dev-server 3.1 feedback adapted your example from the webpack4 branch webpack 4.0.1,
|
Installing the webpack4 branch locally and looking through the example I was able to get it working, thanks! My actual issue is I accidentally had the resolve section in the webpack config twice, sorry! |
webpack: 4.1.0
|
@firsttris @yujiaze Thanks for posting the errors. I upgraded the webpack 4 branch to 4.1.0 but I did not get the error you got. Although, it seems likely your errors are related to this plugin because it uses the described-resolve hook. I'm not sure why you get the error and I don't. Could you perhaps try to clone the webpack4 branch in this repo and check if that works for you? If it does, check what is different between that config and yours. Or you can post your full config and I'll try to reproduce using that. |
same issue in my project after I tried to use webpack@4.1.1
|
@TatsuUkraine Could you compare your config to the working webpack 4 example from this repo? Or provide a reporudction config? To run the working example, clone this repo, then
|
@jonaskello it will be quite hard to provide my full webpack config, since I have dynamic configuration build. But here is how I register your plugin in my config client build:
server build
|
@TatsuUkraine Thanks! Since the minimal example that I have is working I cannot troubleshoot from that. So I'm trying to get to a minimal reproduction config. You don't have to provide the full config. A small (but runnable) config with just enough to reproduce the error you are getting would be perfect. So if you could make a small config where you bascially strip everything but the tsconfig-plugin, and you still get the error that would be very helpful. Did the example in this repo's webpack4 branch work for you? |
Btw, I think CommonsChunkPlugin should not be used in webpack4? See here for more info. |
Hello, I found this issue while I was running into the same sorts of issues during my Webpack 4 upgrade/usage. Just like many of the above reporters I also had the same issue where Webpack 4 was crashing with After an afternoon of digging I eventually came up with 2 observations: Which plugin array you use is very importantThis also took me a while to figure out, but Webpack actually has 2 places where you can define a plugins array. The first place is the in the root object of the config, this is described here and it's where I also initially placed the usage of this plugin (and I believe everyone who is having problems are probably doing the same thing). There is however a second place where you are allowed to specify a plugins array, which is in the resolve property of the config. This scopes your plugin to run specifically during resolve. What I noticed is that if you place the plugin definition in this last type of array (the resolve one) the plugin works perfectly fine (note that I cloned the However, if your plugin was defined in the first array, the root of the config, this used to work perfectly fine, but with So the easy fix for users is to just move the plugin definition into the resolve plugins array. This solved my problems. It's also the reason your branch "just works" because your example places the plugin in this array. We can solve this and be Webpack 4 and backwards compatible.I took the some time to hack together a solution that actually makes the plugin work in both cases. I am by no means a Webpack expert, so some things might not be 100% legit, but I tested all my cases and this causes the plugin to work for I'll just paste the code in here. Please note that I didn't make the effort to refactor this properly and it really is what I described, it's a hack, it needs major clean up. export class TsconfigPathsPlugin implements ResolverPlugin {
// ...
apply(resolver: Resolver): void {
const { baseUrl } = this;
if (!baseUrl) {
// Nothing to do if there is no baseUrl
this.log.logWarning(
"Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin"
);
return;
}
// tslint:disable:no-any
// Hack starts here...
const compiler = resolver as any;
console.log("hooks ==", compiler.hooks);
console.log("describedResolve ==", compiler.hooks.describedResolve);
console.log("afterResolvers ==", compiler.hooks.afterResolvers);
// Check for Webpack 4 hooks
if (compiler.hooks) {
// afterResolvers will only exist, if the plugin was places in the root plugins
// There is no hook to describedResolve. Instead we have to first hook into afterResolvers
// When they get called, we can get back to calling the describedResolve Hook.
if (compiler.hooks.afterResolvers) {
console.log("Plugin placed in Root Plugins!");
compiler.hooks.afterResolvers.tap("TsconfigPathsPlugin", () => {
// TODO: This is ugly as hell, please refactor.
compiler.resolverFactory.hooks.resolver
.for("normal")
.tap("TsconfigPathsPlugin", (res: any) => {
const target = res.ensureHook(this.target);
res
.getHook(this.source)
.tapAsync(
"TsconfigPathsPlugin",
(request: any, _: any, callback: any) => {
const func = createPlugin(
this.matchPath,
res,
this.absoluteBaseUrl,
target,
this.extensions
);
func(request, callback);
}
);
});
});
} else {
console.log("Plugin placed in Resolve.Plugins!");
// We are in Webpack 4, and the plugin was placed in the resolve.plugin array,
// we have an instant hook to describedResolve, using the new Tapable API.
// TODO: Clean up createPluginWp4 hack.
compiler.hooks.describedResolve.tapAsync(
"TsconfigPathsPlugin",
createPluginWp4(
this.matchPath,
resolver,
this.absoluteBaseUrl,
this.target,
this.extensions
)
);
}
} else {
console.log("Legacy Webpack!");
// It's Webpack < 4.0.0, default the old plugin system.
resolver.plugin(
this.source,
createPlugin(
this.matchPath,
resolver,
this.absoluteBaseUrl,
this.target,
this.extensions
)
);
}
}
}
// tslint:disable:no-any
// This is just a copy of the old method, but it returns the Webpack 4 syntax.
// The only difference here is that the function returned has an additional parameter, which we currently don't use.
// It's their new RequestContext.
function createPluginWp4(
matchPath: TsconfigPaths.MatchPathAsync,
resolver: Resolver,
absoluteBaseUrl: string,
target: string,
extensions: ReadonlyArray<string>
): any {
const fileExistAsync = createFileExistAsync(resolver.fileSystem);
const readJsonAsync = createReadJsonAsync(resolver.fileSystem);
return (request: any, _: any, callback: any) => {
const innerRequest = getInnerRequest(resolver, request);
if (
!innerRequest ||
(innerRequest.startsWith(".") || innerRequest.startsWith(".."))
) {
return callback();
}
matchPath(
innerRequest,
readJsonAsync,
fileExistAsync,
extensions,
(err, foundMatch) => {
if (err) {
callback(err);
}
if (!foundMatch) {
return callback();
}
const newRequest = {
...request,
request: foundMatch,
path: absoluteBaseUrl
};
return resolver.doResolve(
target,
newRequest,
`Resolved request '${innerRequest}' to '${foundMatch}' using tsconfig.json paths mapping`,
createInnerCallback((err2: Error, result2: string): void => {
if (arguments.length > 0) {
console.log("here?");
return callback(err2, result2);
}
// don't allow other aliasing or raw request
callback(null, null);
}, callback)
);
}
);
};
} This still causes 2 deprecation warnings, but the plugin is 100% functional for my own project. I hope this is a good place to start @jonaskello EDIT: I've pushed the code to my own fork: https://github.com/Nayni/tsconfig-paths-webpack-plugin/blob/nayni-webpack4/src/plugin.ts EDIT2: Actually missed the use-cases in comments and swapped them around while cleaning it up. All good now! |
@Nayni Thanks, that is a great find :-). I have never tried to put resolver plugins in the regular plugins array so I would not have found that myself! I'm not sure webpack actaully supports resolver plugins in the regular plugins array. I guess it could work anyway, but if webpack does not support it, I think it may break again later and then we have more trouble. So instead maybe we could be even more clear in the readme that this is a resolver plugin and it should be in the resolver section of the config? And perhaps we can throw an error if we can detect that it is registred in the wrong section? @Nayni If you want to send a PR for your changes I would be happy to review it! |
I think the best option would be to be more clear on where this plugin is supposed to be placed. Because I still consider the code I posted above to be a hack. I guess it should be possible to check where the plugin was placed, at least in Webpack 4 this would be as easy as checking if we have resolver hooks, for Webpack 3 I have no clue though. I'm not sure if it's possible to inspect the original config in a plugin, but it would be a great help for people who are just starting with Webpack or this plugin. I'll see what I can do with my changes in terms of a PR, probably somewhere later this week. |
@jonaskello yep, you are right about chunks, I just posted my current config, since the way how I use your plugin did change) |
This is now fixed in 3.0.0 thanks to the PR by @Nayni! |
I cannot get paths to work with webpack 4. An example of it working would be nice
The text was updated successfully, but these errors were encountered: