Some of the canisters I create are generated dynamically, meaning that I am not creating all of them at the onset of my application running. However, I would like to have the candid type declarations available to my front-end without having to create a canister (as I am only going to then delete this canister afterwards).
The error that I currently receive when attempting to generate actor declarations without creating a canister is:
Error: Failed to determine id for canister 'test'.
Caused by: Failed to determine id for canister 'test'.
Cannot find canister id. Please issue 'dfx canister create test'.
This is because dfx generate
tries to make things easy and uses this template, using the canister name and requiring the canisterId (environment variable) in order to bake a ready-to-go actor for you on the frontend.
This comment in the sdk repo details this exact “forced creation”, saying
“This is just to display an error if trying to generate before creating the canister.”
On line 7 of the generated file, we have
// CANISTER_ID is replaced by webpack based on node environment
export const canisterId = process.env.TEST_CANISTER_ID;
and then at the end of the file we have the fully-baked actor
/**
* A ready-to-use agent for the test canister
* @type {import("@dfinity/agent").ActorSubclass<import("./test.did.js")._SERVICE>}
*/
export const test = createActor(canisterId);
I would like to be able to generate declaration files for my front-end without having deployed an actor, and hence it would be great to have a way of running dfx generate
to product an index.js file that does NOT have the lines of code mentioned above (lines 6-7) and lines (34-38) includes, thus removing the dependency on requiring the canisterId and that a canister be created for that actor.
While the aforementioned features of the generate command are great for a newcomer to the IC, they become more restrictive when building more dynamic, multi-canister applications, or even when wanting to import your application canister id(s) through a different method or environment variable.
A potential solution would be to add a flag like --headless
, that allows the developer to generate declarations for an actor (that is defined in the dfx.json
) without requiring that a canister be deployed for that actor. This would then still be backwards-compatible with the existing repositories and hello world examples.
Then I can run dfx generate --headless
(for all of my actors), or dfx generate --headless test
for one of my actors (my test actor).