@molsoft/molsoft-tools
v3.0.3
Published
Tools used by the molsoft team to build shopify themes
Downloads
5,769
Readme
molsoft-tools
:warning: These build tools needs a unique key generated by Molsoft to run.
Tools used by the molsoft team to build shopify themes
Usage
Installation:
$ npm install @molsoft/molsoft-tools
package.json scripts:
{
"scripts": {
"start": "molsoft-tools watch",
"deploy": "molsoft-tools deploy",
"build": "molsoft-tools build",
"watch": "molsoft-tools watch",
"download": "molsoft-tools download",
"settings": "molsoft-tools download --settingsOnly",
"create": "molsoft-tools create",
"shopify": "shopify"
}
}
config.yml (molsoft-tools will automatically switch to this store):
store: mystore.myshopify.com
molsoft_key: 123456 # A molsoft key is required to run any command of this package.
Usage:
$ npm start - start development server
$ npm run watch - start development server
$ npm run deploy - deploys to production environment
...
Project structure
|
└─── src (shopify theme structure)
| |
│ └─── assets
│ | └─ ...
| |
│ └─── config
│ | └─ ...
| |
│ └─── layout
│ | └─ ...
| |
│ └─── locales
│ | └─ ...
| |
│ └─── sections
│ | └─ ...
| |
│ └─── snippets
│ | └─ ...
| |
│ └─── templates
│ | └─ ...
| |
|
└─── tools (molsost tools specific)
| |
| └─── schema (used to inject snippets into section schema)
| | |
| | └─ icons.json
| |
| └─── frameworks
| | |
| | └─── my-framework
| | | |
| | | └─── sections
| | | | |
| | | | └─ [name].liquid
| | | |
| | | └─── styles
| | | | |
| | | | └─ [name].scss
| | | |
| | | └─── scripts
| | | | |
| | | | └─ [name].js
| | | |
| | | └─── snippets
| | | | |
| | | | └─ [name]-snippet.liquid
| | | |
| | | └─── rest of the shopify structure
| |
│ └─── scripts
│ | │
| | └─── layout (webpack entrypoints for layouts, only loaded on specific layout)
| | | |
| | | |- theme.js
| | |
| | └─── templates (webpack entrypoints for templates, only loaded on specific templates)
| | | |
| | | └─── customers
| | | | |
| | | | |- account.js
| | | | └─ ...
| | | |
| | | |- product.js
| | | |- collection.js
| | | |- index.js
| | | └─ ...
| | |
| | └─── optimized_section (webpack entrypoints for sections, only loaded where imported)
| | | |
| | | └─ my-section.js
| | |
| | └─── optimized_components (webpack entrypoints for components, only loaded where imported)
| | | |
| | | └─ my-component.js
| | |
| | └─── personalized-project-structure-folder
| | | |
| | | └─ ...
| |
│ └─── styles
│ | │
| | └─── sections (suggested structure)
| | | |
| | | └─ ...
| | |
| | └─── components (suggested structure)
| | | |
| | | └─ ...
| | |
| | └─── core (suggested structure)
| | | |
| | | └─ ...
| | |
| | └─── personalized-project-structure-folder
| | | |
| | | └─ ...
| | |
│ | │- theme.scss (suggested structure)
| |
|
│- package.json
|- .babelrc
|- config.yml
|- .gitignore
Scripts
There are 4 folders where webpack will look for JS file entry points. molsfot-tools will need to be restarted for any new js files created in these folders.
/tools/scripts/layout
Any scripts that the name match with a shopify layout file will be added to the snippet script-tags.liquid
and loaded automatically on the matching layout. This should be used for any global scripts across the website.
So a file /tools/scripts/layout/theme.js
will be loaded on the theme.liquid
layout with the following logic:
{%- if layout == 'theme' or layout == blank -%}
<script type="text/javascript" src="{{ 'layout.theme.js' | asset_url }}" defer="defer" class="webpack-scripts layout-{{ layout }}"></script>
{%- else -%}
<link rel="prefetch" href="{{ 'layout.theme.js' | asset_url }}" as="script">
{%- endif -%}
For the script to load automatically you will need to add this to your layout file (e.g. theme.liquid):
{% render 'script-tags', layout: 'theme' %}
/tools/scripts/optimized_sections
& /tools/scripts/optimized_components
Any scripts in these folders will be added to the snippet section-script-tags.liquid
and component-script-tags.liquid
. These optimized scripts needs to be loaded manually in the sections liquid.
A section or component script can be loaded anywhere with the name of the file as a parameter. So a section a file /tools/scripts/optimized_sections/header.js
or a file /tools/scripts/optimized_components/tab.js
can be imported like that in a section:
{% render 'section-script-tags', section: 'header', lazy: false %}
{% render 'component-script-tags', component: 'tab', lazy: false %}
The script will be added like that to the snippet:
{%- if section == 'header' -%}
<script type="{% if lazy %}javascript/blocked{% else %}text/javascript{% endif %}" defer="defer" src="{{ 'section.header.js' | asset_url }}"></script>
{%- endif -%}
Notice that you can pass a lazy
parameter. If set to true the script will be added but never loaded. You will need to add your own logic to load the script at the moment you want. For example, the intersection observer could be used to load the script when the section is close to be in viewport.
/tools/scripts/templates
(Deprecated)
NOTE: This is marked as deprecated because optimized_sections and optimized_components are prefered for any code related to a section since they are loaded as necessary instead of globally on a template. Using optimized_sections and optimized_components prevents your from loading unnecessary code.
Any scripts that the name match with a shopify template file will be added to the snippet script-tags.liquid
and loaded automatically on the matching template.
So a file /tools/scripts/templates/gift_card.js
will be loaded only on the gift_card.liquid
template with the following logic:
{%- if template == 'gift_card' -%}
<script type="text/javascript" src="{{ 'template.gift_card.js' | asset_url }}" defer="defer" class="webpack-scripts"></script>
{%- else -%}
<link rel="prefetch" href="{{ 'template.gift_card.js' | asset_url }}" as="script">
{%- endif -%}
For the script to load automatically you will need to add this to your layout file (e.g. theme.liquid):
{% render 'script-tags', layout: 'theme' %}
CSS/SCSS
CSS and SCSS can be imported in any of the javascript entry points to be loaded alongside the corresponding script.
`/tools/scripts/layout
Having this in the layout script theme.js:
import '../../styles/theme.scss';
Will add this to the style-tags.liquid
snippet:
{%- if layout == 'theme' -%}
<link type="text/css" href="{{ 'vendors__layout.theme.css' | asset_url }}" rel="stylesheet" class="webpack-styles">
{%- else -%}
<link rel="prefetch" href="{{ 'vendors__layout.theme.css' | asset_url }}" as="style">
{%- endif -%}
To have the css load automatically on the layout you will need to add this in the layout file (e.g. theme.liquid):
{% render 'style-tags', layout: 'theme' %}
/tools/scripts/optimized_sections
& /tools/scripts/optimized_components
Having this on the section or component script header.js:
import '../../styles/sections/header.scss';
Will add this to the section-style-tags.liquid
and component-style-tags.liquid
snippet:
{% if section == 'header' %}
{% if inline %}
<style>
...
</style>
{% else %}
<link rel="stylesheet" {% if lazy %}data-{% endif %}href="{{ 'section.header.css' | asset_url }}"{% unless lazy %} media="print" onload="this.media='all'"{% endunless %}>
<noscript>{{ 'section.header.css' | asset_url | stylesheet_tag }}</noscript>
{% endif %}
{% endif %}
A section or component style can be imported anywhere like that with the section name as a parameter:
{% render 'section-style-tags', section: 'header', inline: true, lazy: false %}
{% render 'component-style-tags', section: 'tab', inline: true, lazy: false %}
Notice that you can pass an inline
parameter and lazy
parameter. If inline is set to true the style will be inline. The best practice would be to use a section checkbox to activate this if the section is above the fold and deactivate it if bellow the fold. (For content above the fold it is better for performance to have inline CSS)
Lazy will make the css not load at all and will need some additional logic to load the style when you want to. After some tests this is not a recommended to do as this will cause a flash of unstyled content too big to be user friendly.
/tools/scripts/templates
(Deprecated)
NOTE: This is marked as deprecated because optimized_sections and optimized_components are prefered for any code related to a section since they are loaded as necessary instead of globally on a template. Using optimized_sections and optimized_components prevents your from loading unnecessary code.
Having this in the template script product.js:
import '../../styles/templates/product.scss';
Will add this to the style-tags.liquid
snippet:
{%- if template == 'blog' -%}
<link type="text/css" href="{{ 'template.blog.css' | asset_url }}" rel="stylesheet" class="webpack-styles">
{%- else -%}
<link rel="prefetch" href="{{ 'template.blog.css' | asset_url }}" as="style">
{%- endif -%}
To have the css load automatically on the template you will need to add this in the layout file (e.g. theme.liquid):
{% render 'style-tags', layout: 'theme' %}
schema snippets
molsoft-tools supports the injection of snippets into sections schema using json files. To create a schema snippet, you need to do so in the /tools/schema
folder.
injecting a schema snippet
Create a json file in the folder /tools/schema
:
e.g.:
// /tools/schema/icons.json
{
"type": "select",
"id": "icons",
"label": "Icons",
"options": [
{
"label": "Search",
"value": "search"
},
{
"label": "Account",
"value": "account"
},
{
"label": "Arrow right",
"value": "arrow-right"
},
{
"label": "Arrow left",
"value": "arrow-left"
}
]
}
Then in your section schema you can inject this snippet using the snippet file name like this:
{% schema %}
{
"name": "My section",
"class": "my-section",
"settings": [
{
"type": "text",
"id": "title",
"label": "Title"
},
{
"snippet": "icons.json"
},
{
"type": "text",
"id": "other_settings",
"label": "Some other settings"
}
]
}
{% endschema %}
injecting a schema snippet containing a group of settings
If you want to inject a group of settings all at once, you can create a json file containing an array in the /tools/schema
folder.
e.g.:
// /tools/schema/section_layout.json
[
{
"type": "header",
"content": "Layout"
},
{
"type": "checkbox",
"id": "above_the_fold",
"label": "Section is above the fold",
"info": "Section is visible before scrolling the page"
},
{
"type": "select",
"id": "section_size",
"label": "Section size",
"options": [
{
"value": "full-width",
"label": "Full width"
},
{
"value": "full-width-container",
"label": "Large"
},
{
"value": "container",
"label": "Medium"
},
{
"value": "container container--small",
"label": "Small"
}
],
"default": "container"
},
{
"type": "range",
"label": "Top spacing",
"id": "section_margin_top",
"min": 0,
"max": 10,
"unit": "rem",
"step": 0.2,
"default": 8
},
{
"type": "range",
"label": "Section top padding",
"id": "section_padding_top",
"min": 0,
"max": 10,
"unit": "rem",
"step": 0.2,
"default": 6
},
{
"type": "range",
"label": "Section bottom padding",
"id": "section_padding_bottom",
"min": 0,
"max": 10,
"unit": "rem",
"step": 0.2,
"default": 6
}
]
Then in your section schema you can inject this snippet group by appending ...
in front of the file name:
{% schema %}
{
"name": "My section",
"class": "my-section",
"settings": [
{
"type": "text",
"id": "title",
"label": "Title"
},
{
"snippet": "...section_layout.json"
},
{
"type": "text",
"id": "other_settings",
"label": "Some other settings"
}
]
}
{% endschema %}
Frameworks
If you regularly add new sections and their structure is always similar, you can create what we call a framework. A framework is a template of files that will be copied to your project and some variables will be automatically populated. You can check the command molsoft-tools create
for more information.
Commands
molsoft-tools watch
molsoft-tools deploy
molsoft-tools download
molsoft-tools create
molsoft-tools setup-theme
molsoft-tools help [COMMAND]
molsoft-tools watch
Will start development server and watch for file changes.
Note: Some issues might occur with the local URL. It is sometimes prefered to use the preview URL.
USAGE
$ molsoft-tools watch
OPTIONS
-f, --otherFlags=otherFlags Add other flags to shopify CLI.
ex: molsoft-tools watch --otherFlags="--allow-live --dir=something etc...
-i, --pullId=pullId The theme id where you want to pull the setting from. Will be prompted to select thetheme if omitted
-s, --pullSettings Will pull settings from a selected theme and add it to your development theme
-v, --verbose Will log the webpack object (including errors if there is)
molsoft-tools deploy
Will build and deploy the theme to the selected theme.
USAGE
$ molsoft-tools deploy
OPTIONS
-D, --development Deploy to your development theme
-b, --buildOnly Will build the project without deploying
-d, --distFolder=distFolder Name of the folder where the project will be built
-t, --themeId=my-theme-id The id of the theme where you want to deploy (Shopify cli will prompt you to select a theme if ommited)
-f, --otherFlags=otherFlags Add other flags to shopify CLI.
ex: molsoft-tools watch --otherFlags="--allow-live --dir=something etc...
-j, --json Creates a json output of the deployment inside the dist folder
-F, --force Will skip the prompt where you are asked if you are sure you want to push to the live theme
-s, --ignoreSettings Will deploy the theme without the settings and json templates
-v, --verbose Will log the webpack object (including errors if there is)
molsoft-tools download
Will download the selected theme into the src folder while ommiting webpack generated files
USAGE
$ molsoft-tools download
OPTIONS
-t, --themeId=my-theme-id The id of the theme that you want to download (Shopify cli will prompt you to select a theme if ommited)
-s, --settingsOnly Will download only the settings of the specified theme
molsoft-tools create
Creates files and folders for a new component based on a framework template.
To create a new framwork template, create a folder in /tools/frameworks with the name you want for your component. In this folder you can replicate the structure you want for your component.
You can use the variable [name]
in your file names to automatically replace it with the name of the component you are creating. You can also use the variable [name]
and [class]
in your file content to automatically replace it with the name of the component you are creating. The variable [name]
for the file name and the [class]
variable will be converted to kebab case. The [name]
variable for the file content will stay the same as the name you entered.
Example of the structure of a framework template:
└─── tools
| |
| └─── frameworks
| | |
| | └─── my-framework
| | | |
| | | └─── sections
| | | | |
| | | | |- [name].liquid
| | | |
| | | └─── styles
| | | | |
| | | | |- [name].scss
| | | |
| | | └─── scripts
| | | | |
| | | | |- [name].js
| | | |
| | | └─── snippets
| | | | |
| | | | |- [name]-snippet.liquid
| | | |
| | | └─── rest of the shopify structure
USAGE
$ molsoft-tools create
molsoft-tools setup-theme
Will setup the theme to work with molsoft-tools
USAGE
$ molsoft-tools setup-theme
OPTIONS
-C, --convert Will convert a theme in current folder to the molsoft-tools structure.
First possible optimization will be to move the scripts and styles in the script and style folders
and import them in "scripts/layout/theme.js" and "styles/theme.scss".
-n, --newProject Will ask for credentials, download the theme, do the setup and create QA theme and developper theme
DESCRIPTION
This will convert the default file structure of a shopify theme to the molsoft-tools structure and other small things
to help with setup.
molsoft-tools help [COMMAND]
display help for molsoft-tools
USAGE
$ molsoft-tools help [COMMAND]
ARGUMENTS
COMMAND command to show help for
OPTIONS
--all see all commands in CLI