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
Add an option to create context from the webpack config, i.e. via a plugin #2783
Comments
You are in luck, as there is already a plugin doing exactly this: The ContextReplacementPlugin. It allows to configure a regexp like this: new ContextReplacementPlugin(/selector/, "./folder", true, /filter/) Or it allows to set the exact mapping (webpack 2): new ContextReplacementPlugin(/selector/, "./folder", {
"./request": "./request",
"./other-request": "./new-request"
/* runtime-request: compile-time request */
}) |
I've read the docs on this plugin and I guess I am a little confused on how it actually works. What is the purpose of the System.import(/group1/); And then in the plugin, would it be setup something like this? new ContextReplacementPlugin(/group1/, "./folder", {
"/styleguide/moduleA" : "./actual/relative/path/to/moduleA",
"/other/directory/moduleB" : "./actual/different/relative/path/to/moduleB"
}) Is this correct? And I still do not understand what the "./folder" is doing haha. Thanks for your help, glad to see that this is already in webpack! |
Ok after spending some time with it I understand how your first example is working, but how would I get it to work with something like this: let path = '../../' + this.componentDetails.path + '/styleguide/' + sampleFileName;
System.import(path); Where the path info is gotten from the window, so it has basically 0 context. How to I target just that system import (so that it isn't redirecting every resolve in my app)? I figured out that using the first method, my plugin would look like this: new webpack.ContextReplacementPlugin(/selector/, "./src/app/ui_elements/mixins/", true, /^\.\/.*.sample_.*\..*ts/) And if I wanted multiple directories to resolve I would use multiple plugins with the same Thank you for your help @sokra. |
Awesome. This is really relevant question for Angular2 users with the dynamic AppModule resolver. Will need to add this to documentation for sure. Also @mover96, thank you for the thoughtful and detailed question. This really helps us solve/answer things. You deserve some 🎉 🎉 . |
I feel like what would solve my issue is the ability to use something like |
Here is an example: https://github.com/webpack/webpack/blob/master/test/configCases/context-replacement/System.import/webpack.config.js It should match the absolute path of the directory. yes it's a bit weird. We better write a new plugin for context information with a better API. |
I'm going to summarize my findings in case anyone runs into this thread, and I will also explain why the current system, even with The Goal:First let me better explain what exactly I am trying to accomplish. I have a 600 module core app, most of which are Angular 2 components. This app already takes around 90 seconds to build (even with the vendors cached with the dll plugin) so it is a medium sized app. The vast majority of components are in a folder of their own name, along with a styleguide folder. The styleguide folders contain 3 files, a sample component, and an html and scss file for the component. On the server side (.NET Core) I search the entire file tree for these styleguide folders, and put all the sample component names and paths into one big object. There are about 150 of these components (these are not including in the original 600). That object gets attached to Snippet 1 let path = '/' + this.componentDetails.path + '/styleguide/' + sampleFileName;
System.import(path).then //omitted The dynamic loading and displaying of these components is handled by an entirely separate Angular app. And since the files were on the disk and already transpiled in the same directory structure this worked perfectly. How the
|
First and foremost. I cannot thank you enough for this write-up and the time you took to explain your scenario. Not only is this an invaluable learning source for other developers, but contains some very awesome suggestions and enhancements that we can consider for webpack and Also we'd like to use this writeup for our documentation ( maybe some tweaks to cater to multiple user bases)? If you ever need help navigating the webpack source and you are wanting to contribute please let me know and I will be happy to guide you. 👏👏👏👏👏👏👏👏👏👏👏👏👏👏 |
I am glad that it is useful! Feel free to use the write up and make whatever tweaks necessary. I was onboarded to a new company 3 weeks ago, and my first task was to get their preexisiting Angular 2 app working with webpack. I've spent almost 80 hours with it now (I am somewhat new to Angular as well, which explains some of the extraneous time) but webpack is a beast to get up and running. But, every single issue I have been able to figure out up until this one since there was almost no information that I could find about it. But I have come to learn how helpful posts like these can be haha! That being said, I do feel like I have a pretty good grasp on webpack now, especially coming from an Angular 2 + some non-node backend view (which is a touch more rare than the React/node crew). And since I've had to explain a lot of my finding to my supervisor I seem to know where the common disconnects are for people. So long story short I would love to contribute to some of the documentation, because even though I've dumped hours into figuring out webpack, the end results are amazing. Our page reload speed went from 20+ seconds to 2, and the HMR is a godsend haha. So if you point me in the right direction I'll see what I can do! |
I'll ping you in the very near future. Thank you so so so so so so so so so so so so much. |
Thanks @mover96 for writing this up. I think the resolver / context system is by far one of the most interesting features of Webpack and I have also been struggling with the exact same things you described. The solution I have wandered towards involved developing my own registry of file paths, defining regex style routes, using e.g.
This allowed me to build a database of tons of React components each which have accompanying files such as stylesheets, tests, documentation, examples. So I could do something like:
or query all components by certain patterns to find out information about them
Using these types of queries, my desired goal was to be able to use webpack to be able to bundle them up for certain purposes -- whether it was to use it in production or to generate a kitchen sink gallery type page, or to find all of the existing components which lacked documentation or tests and auto-generate these files with useful content The constraints you describe above have made my attempts less than stellar. I ended up using Webpack's resolver plugins to take a require or import statement, used the request data Webpack provides, and used that to infer the intended module / file that the user was requesting and handled the resolution on my own using the metadata I gathered. I then passed webpack the absolute path and whatever loader information was required. I still have a lingering suspicion that my solution could be much much cleaner by using a context replacement plugin but after reading your write up I am not sure. In either case I would love to take another crack at it and use more of webpack's internals to do it rather than rely on my own hacky and slow version. Regardless, @TheLarkInn I would love to tag along if you ever do a walk through of Webpack's code base because I feel after this battle I could clean up a little and jump right into contributing. I'd basically trade doing a bunch of chores on Webpack for some enlightenment. @mover96 I'd love to see your project as well because it sounds very interesting BTW: An interesting project to check out is the https://github.com/yuanyan/haste-resolver-webpack-plugin This provides an experience similar to |
@datapimp I just saw this!!! Awesome. Would you also consider writing documentation for this as well? And yes, any time anywhere you let me know when you'd like to walk the webpack code. (But it may cost you some documentation 😏) |
@TheLarkInn ha man i was feeling salty for a minute! |
Sorry lots of things thrown my direction these days and no good way to see the notifications. But yes just let me know. Context and the parser are two very high priority learning topics that if documented could really be useful to the community. So the more people I can try to teach the better. |
This issue was moved to webpack/webpack.js.org#140 |
For maintainers only:
|
I'm submitting a feature request
Webpack version:
2.1.0@beta.15
Please tell us about your environment:
Windows 10
Current behavior:
When using System.import (I am using webpack 2), webpack uses its context system (https://webpack.github.io/docs/context.html) to determine the path. In my case it is impossible for me to determine the URL before runtime, as it is attached to a
Window
object by the server when it starts up. Before I switched to webpack, I was using SystemJs to import these files, and since every file was transpiled from typescript and was sitting on the disk, the system.import was fine because it would just navigate to that file on the disk. With webpack, however, it needs to know about these files before runtime so it knows what to bundle and how to set up the linking and whatever else it does.The context system exist to somewhat circumnavigate this issue, but I find it very lacking. The way it is set up is it determines what that import statement could possibly be, and imports all of them preemptively. This was an issue at first since the import statement was
System.import(path)
, so I switched that statement to provide more context for the context engine. However, I am trying to import 60-100 files this way (they are 5-10 line angular components), and the highest directory they all share isapp/
itself. They are scattered throughout the entire app, as these are all companion components that provide documentation for all of the main components. This breaks down the context system, because aside from importing absolutely everything preemptively, it has no other options.I restructured some of the app to collect these files in 4-5 folders throughout the app. Even with this, the only option webpack's context system gives is to have a System.import statement written with the appropriate context for each folder. For example:
This is a big issue because now what should be a single import statement is now 2 in the source, which would have to be wrapped in if/else statements and if anyone looked at this code would immediately think this code is extraneous and inefficient. And the other issue is I just had to change my source code to support a specific bundler which would have to be documented, and in 3 months when the next cool whatever.js comes out and we want to switch, we have code in our source that is specifically for webpack, which is not desired.
I understand this is a very complex issue, because I am asking webpack to bundle files that will not be determined until runtime, i.e. once webpack has finished bundling. However these System.import() are fully supported by the ES6 spec*, and so they will not be going away anytime soon, and especially in my codebase I expect to start seeing them more often with even more complicated/obscure paths.
*well maybe not fully I do not know the specifics of the spec (and don't exactly care to know) but they aren't going away.
Feature Request:
I would like to let webpack know about these files via a config, so that I do not have to alter my source code. If I could setup contexting via a plugin, so that webpack would know what to bundle, it could generate its map thing or whatever it does, and then associate that set of files with a specific System.import() (or maybe all of them with some option) then it could handle fairly complex pathing. Not only could you specify the exact file path, but you could also give the plugin the same context you give System.import() now and it would do what it already does and would grab all possible dependencies. Since I have these files scattered throughout my app in various folders, this kind of specificity is needed.
The text was updated successfully, but these errors were encountered: