Shopify / slate

Slate is a toolkit for developing Shopify themes. It's designed to assist your workflow and speed up the process of developing, testing, and deploying themes.
https://shopify.github.io/slate
MIT License
1.28k stars 365 forks source link

Use liquid template files as Webpack entry points #876

Open t-kelly opened 6 years ago

t-kelly commented 6 years ago

*Depends on #867, #874, and #875. Related to #855.

What are entry points in Slate themes?

Webpack introduces the concept of entry points, a file which acts as the point where all dependency declarations for a webpage start from. When Webpack is used with React, an entry point file is typically the main app.js file. This file imports submodules, which can in turn import more submodules, or any files needed by the submodule such as images, fonts, scripts, and styles. The Webpack dependency tree is ideally made up of all files on the page, regardless of their file type.

In themes, we don’t use a single app.js file to render the page and control the entire theme, i.e. themes are not single page apps. Instead, themes consist of multiple pages each with their own unique dependencies. This means that each page should have its own entry point and dependency tree.

The problem with how Slate currently approaches entry points

Slate currently uses JS files in the scripts/templates folder that having matching names to liquid files in the templates/ folder as Webpack entry points. This is a fairly magical link which is not totally obvious until a developer has read the associated documentation on template entry points and bundles.

The ideal theme dependency tree

The liquid files in the templates folder are the ideal entry point file Webpack. These files are responsible for declaring dependencies which are displayed on a particular page route, including:

* Static sections using the `{% section %}` tag
* Snippets using the `{% include %}` tag
* layout using the `{% layout %}` tag
* assets using the filters like the `asset_url` filter

The only dependencies not declared by template files are scripts and styles we that we might want bundled together on build. For these kind of files, we could introduce a new Liquid tag exclusive to Slate, {% import %}.

Example

templates/product/product.liquid

{% import './product.js' %}
{% import './product.scss %}

{% layout '../layouts/main' %}

{% section '../sections/product-display' %}
{% section '../sections/product-form' %}
{% section '../sections/social-sharing' %}

{% include './product-meta.liquid' %}
YourWishes commented 6 years ago

I love the idea of this, it solves a lot of hiccups we're having with our current theme flow. I have some queries regarding how you see it working moving forward with Node Packages?

e.g. in my theme I have {% section 'coolpackage/sections/coolsection.liquid' %}

Would the webpack loader be able to determine, rather than using ./ for a relative directory and something along the lines of; {% section 'native-shopify-section' %}

for a native section, that I'm trying to reference a Package? Or are you looking to do something more along the lines of sass-magic, e.g. {% section '~@coolpackage/sections/coolsection.liquid %}

Additionally, I am hoping one day to have a feature where dynamic sections can also be packagized, but without a direct {% section 'somepackage/somesection.liquid' %} reference the proposed method may not allow for that.

Would we be looking perhaps for something along the lines of a slate-package.json in the future?

Ideally I'd love to have something resembling this:

mytheme
├-- sections/
|   ├-- sectiona.liquid
|   ├-- sectionb.liquid
|-- node_modules/
|   ├-- our-carousel
|       ├-- sections/
|           ├-- carousel.liquid
...

And have it output like so:

mytheme
├-- sections/
|   ├-- sectiona.liquid
|   ├-- sectionb.liquid
|   ├-- our-carousel-carousel.liquid
...

But at the same time avoid bloating the theme wherever possible.

t-kelly commented 6 years ago

@YourWishes it sounds like we're on the same page!

Just to keep things tidy, let's keep paths discussion in #874. I might also make a new issue for the node_modules reference.. I agree with the proposal of using ~ to distinguish between native sections and node_modules.