Skip to content
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

Specify target components to Builder #169

Closed
mihkeleidast opened this issue Oct 25, 2016 · 10 comments
Closed

Specify target components to Builder #169

mihkeleidast opened this issue Oct 25, 2016 · 10 comments

Comments

@mihkeleidast
Copy link
Member

Hey, I'm running a pretty large pattern library on Fractal, with a total build time approaching 30 minutes. Most of the time, though, I don't really need to build the whole library, but only a single component for a quick prototype demo.

Is it currently possible through the API to specify which components to include in the static build?

@allmarkedup
Copy link
Member

allmarkedup commented Oct 25, 2016

@Risker woah that is a crazy long build time! How many components do you have in there? I've never had build times anywhere near that long, although I am well aware that the current parse/build system is in serious need of some performance improvements.

Until then... there is no way to only 'build' parts of the UI itself. But if you don't need the UI and just want a rendered component for prototyping then you can certainly use the API to either write a Fractal custom command or a Gulp task or similar to render one or more components and save them to disk.

For example, if you put the following into your fractal.js file:

const fs = require('fs');
const path = require('path');

function renderComponent(args, done){
    const app = this.fractal;
    const target = app.components.find(args.component);
    if (target) {
        app.components.render(target, null, null, {
            preview: args.options.layout
        }).then(function(html){
            const filePath = path.join('./', args.options.output || '', `${target.handle}.html`);
            fs.writeFile(filePath, html, function(err){
                if (err) {
                    app.cli.console.error(`Error rendering ${args.component} - ${err.message}`);
                } else {
                    app.cli.console.success(`Component ${args.component} rendered to ${filePath}`);
                }
                done();
            });
        });
    } else {
        app.cli.console.error(`Component ${args.component} not found`);
    }
};

fractal.cli.command('render <component>', renderComponent,  {
    description: 'Render a component',
    options: [
        ['-l, --layout', 'Render the component within it\'s preview layout.'],
        ['-o, --output <output-dir>', 'The directory to render the component into, relative to the CWD.'],
    ]
});

You could then use the command fractal render @foo from within your project and it would render the @foo component and save it as foo.html, or if you want to render it with within it's preview layout you could run fractal render @foo --layout. There is also an option for specifying the relative output directory (i.e. fractal render @foo --output exported/components.

Would something like that work for you?

@allmarkedup
Copy link
Member

@Risker and If you want to run through all (or some of) your components and renderer them without the web UI you may also want to check out this issue for some ideas: #140 (comment)

@mihkeleidast
Copy link
Member Author

@allmarkedup thanks for looking into this!

Starting a build tells me it's trying to export 3164 items. Is that a lot? :) (we treat full page prototypes as components as well, and we got a lot of different page templates)

Our main goal with this idea/request would still require the web UI. I'll try to explain this more: rather often somebody on our team is asked to build a prototype page based on our pattern library. When it comes to handing off that prototype to another team to implement, we currently have the following options:

  • build the whole pattern library (what we're doing now)
  • build only that page via a helper command (like the one in your reply)
  • build a mini version of the pattern library with just the necessary components (since fractal collects all the references made in a component, those would be included as well) We could then hand off that mini pattern library with variants/docs of all the components used in that prototype. Then the next team could change variants/settings more easily. (what we're trying to achieve)

So some kind of filtering system for the builder would come in handy, based on (an array of) component handles. Or even tags! Thinking "build a pattern library of components and dependencies that have "registration-flow" tag attached"...

@allmarkedup
Copy link
Member

@Risker Ok I understand a bit better now, but unfortunately that is not something that is supported right now. A filtering system would be handy but Fractal's dependency tracking is not super-robust at the moment so would need to be improved before something like this could be implemented.

I think possibly the best thing I can do for you in the near future is to improve the speed of the build process which I'll hopefully get to look at soon!

@stale
Copy link

stale bot commented Jul 12, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 12, 2018
@stale stale bot closed this as completed Jul 19, 2018
@thomasaull
Copy link

Hey @allmarkedup, I have a follow up question regarding your code example: #169 (comment)

In my project, for a full build, I'm setting a static path like in the documentation: https://fractal.build/guide/web/configuration-reference.html#static-path, so that in components this path:

/images/my-image.jpg

when doing a build, becomes this:

../../images/my-image.jpg

However, I can't get this behaviour working when using the components.render() function. Probably because I don't know how to configure the static path in this case. I searched the documentation, source codea and the Discord but I can't find anything which does help me in this case. Do you have any pointers for me?

@mihkeleidast
Copy link
Member Author

mihkeleidast commented Feb 3, 2021

@thomasaull you need to specify env.request.path to the render method:

const env = {
    request: {
        path: page.meta.path + 'index.html',
    },
};
component.render(context, env).then((html) => {
    console.log(html)
});

@thomasaull
Copy link

thomasaull commented Feb 3, 2021

@mihkeleidast Appreciate your help and it seems like this is the bit I was missing. One (probably) last question: When I'm doing a full build, the _env.request.path property is something like /components/preview/my-component

Everything works, when I'm hard coding this string in my function like in your example. But there is probably a smarter way to do this. This might be what your page.meta.path is doing — is the page variable in your case the result of fractal.components.find()?

@mihkeleidast
Copy link
Member Author

Yeah we have a static path defined in the component (page) meta and we render all the pages this way.

@thomasaull
Copy link

@mihkeleidast Thanks for the explanation and for your help! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants