Skip to content
This repository has been archived by the owner on Jul 19, 2021. It is now read-only.

@shopify/liquid-loader #867

Open
t-kelly opened this issue Nov 2, 2018 · 0 comments
Open

@shopify/liquid-loader #867

t-kelly opened this issue Nov 2, 2018 · 0 comments

Comments

@t-kelly
Copy link
Contributor

t-kelly commented Nov 2, 2018

TL;DR: Liquid files are not parsed by Slate, which limits what Slate can do with them. A Webpack liquid loader that parses Liquid could intelligently process the contents of liquid files and facilitate a host of build features and developer enhancements.

Background

Slate v1 originally included a liquid-asset-loader. This loader would read the contents of Liquid files for any use of {{ 'path' | asset_url }} so they could be transformed to work with both dev builds on localhost as well production builds on cdn.shopify.com.

The liquid-asset-loader failed because it was using a very basic approach to interpreting the contents of Liquid files, which resulted in a variety of breaking edge cases. Ultimately, the loader was removed and the feature of serving theme assets locally while developing was lost.

Now, Slate does not try to interpret the contents of Liquid files, it simply copies them from the src folder to the dist folder on build using copy-webpack-plugin.

Problems

An incomplete dependency graph

Webpack shines when it can handle all project dependencies and build a complete project dependency graph. This dependency graph contains all files referenced in the project, from Liquid to custom fonts and images.

In its current state, Slate’s Webpack config has only partial coverage of theme project dependencies and only manages JS and CSS dependencies imported in theentry points found in scripts/templates and scripts/layout. All Liquid files are not added to the dependency tree, and are instead simply copied from src to dist without reading their contents intelligently.

Liquid files contain references to project dependencies, for example let’s look at an example template Liquid file:

/templates/product.liquid/

{% layout 'product' %}

{% section 'product-display' %}

{% include 'social-sharing' %}

The contents of this Liquid file contains a variety of references to dependencies; from referencing layout/product.liquid with {% layout ‘product’ %} to snippets/social-sharing.liquid with {% include 'social-sharing' %}. All of these references could be contributing to a more complete dependency graph, but instead Slate has no idea if they are being used by theme and are actually dependencies.

We cannot read values within Liquid reliably

Without parsing Liquid into a abstract syntax tree (AST) we can not reliably compute values within Liquid. For example, the following example is straight forward, the value is a string:

<img src="{{ 'my-image.jpg' | asset_url }}" />

Things get a little more difficult if that string is assigned to a variable; now we need to be able to compute the value of the variable:

{% assign image = 'my-image.jpg' %}
<img src="{{ image | asset_url }}" />

Things get even harder if that code is in a {% for %} loop where we would want to add all potential values in the loop to the dependency tree:

{% assign images = 'image-1.jpg,image-2.jpg, image-3.jpg' | split: ',' %}

{% for image in images %}
  <img src="{{ image | asset_url }}" />
{% endfor %}

We cannot transform Liquid reliably

If we cannot reliably read values, we cannot reliably write values. Liquid transformation could open the door to host of Liquid enhancements on build.

An example of a Liquid enhancement on build could be inlining snippets on build. Inlining snippets on build would result in Liquid with fewer co-dependencies in production. Let’s say two sections, section-aand section-b both use {% include ‘responsive-image’ %} snippet. If we upload all three files to Shopify, those two sections depend on an external file and cannot be easily transported to another theme or project. Also, if you make an edit to responsive-image snippet in the online-code editor, it will effect both sections. What if you want to only edit responsive-image for one section? These decisions might be easy for a developer to make, but are more difficult for a less technically savvy merchant.

Solution

I propose we create a Webpack Liquid Loader that parses Liquid and adds any referenced dependencies to Webpacks dependency graph. In addition, the loader could accept additional extensions which transform Liquid on output. This would allow us to individually toggle transformations on and off and allow us to approach transformations in a incremental manor.

LiquidJS is a promising start to make this happen. I created an issue to start the ball rolling onunparsing the Liquid AST back to Liquid.

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

No branches or pull requests

1 participant