Can a rollup plugin get access to the entire module dependency graph? - rollupjs

I've got a rollup plugin I maintain and part of what it does requires it knowing about every module in the project. I don't know of a good way to get this information though.
resolveId() won't get called if the file was already resolved by any plugin further up the chain
generateBundle() doesn't include any modules that were tree-shaken away
Is there another hook I could use to get access to the module + importer information?

Try using this.getModuleInfo(id). If you have the ids of the entry points, this will give you all imported ids and basically let you crawl the whole graph. Note that during the build phase, plugins can emit additional entry points so you might want to use the Information from generateBundle as a starting point.

Related

How can I load code from another Dart package, known only at runtime?

I am building a Dart application. It needs to load code from a third-party package, which is only known at runtime. My application needs to:
auto-discover the dependency
load a library from that dependency
interact with the dependency
Ideally, I do not want to require that my users specify the third-party dependency. The application should auto-discover the dependency.
For example, a workflow could be something like this:
User installs my app (pub global activate my_app)
User installs a "plugin" (pub global activate plugin_for_my_app)
User runs my app (my_app)
The app auto-discovers that plugin_for_my_app exists.
The app loads the plugin (via spawnUri perhaps?)
The app calls into the plugin
Requirements:
Must run from the command-line.
Must work on Windows, Mac, Linux.
Should (but doesn't have to) run when compiled to JavaScript.
pub run support is optional (pub run makes it tricky, because it rewrites your import URIs, so it's not a requirement)
What's the best way to do this?
This package https://pub.dartlang.org/packages/plugins seems to do exactly what you want (haven't used it myself yet though) by loading plugins into isolates.
This is not directly answering the question (CL tools as requested), but I use plugins in the browser and wanted to share my "pattern".
My web application imports includes.dart which is a dynamically generated file that imports all .dart files found in a specified directory. The file gets (re-)generated at app startup by the backend, just before serving the files to the browser. The found .dart files implement a public api (eg. init() and run()) so that the main application can call their code. The plugin code are not loaded into separate isolates but are executed in the same isolate as the main app which gives the benefit of plugins sharing the same heap and you're able to access the plugin code directly. This solution also assumes the plugins resolve their own dependencies.
This setup works fairly well for my use case. However, as there's no real dynamic code reloading in Dart (yet, I hope. see https://code.google.com/p/dart/issues/detail?id=10530), there's always a refresh step needed to load the new code.
In the plugins package, currently, there is no way to resolve dependencies through pub. When I originally designed the API it was assumed that the dependencies were already retrieved through pub get. With that said, plugin discovery on the file system is simple.
As you can see in the example in the README, loading plugins was as simple as new PluginManager().loadAll(String directory) which would automatically discover all plugins inside the directory and load them. This solution is ideal if all plugins are to be in one folder.
It is possible to do individual plugin directory loading as well, provided it follows the plugin directory structure. Using a PluginLoader you can load in a directory that contains the necessary files for a plugin to run properly. It is not necessary to call load() since the PluginManager will take care of calling in load for you.
A simplified way of loading a plugin
Instantiate the PluginManager.
PluginManager pm = new PluginManager();
Determine the plugin you want loaded. The plugins library will automatically
determine the pub cache directory. As per the documentation of pub, the PUB_CACHE environment variable is also supported.
Load in the plugin. A Future is returned with a Plugin object that provides basic information about the plugin. The plugin requires a pubspec.yaml with a name, a packages directory, and a bin/main.dart source file. However we are loading from the pub cache, so we do not need to worry about the setup of the plugin, the only requirement is the package from the pub cache supports the plugins package.
pm.loadFromCache("test-1.0.0").then((Plugin plugin) {
print("Plugin loaded!");
handle();
});
After all the plugins you desire to be loaded are initialized, the manager can now listen for requests properly. Simply use the listener to 'see' the incoming data.
The plugin side
The plugin simply uses a receiver as provided by the plugins API.
void main(List<String> args, SendPort port) {
Receiver rec = new Receiver(port);
rec.listen((Map<dynamic, dynamic> data) {
print("Received data: $data");
});
}
I wrapped the plugins package with a bit of sugar to provide some extra things like declarative RPC. It's very flexible, and samrg472 (the author of plugins.dart) is a good friend, so I have asked him to comment as well.
https://github.com/PolymorphicBot/PolymorphicBot/blob/master/lib/src/core/plugins/handler.dart

Grails migration issues. DBM-UPDATE include not recursing, fails silently

This is part of an ongoing project... splitting out domain objects so they can be consumed by multiple applications. The database migration files for the domain objects live with the plugin... but we want the apps to be able to reference them during a dbm-update.
I can get the application to recognize the plugin changelog, but after that, the changelog does not perform includes and process them as I expect.
Using GrailsPluginUtils I am able to get the path of the plugin and the plugin changelog, with which I do an include file. If I put the changeSet right in that file I am good, it runs. If I move it to a separate file in the same folder, or in a sub-folder, and reference it via "./someFile.groovy" it seems to FIND it but does not process it. I say it seems to find it because if I do NOT use a relative file path, the migration process throws an error saying it cannot find the file e.g., "someFile.groovy"...
I have workarounds but they are not acceptable because we want to control the order of how the DB migrations occur by using sub-directors with a _changelog.groovy that then includes the actual transformations (changeSets). But they are not being "include"ed.
If I use includeAll, it will grab any and all scripts in that one folder, but again, does not process any other includes referenced therein. I can write a script to scan the folders recursively but again, that requires a lot of coding to parse the _changelogs and grab the appropriate inclusion order, etc.
I really just want "include file:" to work as it does in a given application for its own changelog files.
Has anyone else done this? Am I missing something terribly obvious?
In the app...
databaseChangeLog {
...
include file: "${GrailsPluginUtils.pluginInfos.find { it.name == 'my-plugin' }.pluginDir}/grails-app/migrations/my_plugin_changes"
}
... in the plugin...
databaseChangeLog {
include file: "./someChangeLogChangeSet.groovy"
}
Thank you...
We had also tried adding changelog files to the plugin where our domains live but were unable to access it from the main app. However, if you want to access your files from other location then you could specify this property in your config file and give the folder name here Or even copy all the migrations to the appropriate location to the main app.
grails.plugin.databasemigration.changelogLocation = 'migrations'
If you do find a actual solution to this, please post it.

Check for a file existence in WIX SEtup

I am creating a Setup for my .Net Application using WIX.
I want to check the existence of a file before installing my WIX SET UP as a Dependency.
If that file not exist then a message should be displayed.
Any help would be appreciated.
To check for the existence of a file you can use the FileSearch-element in combination with the DirectorySearch-element. For an example you can take a look at How To: Check the Version Number of a File During Installation (you don't have to use the version part for your needs).
For displaying the dialog you can create your own SpawnDialog like described here. Another alternative would be to add the text as property to the Welcome-dialog and set the property based on your findings. Still another way would be to include a second Welcome-dialog and then invoke the needed one as described in this stackoverflow-question.

Loading Angular.dart modules?

I'm confused about loading modules in Angular.dart ... (I hope).
So for angular.dart.ui let's say...I found myself putting in my main application under my main app module, type(Modal); ... but that wasn't enough apparently and I had to also add the import to the packages "timeout" and add type(Timeout); as well.
Do I need to keep adding type() all over the place and tracing back through someone else's code all the other dependencies they use??
Or should it just load all those when I inject, in this case, Modal?
I must be missing something here because adding the package you want and then testing in the browser and watching for "No provider" errors and adding all other dependencies one by one sounds like it slows down development, but I imagine the entire point of DI is to speed it up.
In you main you simply do
install(new ModalModule());
instead of
type(Modal) // old syntax
//...
bind(Modal) // new syntax
ModalModule is then installed as submodule which contains
TimeoutModule (which itself may contain some types)
ModalWindow and
Modal.
If you take a look at the source you will see that this way all you need is automatically registered for you.

Why is WSCript object not known to my script that's controlled by a custom IScriptControl?

I am using someone else's library that provides its own scripting host instance, it appears.
This lib provides me with functions to define the type of scripting language such as "jscript" and "vbscript", and I can supply it with script code and have that executed, with passing arguments in and back. So, basically, it works.
However, when I try to access the "WScript" object, I get an exception saying that this keyword is undefined.
The developer, not knowing much about this either (he only made this lib for me because I do not want to deal with Windows SDKs right now), told me that he is using "IScriptControl" for this.
Oh, and the lib also provides flags to allow "only safe subset" and "allow UI", which I set to false and true, respectively.
Does that ring a bell with anyone? Do a user of IScriptControl have to take extra steps in order to make a WScript object available? Or, can he use IScriptControl in a way that this is supplied automatically, just as when running the same script from wscript.exe?
Basically, all I need is the WScript.CreateObject function in order to access another app's API via COM.
I don't know why WScript is not known, but I suspect it is because the script host doesn't provide it. Maybe only wscript.exe does this.
If you are using Javascript, to create an object you can use new ActiveXObject(). If you are using VBScript, you can just use CreateObject.
See this article for some background.

Resources