twig.js: Includes in Twig files throwing errors
I’m using Twig.js in Storybook and at first it seemed to be working fine… until I tried to do an include in a twig file. I can’t get it to work no matter what I try, and it’s always throwing console errors related to fs and path.
For context, I’m using:
- Twigjs 1.15.4
- Storybook 6.5.9
- Vue 3
- Vite (instead of Webpack)
- vite-plugin-twig-loader
- Node 16.13.0
I’ve put together a very basic test, based on what’s on the Twig.js Readme (note that test.twig is in the same folder as the test script):
import Twig from 'twig';
const test1 = Twig.twig({
data: 'The {{ baked_good }} is a lie.',
}).render({ baked_good: 'cupcake' });
const test2 = Twig.twig({
data: "The {{ baked_good }} is a lie. {% include 'test.twig' %}",
allowInlineIncludes: true,
}).render({ baked_good: 'cupcake' });
console.log(test1, test2);
The first test works just fine, outputting “The cupcake is a lie.”. However, test2 fails, with this series of messages:
- Error parsing twig template undefined
- TypeError: fs.readFileSync is not a function (line 7130 of twig.js)
- TypeError: Cannot read properties of undefined (reading ‘valueOf’) (line 1859 of twig.js)
I thought maybe it was a path issue, but adding the param path: './' just threw a new error: path.normalize is not a function
I’ve put together a Codepen with this sample code and although it can’t load an included twig file, you can still see it throwing the fs.statSync is not a function error in the console.
So far I’ve spent 12 hours trying to figure out what is happening here. No matter what I do, a simple “include” in a twig file breaks it. I’m also following the instructions suggested by the Twig loader for Vite and again, things are fine until I try to include another twig file.
I’ve Googled for hours and can’t find anyone having this exact problem, so I’m hoping I’m just missing something incredibly basic.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 27 (3 by maintainers)
Coming back to share a workaround I recently discovered.
Looks like when using Vite, and in this case Storybook, (in the example its Storybook 8 and Vite 5, but Im not sure that matters) you can import the relative asset path (
./path/to/your/import?url) using Explicit URL Imports and pass that toTwig.twigas the href parameter.It seems by providing the
href, the twig templates use theajaxmethod rather than thefsmethod, as mentioned above, which avoids thefsissues originally mentioned.So, a simple example:
In the provided example I’m using some imports and macros and seems to work well!
@larowlan’s Drupal loader works great—switched to it and updated my story format and all’s well!
FWIW, its a fresh rewrite rather than a fork. But I did try the other loader first.
It looks like there is a psuedo fork of
vite-plugin-twig-loaderhere: vite-plugin-twig-drupal, trying to getincludes/embeds/extendsworking. Wonder if it might help the issues you’re experiencing. Although I haven’t been able to get Macros working: https://github.com/larowlan/vite-plugin-twig-drupal/issues/5@ericmorand I’ve been looking at @storybook/server with mixed feelings since it’d add a persistent external dependency. I’d almost rather lean more heavily into duplicating Twig environments with Twig.js to keep a fully-static reference.
The main issue is that storybook compiles things in the browser. This has been an issue from the beginning and is likely to remain one in the future: this is a design decision that is enough a bad one to prevent a lot of us from using it and use our own build tool chain that compile things in the server.
Also following up on this thread to see if anyone has found a solution. I’m running into similar issues as well and I am guessing it’s more-so related to how the loader package is working.
EDIT: We ended up just making the move to Twing. I saw another ticket that confirmed it would be the better approach for our use case, which is a WP theme.
Great, I’ll keep an eye out for it. Thanks for being willing to provide the additional info in order to hopefully get to the bottom of what’s going on.