@syncify/cli 0.3.0-beta → 1.0.0-unstable.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +10 -6
  2. package/dist/api.js +32 -12
  3. package/dist/cli.js +610 -6
  4. package/dist/index.d.ts +2264 -0
  5. package/dist/index.js +10 -10
  6. package/dist/syncify.js +24248 -0
  7. package/hot.js.liquid +13 -2
  8. package/package.json +118 -115
  9. package/readme.md +110 -2176
  10. package/scripts/postinstall.js +116 -0
  11. package/scripts/postversion.js +60 -0
  12. package/dist/cjs.js +0 -236
  13. package/pnpm-lock.yaml +0 -5662
  14. package/schema/syncify.config.json +0 -676
  15. package/schema/syncify.env.json +0 -58
  16. package/schema/syncify.package.json +0 -11
  17. package/types/api.d.ts +0 -319
  18. package/types/bundle/cache.d.ts +0 -101
  19. package/types/bundle/commands.d.ts +0 -396
  20. package/types/bundle/errors.d.ts +0 -101
  21. package/types/bundle/file.d.ts +0 -285
  22. package/types/bundle/filters.d.ts +0 -81
  23. package/types/bundle/hot.d.ts +0 -185
  24. package/types/bundle/index.d.ts +0 -603
  25. package/types/bundle/plugin.d.ts +0 -127
  26. package/types/bundle/processors.d.ts +0 -54
  27. package/types/bundle/reports.d.ts +0 -123
  28. package/types/bundle/requests.d.ts +0 -374
  29. package/types/bundle/shared.d.ts +0 -124
  30. package/types/cli.d.ts +0 -547
  31. package/types/config/index.d.ts +0 -550
  32. package/types/config/terser.d.ts +0 -319
  33. package/types/config/views.d.ts +0 -191
  34. package/types/index.d.ts +0 -55
  35. package/types/modules/html-minifier-terser.d.ts +0 -218
  36. package/types/stores.d.ts +0 -11
  37. package/types/transforms/image.d.ts +0 -15
  38. package/types/transforms/json.d.ts +0 -51
  39. package/types/transforms/pages.d.ts +0 -254
  40. package/types/transforms/script.d.ts +0 -308
  41. package/types/transforms/style.d.ts +0 -219
  42. package/types/transforms/svg.d.ts +0 -189
package/readme.md CHANGED
@@ -1,2260 +1,194 @@
1
- **BETA VERSION**
2
-
3
- <hr>
4
-
5
- # SYNCIFY
6
-
7
- A lightening fast, extensible and superior alternative Shopify CLI (Theme Development) tool. Syncify provides developers with a powerful CLI and employs an intuitive approach for creating Shopify themes. It's batteries included solution designed for advanced theme development.
8
-
9
- ### Demos
10
-
11
- - [Syncify Dawn Basic](https://github.com/panoply/syncify-dawn-basic)
12
- - [Syncify Dawn Advanced](https://github.com/panoply/syncify-dawn-advanced)
13
-
14
- ### Key Features
15
-
16
- - Watch, upload, import and export to multiple storefronts and themes.
17
- - Intelligent path mapping resolutions that support custom directory structures.
18
- - HOT Reloading of assets, section, snippets, templates and layouts.
19
- - Clear, concise, informative and beautiful TUI/CLI logging.
20
- - An elegant global directory based metafields sync approach using JSON files.
21
- - Supports spawned processing with existing build tools.
22
- - Additional resource controls for syncing Files, Pages and Redirects.
23
- - Provides a simple Reusable Sections approach for shared section references
24
-
25
- ### Why?
26
-
27
- I have been working on the Shopify platform for several years and nothing the Shopify team have produced has increased my productivity. Despite the advancements Shopify has made in recent years I still find their developer tooling to be missing the mark and a clear disconnect is apparent. The Shopify CLI is cool and all but for me the approach to theme development it fails to achieve fluidity. Syncify is how I believe theme creation, development and maintenance should be done.
28
-
29
- Syncify provides you with essential stack tooling for producing lean, performant and refined themes. It's fast, flexible, extensible, scalable but most importantly, it's an un-restrictive workflow.
30
-
31
- # Installation
32
-
33
- Syncify is distributed as both an ESM and CJS module. It is recommended that you install as a development dependency in your project opposed to installing globally. Please consider choosing and adopting [pnpm](https://pnpm.js.org/en/cli/install) as your package manager for most optimal usage.
34
-
35
- **PNPM**
36
-
37
- ```bash
38
- pnpm add @syncify/cli -D
39
- ```
40
-
41
- > Use `pnpx @syncify/cli` for remote execution
42
-
43
- **NPM**
44
-
45
- ```bash
46
- npm i @syncify/cli --save-dev
47
- ```
48
-
49
- > Use `npx @syncify/cli` for remote execution
50
-
51
- **Yarn**
52
-
53
- ```bash
54
- yarn add @syncify/cli --dev
55
- ```
56
-
57
- # Setup
58
-
59
- After installing you will need to configure a connection to your shopify store. Syncify requires you provide either an Admin API Access Token (recommended) or API Key and Secret as credentials.
60
-
61
- <details>
62
- <summary>
63
- <strong>Authorize</strong>
64
- </summary>
65
- <p>
66
-
67
- You will need to create a [private app](https://help.shopify.com/en/manual/apps/private-apps) to obtain this information from Shopify. If you are coming from [Theme Kit](https://shopify.dev/themes/tools/theme-kit) you might be able to port those settings but it is recommended that you generate API access information specifically for usage with Syncify.
68
-
69
- > There are plans to provide an official Syncify Shopify App to make this easier in future releases.
70
-
71
- **Steps:**
72
-
73
- 1. From your Shopify admin, go to **Apps**.
74
- 2. Click **Develop apps**.
75
- 3. Click **Create an app**.
76
- 4. Provide an App name (eg: `Syncify`) and click **Create app**
77
- 5. The app will be created, then click **Configure Admin API Scope**
78
- 6. Select the required scopes (listed below)
79
- 7. Click **Save**
80
- 8. Goto the **API credentials** tab,
81
- 9. Under **Access Tokens** press the **Install app** button.
82
- 10. Press **Reveal token once** and copy the token into an `.env` file.
83
-
84
- </p>
85
- </details>
86
-
87
- <details>
88
- <summary>
89
- <strong>Scopes</strong>
90
- </summary>
91
- <p>
92
-
93
- You need to provide Syncify read and write access to a couple of admin endpoints so it can perform operations. Below are the required scopes you will need to enable within in your private app.
94
-
95
- #### Files
96
-
97
- - write_files
98
- - read_files
99
-
100
- #### Pages
101
-
102
- - write_online_store_pages
103
- - read_online_store_pages
104
-
105
- #### Themes
106
-
107
- - write_themes
108
- - read_themes
109
-
1
+ <br>
2
+ <p align="center">
3
+ <a href="https://syncify.sh">
4
+ <img src="https://raw.githubusercontent.com/panoply/syncify/3b7839da26b4355943c94ddf93f81e2f41a6a2bf/assets/logo-text.svg"
5
+ width="270px">
6
+ </a>
110
7
  </p>
111
- </details>
112
-
113
- # Credentials
114
-
115
- Shop credentials can be stored within a `.env` or `.env.syncify.json` file. You can also provide credentials at runtime using `process.env` variables. The preferred approach is to store this information within a `.env` file.
116
-
117
- ### Using a `.env` file
118
-
119
- When using a `.env` file, you can provide shop credentials in either uppercase of lowercase format. The `.env` values **must** begin with the shop name following an underscore `_` character. If you are syncing to multiple storefronts just follow the pattern for each store.
120
-
121
- Using an **API Access Token**
122
-
123
- ```env
124
- YOUR-SHOP-NAME_API_TOKEN = 'shpat_abcdefghijklmnopqrstuvwz'
125
- ```
126
-
127
- Using an **API key** and **API Secret**
128
-
129
- ```env
130
- YOUR-SHOP-NAME_API_KEY = 'abcdefghijklmnopqrstuvwz'
131
- YOUR-SHOP-NAME_API_SECRET = 'abcdefghijklmnopqrstuvwz'
132
- ```
133
-
134
- ### Using `process.env` variables
135
-
136
- Syncify also supports runtime credential assignment. This approach allows you to set credentials via the command line or within a script executable. This is highly discouraged and rather insecure.
137
-
138
- Using an **API Access Token**
139
-
140
- ```js
141
- // Using an API Access Token
142
- process.env['YOUR-SHOP-NAME_API_TOKEN'] = 'shpat_abcdefghijklmnopqrstuvwz';
143
- ```
144
-
145
- Using an **API key** and **API Secret**
146
-
147
- ```js
148
- // Using an API Key and API Secret
149
- process.env['YOUR-SHOP-NAME_API_KEY'] = 'abcdefghijklmnopqrstuvwz';
150
- process.env['YOUR-SHOP-NAME_API_SECRET'] = 'abcdefghijklmnopqrstuvwz';
151
- ```
152
-
153
- # Configuration
154
-
155
- Syncify supports `syncify.config.ts` and `package.json` configurations. Depending on your preference, either option suffices and no restrictions are imposed. If you are defining options within your projects `package.json` file you can assign options on the `syncify` property.
156
-
157
- ### Supported Files
158
-
159
- Syncify supports the following configuration file types. The recommended approach is the TypeScript `syncify.config.ts` configuration file type.
160
-
161
- - `syncify.config.ts`
162
- - `syncify.config.js`
163
- - `syncify.config.ts`
164
- - `syncify.config.mjs`
165
- - `syncify.config.cjs`
166
- - `syncify.config.json`
167
-
168
- ### Default Options
169
-
170
- Below are the **default** configurations. Options commented out within [transforms](#transform), [processors](#processors) and [terser](#terser) require peer dependencies to be installed for usage.
8
+ <h1></h1>
171
9
 
172
- <!-- prettier-ignore -->
173
- ```ts
174
- import { defineConfig } from '@syncify/cli';
10
+ Syncify is a specialized tool designed for Shopify theme development. It offers an array of features that significantly enhance productivity, integration and workflow on the Shopify platform. Created to address the in-house mediocrity of the OSS (theme dev) offerings by the Shopify team, Syncify delivers a sophisticated, high-performance, and customizable toolkit that streamlines workflows and integrates with modern tooling.
175
11
 
176
- export default defineConfig({
177
- input: 'source',
178
- output: 'theme',
179
- export: 'export',
180
- import: 'import',
181
- config: '.',
182
- clean: true,
183
- stores: [
184
- {
185
- domain: '',
186
- themes: {}
187
- }
188
- ],
189
- hot: {
190
- label: 'visible',
191
- history: true,
192
- method: 'hot',
193
- inject: true,
194
- strategy: 'hydrate',
195
- scroll: 'preserved',
196
- server: 3000,
197
- socket: 8089,
198
- layouts: [
199
- 'theme.liquid'
200
- ],
201
- },
202
- logger: {
203
- clear: true,
204
- silent: false,
205
- stats: true,
206
- warnings: true
207
- },
208
- paths: {
209
- redirects: 'redirects.yaml',
210
- assets: 'assets/**/*',
211
- files: 'files/**/*',
212
- config: 'config/*.json',
213
- locales: 'locales/*.json',
214
- layout: 'layouts/*.liquid',
215
- sections: 'sections/*.liquid',
216
- snippets: 'snippets/*.liquid',
217
- metafields: 'metafields/**/*.json',
218
- metaobject: [
219
- 'templates/metaobject/*.json'
220
- ],
221
- customers: [
222
- 'templates/customers/*.json',
223
- 'templates/customers/*.liquid'
224
- ],
225
- pages: [
226
- 'pages/*.md',
227
- 'pages/*.html'
228
- ],
229
- templates: [
230
- 'templates/*.json',
231
- 'templates/*.liquid'
232
- ],
233
- },
234
- spawn: {
235
- build: {},
236
- watch: {},
237
- },
238
- views: {
239
- snippets: {
240
- separator: '-',
241
- global: [],
242
- prefixDir: false,
243
- renamePatterns: {}
244
- },
245
- sections: {
246
- separator: '-',
247
- prefixDir: false,
248
- global: [],
249
- renamePatterns: {}
250
- },
251
- pages: {
252
- safeSync: true,
253
- author: '',
254
- importLanguage: 'html',
255
- suffixDir: false,
256
- global: []
257
- }
258
- },
259
- transforms: {
260
- script: {},
261
- style: {},
262
- svg: {},
263
- image: {}
264
- },
265
- processors: {
266
- json: {
267
- crlf: false,
268
- indent: 2,
269
- useTab: false,
270
- exclude: []
271
- }
12
+ <h4>
13
+ Read Documentation&nbsp;&nbsp;➠&nbsp;&nbsp;https://syncify.sh
14
+ </h4>
272
15
 
273
- // Refer to transforms section for usage
274
- //
275
- // esbuild: {},
276
- // sass: {},
277
- // postcss: [],
278
- // tailwind: {},
279
- // svgo: {},
280
- // sprite: {},
281
- // sharp: {},
16
+ ### Why Use Syncify?
282
17
 
283
- },
284
- terser: {
285
- json: {
286
- assets: true,
287
- config: true,
288
- locales: true,
289
- metafields: true,
290
- templates: true,
291
- exclude: []
292
- },
293
- views: {
294
- collapseWhitespace: true,
295
- minifySchema: true,
296
- minifyScript: true,
297
- minifyStyle: true,
298
- removeComments: true,
299
- stripDashes: true,
300
- exclude: []
301
- },
18
+ If you are seeking a tool that has considered requirement factors across the modern Shopify Theme Development ecosystem, and would like a solution that produces performance-focused optimizations at the development process level with features designed for the complexities of modern e-commerce, see the below core capabilities offerred by Syncify:
302
19
 
303
- // Refer to terser section for usage
304
- //
305
- // script: {},
306
- // style: {},
307
- }
308
- });
309
- ```
310
-
311
- # Getting Started
312
-
313
- It is relatively easy to get started developing Shopify themes using Syncify. If you are converting an existing project and using Theme Kit, Shopify CLI or another build environment you can progressively adapt it into your workflow by manually configuring how Syncify should behave. Whatever the case, have a look at the [Syncify Dawn (Basic)](https://github.com/panoply/syncify-dawn-basic) example repository as a starting point.
314
-
315
- ### Pre-requisites
20
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Custom input output directory structures for tailored project organization.</samp></strong></i><br>
21
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Compiling TypeScript, JavaScript, TSX, and JSX to support modern web development practices</samp></strong></i><br>
22
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Tailwind, PostCSS, and SASS stylesheet support for advanced CSS management</samp></strong></i><br>
23
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Terse minification of Markup and Liquid to optimize performance</samp></strong></i><br>
24
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Static pages with Markdown → Markup transformation for content creation flexibility</samp></strong></i><br>
25
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Metafield, Redirects, and Navigation synchronization for seamless data management</samp></strong></i><br>
26
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Version Controlled theme distribution ensuring consistency and traceability</samp></strong></i><br>
27
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Shared Schemas as a superset implementation for enhanced data modeling</samp></strong></i><br>
28
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Frontmatter controlled liquid level configuration to fine-tune template behavior</samp></strong></i><br>
29
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>SVG transform and sprite generation processing for efficient icon and graphic handling</samp></strong></i><br>
30
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Multistore and theme parallel synchronization to manage multiple storefronts</samp></strong></i><br>
31
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Websocket HOT Reloads with CFH control and morphing for real-time development feedback</samp></strong></i><br>
32
+ &nbsp;&nbsp;<i><strong> $\color{Green}{✓}$ <samp>Git-based automations with CI baked integrations for streamlined development workflows</samp></strong></i><br>
316
33
 
317
- Before going over the features Syncify provides, it is assumed that you have done the following:
34
+ <h1></h1>
318
35
 
319
- 1. Installed Syncify as a development Dependency
320
- 2. Created a private app and added API credentials
321
- 3. Added a `syncify.config.ts` file in the root of your project
36
+ ### Examples / Themes
322
37
 
323
- ### Contents
38
+ The [Syncify Straps](https://github.com/SyncifyCLI) github organization provides a collection of usage examples and starting point themes using Syncify. You can use the command line to generate new projects with the available straps.
324
39
 
325
- - [Directories](#directories)
326
- - [Paths](#dirs)
327
- - [Stores](#stores-required)
328
- - [Hot](#hot)
329
- - [Spawn](#spawn)
330
- - [Views](#views)
331
- - [Transforms](#views)
332
- - [Processors](#views)
333
- - [Terser](#views)
40
+ ### Editor Intergration
334
41
 
335
- # Directories
42
+ For an integrated development experience in your text editor, please consider using the [VSCode Liquid](https://github.com/panoply/vscode-liquid) extension which has built-in support for Syncify. VSCode Liquid is the independent alternative to the Shopify backed extension which is maintained and created by the same author of Syncify.
336
43
 
337
- Syncify requires you to define custom **base** directory paths that point to theme files. The values you provide will refer to a directory name that is relative to the root of your project. You **cannot** define multi-level directories (eg: `some/dir`) or reverse paths (eg: `../dir`). You can pass these references within your syncify configuration file or via the CLI.
44
+ ### Getting Help?
338
45
 
339
- > **Note**
340
- >
341
- > References passed in via the CLI will overwrite those provided in syncify configuration files.
46
+ Join the [Shopify Developers Discord](https://discord.gg/shopify-developers-597504637167468564) and ask your questions in the **`# syncify`** channel under the **`projects`** tab. Connect with other developers, maintainers, and contributors already using Syncify in their projects or within their agency.
342
47
 
343
- ### Input → Output
344
-
345
- Syncify expects projects to have an **input** directory path which contains theme **source** files. Files contained within an input directory are written to your defined **output** directory path. The generated output will be reflective of your online store and in most cases you will add the output directory to your `.gitignore` file (because it can always be rebuilt from input). If you have become accustomed to working from a single directory structure (i.e: Shopify Dawn) it is important that you understand the difference between the **input** and **output** directory approach.
346
-
347
- Single directory structures are not a viable approach when building modern and performant Shopify themes. Client-side (front-end) development is not SaaS specific and thus, with the proper tooling, Shopify theme development does not require one to adhere to the imposed approach of Shopify Dawn (via Shopify CLI). The argument for multi-directory architecture rests upon the millions of projects which isolate source ~ distribution variations and appropriate such logic.
348
-
349
- ### Default Structure
48
+ # Installation
350
49
 
351
- Below is an example of a Syncify theme structure using the defaults. Syncify will assume this directory structure if you do not provide any customizations via the CLI or within your syncify config file.
50
+ You can install Syncify as a development dependency or globally. There are a couple of different versions available, all of which can be consumed via the NPM Registry. Please consider using [pnpm](https://pnpm.js.org/en/cli/install) as your package manager for a faster and better experience with Syncify and NodeJS development. For all releases and available versions refer to **[syncify.sh/releases](https://syncify.sh/releases)** page.
352
51
 
353
- ```bash
354
- ├─ source # The src directory where you develop and theme files exist
355
- ├─ theme # The output directory where source files will be written
356
- ├─ .env # Shop credentials, such as Admin API Token or API key and secret
357
- ├─ .gitignore # Files to be ignored by git, e.g: your .env file
358
- ├─ package.json # The package.json file common in all Node projects, self explanatory
359
- ├─ syncify.config.ts # The syncify config file, you can optionally use package.json
360
- └─ tsconfig.json # TypeScript configurations, this is optional but preferred.
52
+ <samp align="center">
53
+ <strong>
54
+ <br>
55
+ <table><tr><td>
361
56
 
362
- ```
57
+ <h3> GLOBAL INSTALL&nbsp;&nbsp;⮂&nbsp;&nbsp;SY CLI BINARY </h3>
363
58
 
364
- <!-- prettier-ignore -->
365
- <table>
366
- <thead>
367
- <tr>
368
- <th width="500px">Config File</th>
369
- <th width="500px">CLI Flags</th>
370
- </tr>
371
- </thead>
372
- <tbody>
373
- <tr>
374
- <td>
59
+ Install Syncify globally to make the CLI binary available system-wide so you can use commands anywhere on your computer. The <a href="/packages/config/">@syncify/config</a> package can be leveraged on a per-project basis along side global installations for configuration file TypeScript support.
375
60
 
376
- <!-- prettier-ignore -->
377
- ```ts
378
- import { defineConfig } from '@syncify/cli';
61
+ <br>
62
+ </td></tr></table>
63
+ </strong>
64
+ </samp>
379
65
 
380
- export default defineConfig({
381
- input: 'source',
382
- output: 'theme',
383
- import: 'import',
384
- export: 'export',
385
- config: '.'
386
- })
387
- ```
66
+ ## Stable Release
388
67
 
389
- </td>
390
- <td height="200px">
68
+ The most stable and latest version of Syncify is available for consumption via the [NPM Registry](https://www.npmjs.com/package/@syncify/cli).
391
69
 
392
- <!-- prettier-ignore -->
393
70
  ```bash
394
-
395
-
396
- --input -i # Input Path
397
- --output -o # Output Path
398
- --config -c # Config Path
399
- --export -e # Export Path
400
-
401
-
402
- ```
403
-
404
- </td>
405
- </tr>
406
-
407
- </tbody>
408
- </table>
409
-
410
- # Stores (Required)
411
-
412
- The `stores` option is required and will be used to perform sync operations. The option accepts an **object** or **array** type. Each item will hold reference to your shopify store/s and their theme/s. For each store you define, you will provide the **shop** name, theme **target** name and **id**. The `themes` object uses a **key** > **value** structure, where the **key** represent a theme name (target) and the value a theme id.
413
-
414
- The information you provide to this option can be used via the CLI when targeting and executing operations. Please refer to the [commands](#commands) portion of this readme for more information on CLI usage.
415
-
416
- > **Note**
417
- >
418
- > The theme target name does need to match that defined in your online store and can be anything you like.
419
-
420
- ### Config File
421
-
422
- Below is an example of how a store reference can be defined. In the example, we have only provided a store domain `shop-1.myshopify.com` and 3 themes to connect and interface with. You can provide reference to multiple stores by passing an array list using the same structure.
423
-
424
- <!-- prettier-ignore -->
425
- ```ts
426
- import { defineConfig } from '@syncify/cli';
427
-
428
- export default defineConfig({
429
- stores: {
430
- domain: 'shop-1', // equivalent of shop-1.myshopify.com
431
- themes: {
432
- dev: 123456789,
433
- prod: 123456789,
434
- test: 123456789
435
- }
436
- }
437
- });
71
+ $ pnpm add @syncify/cli --global
438
72
  ```
439
73
 
440
- ### CLI Usage
74
+ ## Nightly Release
441
75
 
442
- Based on the above example configuration, this is how we would target and perform operations with the store and its theme/s using the CLI. In Syncify, when performing a sync action, you pass the store name as the first argument, followed by any `--flags`.
76
+ The nightly releases of Syncify can be installed using the `@next` version tag via NPM, code is on [next](https://github.com/panoply/syncify/tree/next) branch.
443
77
 
444
- <!-- prettier-ignore -->
445
78
  ```bash
446
-
447
- # FLAGS
448
-
449
- --theme, -t <target> # Theme name or comma separated list of theme names to target
450
-
451
- # EXAMPLES
452
-
453
- $ syncify shop-1 -t dev --watch # Running watch mode and targeting dev theme
454
- $ syncify shop-1 -t dev,prod --upload # Uploading to the dev and prod themes of shop-1
455
-
456
- ```
457
-
458
- ### Options
459
-
460
- <details>
461
- <summary>
462
- <strong><code>Domain</code></strong>
463
- </summary>
464
- <p>
465
-
466
- The `domain` option expects a string value, which is your Shopify store name without the `myshopify.com` portion. The domain will be used by the CLI as a target argument. Each store (domain) can have multiple themes.
467
-
468
- </p>
469
- </details>
470
-
471
- <details>
472
- <summary>
473
- <strong><code>Themes</code></strong>
474
- </summary>
475
- <p>
476
-
477
- The `themes` option refers to theme ids the store contains. This option is an object type which uses **key** > **value** mappings. The theme **keys** represent a unique target name, this can be any alpha numeric value. The **key** value is used by the CLI as target reference. The **value** should be the theme id.
478
-
479
- </p>
480
- </details>
481
-
482
- # Paths
483
-
484
- The `paths` option allows you to define your theme/projects structure within the defined `input` directory. Syncify does not require you set a development structure required by Shopify and you should begin to decouple from that logic as it is generally flawed and restrictive when building advanced or large scale stores.
485
-
486
- Each path key represents a theme directory or resource point. Path options accept either a `string` or `string[]` array list of glob [anymatch](https://www.npmjs.com/package/anymatch) patterns and can point to files contained within sub-directories of infinite depth. All defined references will automatically resolve to the defined `input` directory starting point, so you do not need to include it within your path definitions.
487
-
488
- There is no restrictions or limitations imposed on structures other than **input** relativity. Syncify will obtain full resolution and build a valid theme structure that Shopify understands when generating an **output**.
489
-
490
- ### Config File
491
-
492
- By default, Syncify assumes you are using a basic (defaults) structure. This structure is certainly not the preferred format and when leveraging Syncify you are encouraged to establish a structure which suits your project and adheres to your workflow or tastes.
493
-
494
- <!-- prettier-ignore -->
495
- ```ts
496
- import { defineConfig } from '@syncify/cli';
497
-
498
- export default defineConfig({
499
- input: 'source',
500
- output: 'theme',
501
- paths: {
502
- assets: 'assets/**',
503
- config: 'config/*.json',
504
- locales: 'locales/*.json',
505
- layout: 'layout/.liquid',
506
- metafields: 'metafields/**/*.json',
507
- sections: 'sections/*.liquid',
508
- snippets: 'snippets/*.liquid',
509
- templates: 'templates/*.liquid',
510
- customers: 'templates/customers/*',
511
- // pages: 'pages/*',
512
- // redirects: 'redirects.yaml',
513
- }
514
- })
79
+ $ pnpm add @syncify/cli@next --global
515
80
  ```
516
81
 
517
- ### Custom Structures
518
-
519
- Below are **2** different **input** structures and an **output** structure. The **default structure** is what Syncify will use (as above) if no `paths` have been defined in your configuration (the tool defaults to this). The **customized structure** is an example of how you _could_ arrange an `input` directory using the Syncify `paths` option. The **output structure** is what Syncify will generated as an **output** which Shopify can digest.
520
-
521
- <table>
522
- <thead>
523
- <tr>
524
- <th width=330px>Default Structure</th>
525
- <th width="330px">Customized Structure</th>
526
- <th width="330px">Output Structure</th>
527
- </tr>
528
- </thead>
529
- <tbody>
530
- <td>
531
- <pre>
532
- <code>
533
-
534
-
535
-
536
- source
537
- └─┐
538
- ├─ assets
539
- ├─ config
540
- ├─ layout
541
- ├─ locales
542
- ├─ pages
543
- ├─ metafields
544
- │ └─ namespace
545
- │ └─ key.json ㅤ
546
- ├─ sections
547
- ├─ snippets
548
- └─ templates
549
- ├─ metaobject
550
- └─ customers
551
-
552
-
553
-
554
- </code>
555
- </pre>
556
- </td>
557
- <td>
558
- <pre>
559
- <code>
560
- source
561
- └─┐
562
- ├── assets
563
- │ ├─ files
564
- │ ├─ icons
565
- │ └─ images
566
- ├─ data
567
- │ ├─ config
568
- │ ├─ locales
569
- │ └─ metafields
570
- │ └─ namespace
571
- │ └─ key.json ㅤ
572
- ├─ styles
573
- ├─ scripts
574
- └─ views
575
- ├─ customers
576
- ├─ meta
577
- ├─ sections
578
- ├─ snippets
579
- ├─ templates
580
- └─ theme.liquid
581
- </code>
582
- </pre>
583
- </td>
584
- <td>
585
- <pre>
586
- <code>
587
- ㅤㅤ
588
-
589
- ㅤ ㅤ
590
- ㅤ ㅤ
591
- ㅤ ㅤ
592
-
593
- output
594
- └─┐
595
- ├─ assets
596
- ├─ config
597
- ├─ locales
598
- ├─ layout
599
- ├─ sections
600
- ├─ snippets
601
- └─ template
602
- ├─ metaobject
603
- └─ customers ㅤ
604
-
605
-
606
-
607
-
608
- </code>
609
- </pre>
610
- </td>
611
- </tr>
612
- </tbody>
613
- </table>
614
-
615
- There is no distributed difference between the **default** and **customized** structures illustrated above. Both would generate an **output** that Shopify understands, requires and reasons with. Only the **input** source locations differ. The **output** Syncify creates will always be written to a standard Shopify theme structure regardless of how you may decide to organize **input** paths. Custom structures give you creative freedom and does not impose a restrictive workflow you may have become behest to working with Dawn and the Shopify CLI.
616
-
617
- Welcome to the better approach, you're welcome.
618
-
619
- ### Options
620
-
621
- <details>
622
- <summary>
623
- <strong><code>Assets</code></strong>
624
- </summary>
625
- <p>
626
-
627
- An array list of glob path patterns for **asset** files. These will be written in the `assets` directory of your defined `output` path. Please note that you if you transforming CSS, SCSS, SASS or SVG file types using Syncify then you do not need to define those paths here as the `transforms` option will automatically route them, this is the same for assets being processed by spawns.
628
-
629
- **Understanding Spawns in watch mode**
630
-
631
- Syncify will automatically set watch paths of assets when running in watch mode. It will glob match all files being written to your defined `{output}/assets` path but exclude those which you have set to be handled or transformed. For example, if you are using a JavaScript bundler like webpack of rollup, Syncify will watch for any files that are written and handled by these tools or any other spawned process for that matter and once written will trigger an upload.
632
-
633
- </p>
634
- </details>
635
-
636
- <details>
637
- <summary>
638
- <strong><code>Customers</code></strong>
639
- </summary>
640
- <p>
641
-
642
- An array list of glob path patterns to `.liquid` or `.json` **customer** template files. These will be written to the `{output}/templates/customers` directory of your defined `output` path.
643
-
644
- </p>
645
- </details>
646
-
647
- <details>
648
- <summary>
649
- <strong><code>Locales</code></strong>
650
- </summary>
651
- <p>
652
-
653
- An array list of glob path patterns to `.json` **locale** files. These will be written to the `{output}/locales` directory of your defined `output` path.
82
+ # Contributing
654
83
 
655
- </p>
656
- </details>
84
+ Contributions are welcome! This project is a monorepo managed with [pnpm](https://pnpm.js.org/) and [changesets](https://github.com/changesets). Dependencies follow the [workspace protocol](https://pnpm.io/workspaces#workspace-protocol-workspace), ensuring a symlinked structure with pnpm managing NPM registry versions. The [packages](/packages/) directory contains modules consumed by the core [syncify](/syncify/) module. To contribute bug fixes or enhancements, you'll need to fork or clone the entire project. Development is designed for use with [VS Code](https://code.visualstudio.com/), and maintaining consistency within this setup is encouraged.
657
85
 
658
86
  <details>
659
87
  <summary>
660
- <strong><code>Config</code></strong>
88
+ Pre-requisites
661
89
  </summary>
662
90
  <p>
663
91
 
664
- An array list of glob path patterns to `.json` **config** files. These will be written to the `{output}/config` directory of your defined `output` path.
665
-
666
- </details>
667
-
668
- <details>
669
- <summary>
670
- <strong><code>Layout</code></strong>
671
- </summary>
672
- <p>
92
+ - [Git](https://git-scm.com/)
93
+ - [Node v20^](https://nodejs.org/)
94
+ - [Pnpm v9^](https://pnpm.js.org/)
95
+ - [VSCode](https://code.visualstudio.com/)
673
96
 
674
- An array list of glob path patterns to `.liquid` **layout** files. These will be written to the `{output}/layout` directory of your defined `output` path.
97
+ > _The `.vscode` workspace settings include all the necessary configurations for the project, ensuring a seamless development environment. It also provides tailored extension recommendations to enhance productivity and maintain consistency._
675
98
 
676
99
  </p>
677
100
  </details>
678
101
 
679
102
  <details>
680
103
  <summary>
681
- <strong><code>Sections</code></strong>
104
+ Third Parties (optional)
682
105
  </summary>
683
- <p>
684
-
685
- An array list of glob path patterns to `.liquid` **section** files. These will be written to the `sections` directory of your defined `output` path. Sections can be structured within sub-directories. If a section file is determined to be deeply nested in such a way then this option will enable parent directory name prefixing to be applied the output filenames.
686
-
687
- **Understanding Section Processing**
688
-
689
- If the section input path is `source/sections/index/some-file.liquid` then the filename will be prefixed with `index` so when referencing it within themes you'd need to use `index-some-file.liquid` in `{% section %}` tags. Prefixing is helpful when you have a large number of sections and want to avoid name collusion.
690
106
 
691
- See also [Views](#views).
692
-
693
- </p>
694
-
695
- </details>
696
-
697
- <details>
698
- <summary>
699
- <strong><code>Snippets</code></strong>
700
- </summary>
701
107
  <p>
702
108
 
703
- An array list of glob path patterns to `.liquid` **snippet** files. These will be written to the `snippets` directory of your defined `output` path.
109
+ - [Potion Theme](https://marketplace.visualstudio.com/items?itemName=sissel.material-potion)
110
+ - [Github Desktop](https://desktop.github.com/)
111
+ - [iTerm2](https://iterm2.com/)
704
112
 
705
- See also [Views](#views).
113
+ > _While not required, if you wish to recreate the environment in which this project is developed then you can install and leverage the above additional third-party tooling._
706
114
 
707
115
  </p>
708
116
  </details>
709
117
 
710
118
  <details>
711
119
  <summary>
712
- <strong><code>Templates</code></strong>
120
+ Installation
713
121
  </summary>
714
122
  <p>
715
123
 
716
- An array list of glob path patterns to `.json` or `.liquid` **template** files. These will be written to the `templates` directory of your defined `output` path.
124
+ - Ensure [pnpm](https://pnpm.js.org/) is installed globally `npm i pnpm -g`
125
+ - Leverage `pnpm env` if you need to align node versions.
126
+ - Clone this repository `git clone https://github.com/panoply/syncify.git`
127
+ - Run `pnpm i` in the root directory
128
+ - Run `pnpm build` which will bundle all packages
717
129
 
718
130
  </p>
719
131
  </details>
720
132
 
721
- <details>
722
- <summary>
723
- <strong><code>Metaobject</code></strong>
724
- </summary>
725
- <p>
726
-
727
- An array list of glob path patterns to `.json` **metaobject** template files. These will be written to the `{output}/templates/metaobject` directory of your defined `output` path.
728
-
729
- </p>
730
- </details>
731
-
732
- # Shared Sections
733
-
734
- Syncify provides an elegant and simple solution for shared sections. This is an experimental feature and aims to provide developers an easy way to re-use section contents between section files containing schema.
735
-
736
- # HOT
737
-
738
- Live reloading is supported in watch mode. Syncify leverages websocket's, XHR and statically served endpoints to provide this capability with zero configuration or the need to install or setup additional tooling. No extensions and no complexities. Syncify will listen for messages sent via websocket on the client and carry out HOT replacements of Assets, Sections, Snippets, Layouts and Templates without triggering full-page refreshes. HOT Reloads can be enabled by passing the `--hot` flag via the CLI.
739
-
740
- > The HOT reload approach Syncify employs tends to be considerably faster than HOT reloading with the Shopify CLI.
741
-
742
- ### Assets
743
-
744
- SASS/CSS, TypeScript/JavaScript and SVG asset file types are HOT reloaded by swapping out the URL's or containing source with localhost equivalents served statically by Syncify.
745
-
746
- ### Section
747
-
748
- Dynamic sections, static sections of a combination of both are fetched via the Ajax [Section rendering API](https://shopify.dev/docs/api/section-rendering). Replacements are applied to fragments in real-time and surrounding nodes are left intact.
749
-
750
- ### Snippets, Layouts and Templates
751
-
752
- In order to provide HOT replacements Syncify employs a mild form of DOM hydration. Snippets, templates and Liquid/JSON layout files will inject HTML comments `<!-- hot:1aa4f32cf9 -->` containing a UUID before they are uploaded to themes. Syncify will pass this UUID to the client via websocket and once received an XHR (fetch) will be triggered. The response of the XHR request is then parsed and all nodes which proceed the injected UUID comment/s are plucked and swapped in the persisted DOM while leaving unchanged elements intact. The approach employed by Syncify is a mild form DOM hydration that's 10x faster than invoking a hard-refresh.
753
-
754
- ## Programmatic Control
755
-
756
- Running in HOT mode will result in Syncify injecting a snippet into layouts. The snippet is the socket receiver that is responsible for executing replacements/morphs and exposes programmatic control for developers who can to customize or hook into the HOT reload rendering cycles.
757
-
758
- ```ts
759
- // STATUS
760
- //
761
- window.syncify.ready: boolean
762
- window.syncify.connected: boolean;
763
-
764
- // RELOADS
765
- //
766
- window.syncify.assets(): void;
767
- window.syncify.reload(): void;
768
- window.syncify.refresh(): void
769
-
770
- // SECTIONS
771
- //
772
- window.syncify.sections.get()
773
- window.syncify.sections.list()
774
- window.syncify.sections.load()
775
-
776
- // LABEL
777
- //
778
- window.syncify.style.parent({ /* CSS */ });
779
- window.syncify.style.label({ /* CSS */ });
780
- ```
781
-
782
- # Pages
783
-
784
- Syncify supports page sync and employs an intuitive approach to working with static pages for stores. The [paths](#paths) **pages** option is where you can provide path file references to be synced. Pages in Syncify can be either `.html` (markup) or `.md` (markdown) files and cannot contain Liquid syntax (Shopify does not support Liquid in pages only static markup). Syncify also support frontmatter in page files, this allows you to pass in additional data when syncing to store/s.
785
-
786
- ### Options
787
-
788
- The `pages` setting available in the `views` option of your `syncify.config.ts` file allows you to configure page processing and transforms. In Syncify, frontmatter can be used to configure per-page control.
789
-
790
- <!--prettier-ignore-->
791
- ```js
792
- import { defaultConfig } from '@syncify/cli'
793
-
794
- export default defineConfig({
795
- ...,
796
- paths: {
797
- // Set the location of page files
798
- pages: [
799
- 'pages/*.md',
800
- 'pages/*.html'
801
- ]
802
- },
803
- views: {
133
+ ## Development Guide
804
134
 
805
- pages: {
806
- suffixDir: false, // When true, directory name will be used for template_suffix
807
- safeSync: true, // Ensure local and remote versions are aligned
808
- author: '', // Fallback author name
809
- global: [], // List of directories to exclude from applying template_suffix
810
- importLanguage: 'html' // Set the import language when remote sources sync to local ones
811
- }
135
+ All packages are compiled using [ESBuild](https://esbuild.github.io/) through [tsup](https://tsup.egoist.sh). You can either cd into any package directory to run commands, or from the workspace root, you can execute pnpm dev. The pnpm dev command initializes development in watch mode and concurrently compiles both the core [syncify](/syncify/) package and the [docs](/docs/). Keep in mind that Syncify is distributed as CommonJS (CJS) but is compatible with ES modules (ESM) as it exports as a CLI Binary.
812
136
 
813
- }
814
- })
815
- ```
816
-
817
- ### Remote and Local sources
818
-
819
- By default, syncify will perform **safe** synchronization. The `safeSync` option instructs syncify to pull down remote versions before uploading local ones in watch and upload modes. This operation ensures that you do not overwrite page content in situations where changes have been applied in your store since the last sync was performed on your local machine. Syncify will prompt you when misalignment is detected and allow you to pull in the remote versions.
820
-
821
- ### Markdown Support
137
+ ### Per Package
822
138
 
823
- Pages can be written in markdown, Syncify will transform `.md` page files into valid HTML markup when syncing. Markdown pages are parsed and transformed using the the powerful [markdown-it](https://github.com/markdown-it/markdown-it) and support Github flavored markdown syntax. In addition to Markdown → HTML generation, Syncify can also perform reversed conversion (HTML → Markdown). Using the `importLanguage` option, any time a remote to local alignment is carried out, files will be written in markdown.
824
-
825
- ### Frontmatter Support
826
-
827
- You can pass frontmatter data in page files. Page frontmatter can be used to control per-page publishing settings and allows for additional request payloads to be passed. Syncify supports a modest schema structure for page frontmatter.
828
-
829
- <!-- prettier-ignore -->
830
- ```yaml
831
- ---
832
- title: 'Lorem Ipsum' # The page title
833
- handle: '/some-handle' # Custom page handle
834
- template: 'example' # Specify a template_suffix
835
- published: true # Whether the page is published
836
- links: false # Auto-convert URL-like
837
- breaks: true # Convert '\n' into `<br>`
838
- metafields: # Pass in additional metafields
839
- - namespace: 'foo'
840
- key: 'greeting'
841
- type: 'single_line_text_field'
842
- value: 'Hello World!'
843
- - namespace: 'bar'
844
- key: 'some_condition'
845
- type: 'boolean'
846
- value: true
847
- ---
139
+ ```bash
140
+ pnpm dev # Watch and build modes
141
+ pnpm build # Build mode only (production)
848
142
  ```
849
143
 
850
- # Metafields
144
+ > [!NOTE]
145
+ > Almost all packages will expose the above commands via `package.json` script, with some exceptions depending on module. The `pnpm build` command however is available within all modules.
851
146
 
852
- ###### NOT YET AVAILABLE
147
+ ### Recursive (Workspace Root)
853
148
 
854
- The `metafields` directory `path` reference is where you can provide **global** JSON metafield files that can be synced to your Shopify store. Metafield sync capabilities provided by Syncify use a simple **directory** > **file** based approach. The sub-directory names represent a metafield `namespace` value and JSON file names contained within represent metafield `key` values.
855
-
856
- > Syncify will keep your remote and local metafield references aligned with one another and warn you when local versions do not match remote versions. This will help prevent you from overwriting changes that may have been applied by third-party apps or online within your store.
857
-
858
- **Pull Metafields**
859
-
860
- Syncify provides you with simple interactive prompt based approach for importing pre-existing metafields from your online store. You can optionally choose which metafields you'd like to maintain. Use the `-m` or `--metafields` flag together with the `--pull` flag on the command line to download metafields:
861
-
862
- ```
863
- $ syncify --metafields --pull
149
+ ```bash
150
+ pnpm build # Build production bundles for all modules and packages
864
151
  ```
865
152
 
866
- **Merge Metafields**
153
+ ### Targeting (Workspace Root)
867
154
 
868
- Working with metafields from your local machine may have result in unexpected overwrites if changes were made to remote versions that conflict with local versions. In order to combat this Syncify support **merge** capabilities which can be used to merge changes when metafield modification timestamps differ. Use the `-m` or `--metafields` flag together with the `--merge` flag on the command line perform local and remote alignments.
869
-
870
- ```
871
- $ syncify --metafields --merge
155
+ ```bash
156
+ pnpm @acquire <cmd> # Targets the @syncify/acquire acquire config bundle
157
+ pnpm @ansi <cmd> # Targets the @syncify/ansi CLI enhancement package
158
+ pnpm @config <cmd> # Targets the @syncify/config configuration package
159
+ pnpm @glue <cmd> # Targets the @syncify/glue Glue utility package
160
+ pnpm @codframe <cmd> # Targets the @syncify/codeframe Codeframe CLI package
161
+ pnpm @hot <cmd> # Targets the @syncify/hot HOT Reloading client
162
+ pnpm @json <cmd> # Targets the @syncify/json JSON parser and differ
163
+ pnpm @kill <cmd> # Targets the @syncify/kill process kill package
164
+ pnpm @turndown <cmd> # Targets the @syncify/turndown reversed markdown parser
165
+ pnpm @timer <cmd> # Targets the @syncify/timer timing utility
166
+ pnpm @update <cmd> # Targets the @syncify/update version check utility
167
+ pnpm @uws <cmd> # Targets the @syncify/uws uWebsockets repackage
168
+ pnpm @cli <cmd> # Targets the @syncify/cli package (main package)
872
169
  ```
873
170
 
874
- **Structure**
875
-
876
- In order to best illustrate how the metafield sync capabilities work it is important that you understand the structure logic. The directory based approach and naming conventions employed are imperative and strict. Syncify wants to prevent irreversible overwrites or deletions from occurring, so please be mindful and wary when using this feature.
171
+ ### GraphQL Introspection and Typings
877
172
 
878
- <table>
879
- <thead>
880
- <tr>
881
- <th align="left" width="300px">&nbsp;&nbsp;&nbsp;&nbsp;Metafield Structure</th>
882
- <th align="left" width="700px">&nbsp;&nbsp;&nbsp;&nbsp;Description</th>
883
- </tr>
884
- </thead>
885
- <tbody>
886
- <td>
887
- <pre>
888
- <code>
889
- source
890
-
891
- └── metafields
892
-
893
- ├── garment
894
- │ ├── fits.json
895
- │ ├── sizes.json
896
- │ └── fabrics.json ㅤㅤ ㅤㅤ ㅤㅤ
897
-
898
- └── details
899
- ├── colors.json
900
- └── weight.json
901
- </code>
902
- </pre>
903
- </td>
904
- <td>
905
- &nbsp;&nbsp;&nbsp;Metafields will be published to the global <code>shop</code> object.<br>
906
- &nbsp;&nbsp;&nbsp;Syncify will use the sub-directory names as the metafield<br>
907
- &nbsp;&nbsp;&nbsp;<code>namespace</code> and the JSON file names contained within<br>
908
- &nbsp;&nbsp;&nbsp;each namespace directory are used as the metafield <code>key</code> name.<br><br>
909
- <strong>Example:</strong><br><br>
910
- <ul>
911
- <li><code>{{ shop.metafields.garment.fits.value }}</code></li>
912
- <li><code>{{ shop.metafields.garment.sizes.value }}</code></li>
913
- <li><code>{{ shop.metafields.garment.fabrics.value }}</code></li>
914
- <li><code>{{ shop.metafields.details.colors.value }}</code></li>
915
- <li><code>{{ shop.metafields.details.weight.value }}</code></li>
916
- </ul>
917
- </td>
918
- </tr>
919
- </tbody>
920
- </table>
173
+ Syncify does not use Shopify OSS offerrings, you will find zero `@shopify/*` projects in the codebase. Interfacing with the Shopify API is handled with a custom client. The client is extensively typed and the TypeScript definitions are generated using [codegen](https://the-guild.dev/graphql/codegen). The repository comes with definitions and introspection included so there is no need to pull or regenerate.
921
174
 
922
- ### Options
175
+ # Author / License
923
176
 
924
- <details>
925
- <summary>
926
- <strong><code>Input</code></strong>
927
- </summary>
928
- <p>
177
+ Syncify was created and is maintained by [Νικολας Σαββιδης](https://github.com/panoply). Shopify has no affiliation with this project and does not fund Syncify; it is a completely independent solution. Choosing to leverage Syncify helps keep these independent projects alive and sends a clear message to Shopify that the community drives innovation.
929
178
 
930
- The `input` option refers to your projects **src** location This is the directory where your development theme files exist. Syncify defaults this directory to `source`. The value defined here will be prepended to any path you define within `paths`.
179
+ ### Acknowledgements
931
180
 
932
- </p>
933
- </details>
181
+ Special thanks to the talented developers who have contributed to Syncify. This project has been in development for several years, and without these individuals, it wouldn't have progressed this far.
934
182
 
935
- <details>
936
- <summary>
937
- <strong><code>Output</code></strong>
938
- </summary>
939
- <p>
183
+ - [Kim Skinner](https://github.com/WolfGreyDev)
184
+ - [Mansedan](https://github.com/webdeveman)
185
+ - [Taksh](https://github.com/taksh108)
186
+ - [David Warrington](https://ellodave.dev/)
940
187
 
941
- The `output` option refers to your project **dist** location. This is the directory where transformed theme files from `input` will be written. Syncify defaults this to `theme`. The `output` directory will be reflective of your online shop. You should point any asset files executing via spawned processes to the `assets` directory contained within this location.
188
+ ### Donate / Sponsor
942
189
 
943
- </p>
944
- </details>
945
-
946
- <details>
947
- <summary>
948
- <strong><code>Config</code></strong>
949
- </summary>
950
- <p>
951
-
952
- The `config` option refers to a directory within your project where configuration files exist, like (for example) a `rollup.config.js` or `webpack.config.js` file. Syncify by default (when this option is **undefined**) will look for config files in the root of your project but this might not always be ideal as it can create clutter in the workspace. The `config` directory allows you to optionally place spawned config files within a sub-directory and informs Syncify to look for these files from that location.
953
-
954
- > Typically this is directory is named `scripts` in node projects.
955
-
956
- </p>
957
- </details>
958
-
959
- <details>
960
- <summary>
961
- <strong><code>Import</code></strong>
962
- </summary>
963
- <p>
964
-
965
- The `import` option refers to a directory where downloaded themes will be written. Syncify provides the ability to download themes from your online store and it is within this directory the files are created.
966
-
967
- </p>
968
- </details>
969
-
970
- <details>
971
- <summary>
972
- <strong><code>Export</code></strong>
973
- </summary>
974
- <p>
975
-
976
- The `export` option refers to a directory where packaged (`.zip`) themes will be written when running the `package` command. Packaged themes will be prepended with the version number defined in the projects `package.json` file.
977
-
978
- </p>
979
- </details>
980
-
981
- <details>
982
- <summary>
983
- <strong><code>Metafields</code></strong>
984
- </summary>
985
- <p>
986
-
987
- The `metafields` option refers to a directory within your project which can contain global JSON metafield files. The path location you reference here should point to a directory of sub-directories. Please refer to the [Metafields](#metafields) section for more information.
988
-
989
- **Correct**
990
-
991
- ```
992
- {
993
- "dirs": {
994
- "metafields": "source/metafields"
995
- }
996
- }
997
- ```
998
-
999
- **Invalid**
1000
-
1001
- ```
1002
- {
1003
- "dirs": {
1004
- "metafields": "source/metafields/**/*.json"
1005
- }
1006
- }
1007
- ```
1008
-
1009
- </p>
1010
- </details>
1011
-
1012
- # Spawn
1013
-
1014
- The spawn option accepts a **key** > **value** list of commands (i.e: scripts) which can be used when running in **watch** (`--watch`) or **build** (`--build`) modes. The Spawn configuration option allows you to leverage additional build tools and have them execute in parallel with Syncify as child processes.
1015
-
1016
- Spawned processes allow you use your preferred asset bundlers such as [Rollup](#), [Webpack](#), [Gulp](#) and many more without having to run multiple npm-scripts.
1017
-
1018
- ### Overview
1019
-
1020
- There are 2 available modes from which you can trigger a spawned process. When a process is spawned in `watch` mode it will run along side Syncify in parallel and execute sequentially in the order of which each spawn is defined. You need to provide any --flags your command (build tool or bundler) requires when running. Spawning a process in `build` mode will trigger spawned commands only 1 time, so it is here where you would provide the compile-only or build-only command, ie: not using watch flags/arguments.
1021
-
1022
- The Syncify **build** mode re-builds the entire theme and you might choose to run this mode using the Syncify `--prod` flag, if you require context of the environment, mode or action taking place within spawned config files, then take a look at the available [Utilities](#utilities) which Syncify exposes to help conditionally load plugins or trigger different build types in accordance with the Syncify execution cycle.
1023
-
1024
- ### CLI
1025
-
1026
- ```bash
1027
- --spawn, -s <name> # spawn targeting
1028
- ```
1029
-
1030
- ### Configuration
1031
-
1032
- <!-- prettier-ignore -->
1033
- ```ts
1034
- import { defineConfig } from '@syncify/cli';
1035
-
1036
- export default defineConfig({
1037
-
1038
- // ...
1039
-
1040
- spawn: {
1041
- build: {},
1042
- watch: {}
1043
- }
1044
- }
1045
- })
1046
- ```
1047
-
1048
- ## Usage
1049
-
1050
- In most situations you will leverage the spawn option to compile something like TypeScript or JavaScript but it is important to note that this capability is not specific to these assets types. Syncify is using [cross-spawn](https://www.npmjs.com/package/cross-spawn) under the hood to help negate any cross-platform issues that may arise. Below are a couple examples where we spawn up 2 well known JavaScript bundlers and lastly we illustrate how to spawn multiple processes.
1051
-
1052
- > All stdout/stderr/stdio from spawned processes will be piped through and intercepted by Syncify, which might result in output being stripped of color.
1053
-
1054
- ### Rollup Example
1055
-
1056
- If you are processing JavaScript asset files using the [Rollup](https://rollupjs.org/) bundler you can spawn build and watch processes by providing the rollup commands to each mode accordingly. Rollup is a fantastic choice for handling `.js` files. In this example, it is assumed that a `rollup.config.js` file is located in the root of your project.
1057
-
1058
- <!-- prettier-ignore -->
1059
- ```ts
1060
- import { defineConfig } from '@syncify/cli';
1061
-
1062
- export default defineConfig({
1063
- spawn: {
1064
- build: {
1065
- rollup: 'rollup -c'
1066
- },
1067
- watch: {
1068
- rollup: 'rollup -c -w'
1069
- }
1070
- }
1071
- }
1072
- })
1073
- ```
1074
-
1075
- ### Webpack Example
1076
-
1077
- If you are processing JavaScript asset files using the [Webpack](https://webpack.js.org/) bundler you can spawn build and watch processes by providing the webpack commands to each mode accordingly. You will need to be using the [Webpack CLI](https://github.com/webpack/webpack-cli) module to ensure a successful spawn is triggered.
1078
-
1079
- > Notice how we also provide the `--color` flag in the spawn. If you omit this flag then the webpack logs will be printed to the CLI without colors, when using webpack you should provide this flag.
1080
-
1081
- <!-- prettier-ignore -->
1082
- ```ts
1083
- import { defineConfig } from '@syncify/cli';
1084
-
1085
- export default defineConfig({
1086
- spawn: {
1087
- build: {
1088
- webpack: 'webpack --color'
1089
- },
1090
- watch: {
1091
- webpack: 'webpack --watch --color'
1092
- }
1093
- }
1094
- }
1095
- })
1096
- ```
1097
-
1098
- ### Multiple Processes
1099
-
1100
- Though it is unlikely you'd ever need to include 2 different JavaScript bundlers in a project there is nothing stopping you from doing such a thing. For the sake of brevity, the below example illustrates how we can execute multiple spawned child processes to run in parallel with Syncify. Notice how we have also included an additional **gulp** spawn in `build` and `watch` modes. Syncify will trigger these processes in sequentially order, Rollup (1), Gulp (2) and Webpack (3).
1101
-
1102
- > Aside from attempting to spawn Syncify itself, there is no limitation or restrictions imposed on what you choose to run along side Syncify.
1103
-
1104
- <!-- prettier-ignore -->
1105
- ```ts
1106
- import { defineConfig } from '@syncify/cli';
1107
-
1108
- export default defineConfig({
1109
- spawn: {
1110
- build: {
1111
- rollup: 'rollup -c',
1112
- webpack: 'webpack --color',
1113
- gulp: 'gulp watch-task'
1114
- },
1115
- watch: {
1116
- webpack: 'webpack --watch --color',
1117
- rollup: 'rollup -c -w',
1118
- gulp: 'gulp watch-task'
1119
- }
1120
- }
1121
- }
1122
- })
1123
- ```
1124
-
1125
- # Transform
1126
-
1127
- In Syncify, asset files can be transformed before being written to the defined `output` directory and uploaded to your Shopify store. The `transform` option provides users with control of the "asset pipeline" and Syncify exposes configuration wrappers for handling files together with modern developer tooling. Transforms are totally optional, and require you to provide additional modules in your project.
1128
-
1129
- Syncify supports built-in and partial processing for the following file types:
1130
-
1131
- - `.json`
1132
- - `.js`
1133
- - `.ts`
1134
- - `.jsx`
1135
- - `.tsx`
1136
- - `.css`
1137
- - `.scss`
1138
- - `.sass`
1139
- - `.svg`
1140
-
1141
- ## Scripts
1142
-
1143
- Syncify exposes a `script` transform option which supports TypeScript (`.ts` and `.tsx`) and/or JavaScript (`.js` and `.jsx`) bundling using [ESBuild](https://esbuild.github.io/). Script transforms use a pre-defined set of processing configurations and will produce lean JavaScript bundles designed to work seamlessly in development mode or when leveraging HOT reloads. Syncify will also apply refinements to distribution bundles focused on performance when generating production builds for your Shopify theme.
1144
-
1145
- > ESBuild is the same bundler used under the hood by tools like [vite](https://vitejs.dev/) and [tsup](https://tsup.egoist.sh). If you are using existing tools like Webpack or Rollup, consider adopting ESBuild as its a far superior option.
1146
-
1147
- ### Installing ESBuild
1148
-
1149
- In order for you to leverage **script** transforms, you will need to install ESBuild as a development dependency. Syncify will complain if you try to use script options without esbuild installed.
1150
-
1151
- ```bash
1152
- pnpm add esbuild -D
1153
- ```
1154
-
1155
- ### Bundling TypeScript
1156
-
1157
- The **script** transform option aims to make bundling easy but also extensible for more advanced use cases. Syncify will automatically detect `tsconfig.json` (or `jsconfig.json`) files located in your workspace and respect processing options defined within. By default, Syncify will produce **ESM** module formats that output in **ES2016** but you can also generate **IIFE** bundles and even inline code as a snippets within `<script></script>` tags.
1158
-
1159
- The `script` options accepts several different structures and it is up to you how you wish to provide settings. The below code sample depicts the default configuration structure:
1160
-
1161
- <!--prettier-ignore-->
1162
- ```ts
1163
- import { defineConfig } from '@syncify/cli';
1164
-
1165
- export default defineConfig({
1166
- transforms: {
1167
- script: [
1168
- {
1169
- input: [],
1170
- format: 'esm',
1171
- target: 'es2016',
1172
- snippet: false,
1173
- rename: '',
1174
- external: [],
1175
- watch: [],
1176
- esbuild: {}
1177
- }
1178
- ]
1179
- }
1180
- })
1181
- ```
1182
-
1183
- You may prefer to use rename (entry point) structures instead. When we are using rename entry points the prefix path expects either `snippets/` or `assets/` be provided. When passing `snippets/` then a snippet will be generated, whereas `assets/` will generate a `.js` file.
1184
-
1185
- > Rename entry points accept `[file]`, `[dir]` and `[ext]` placeholders.
1186
-
1187
- <!--prettier-ignore-->
1188
- ```ts
1189
- import { defineConfig } from '@syncify/cli';
1190
-
1191
- export default defineConfig({
1192
- transforms: {
1193
- script: {
1194
-
1195
- // Producing 2 inline snippet <script> bundles
1196
- // Output will be slideshow.js.liquid and search-form.js.liquid
1197
- 'snippets/[file][ext]': [
1198
- 'scripts/sections/slideshow.ts',
1199
- 'scripts/sections/search-form.ts'
1200
- ]
1201
-
1202
- // Producing an IIFE script as an asset
1203
- // The return value is accessible via window.Foo
1204
- 'assets/foo.min.js': {
1205
- input: 'scripts/index.ts',
1206
- format: 'iife',
1207
- globalName: 'window.Foo,
1208
- }
1209
- }
1210
- }
1211
- })
1212
- ```
1213
-
1214
- ## Styles
1215
-
1216
- ###### TAILWIND IS NOT YET SUPPORT
1217
-
1218
- Syncify exposes a `style` transform option which can be used for CSS (`.css`) and SCSS/SASS (`.scss` or `.sass`) bundling. Style transform support is made possible by using compilers like [Dart SASS](#), [PostCSS](#) and/or [Tailwind](#). The `style` option provides developers with replicated configuration control but you may also prefer to use standard config files (e.g: `postcss.config.js`) which Syncify also supports.
1219
-
1220
- Style transforms help alleviate the complexities sometimes involved in setting up these tools so you can easily process asset specific stylesheets or generate output as a **snippet** within `<style></style>` tags.
1221
-
1222
- ### SASS Support
1223
-
1224
- Syncify provides SCSS/SASS transform support for `.scss` and `.sass` file types using [Dart SASS](#). Using SASS required you to install the Dart module as a development dependency in your project. Syncify will complain if you try to use SASS transforms without Dart SASS installed.
1225
-
1226
- ```bash
1227
- pnpm add sass -D
1228
- ```
1229
-
1230
- ### Tailwind Support ~ COMING SOON
1231
-
1232
- Syncify supports TailwindCSS for CSS processing. If you require transform support for Tailwind, you need to install the TailwindCSS module as a development dependency in your project. Syncify will ignore Tailwind class name occurrences without the module installed.
1233
-
1234
- ```bash
1235
- pnpm add tailwindcss -D
1236
- ```
1237
-
1238
- > Tailwind is not yet available in the beta.
1239
-
1240
- ### PostCSS Support
1241
-
1242
- In addition to SASS transformation, Syncify also support CSS (post)-processing using [PostCSS](#). If you wish have Syncify handle CSS transforms then you need to install **PostCSS** as a development dependency. Syncify will complain if you try to use PostCSS transforms without PostCSS installed.
1243
-
1244
- > Provide PostCSS plugins and any specific settings within the `postcss.config.js` file.
1245
-
1246
- ```
1247
- pnpm add postcss -D
1248
- ```
1249
-
1250
- **Please note:** If you are using Syncify to compile SASS files, then by default the transformed CSS will be passed to PostCSS.
1251
-
1252
- ### Usage
1253
-
1254
- In the below example we are generating multiple stylesheets and compiling both SCSS and CSS file types. The example illustrates how one can leverage Syncify together with [Dart SASS](#), [PostCSS](#) and additional node modules like the Bootstrap framework.
1255
-
1256
- > **Please Note** You will need to remove the comments from the code example if you are copy and pasting it into your `package.json` file. JSON with Comments is not supported in `package.json` files.
1257
-
1258
- <!-- prettier-ignore-->
1259
- ```ts
1260
- import { defineConfig } from '@syncify/cli'
1261
-
1262
- export default defineConfig({
1263
- transforms: {
1264
- style: {
1265
- 'assets/stylesheet.min.css': {
1266
- input: 'styles/stylesheet.scss',
1267
- watch: ['styles/sections/*'],
1268
- postcss: true,
1269
- sass: true
1270
- },
1271
- 'snippets/css.liquid': {
1272
- input: 'styles/vars.css.liquid',
1273
- postcss: true,
1274
- sass: true
1275
- },
1276
- 'assets/bootstrap.min.scss': {
1277
- input: 'styles/vendors/bootstrap.scss',
1278
- style: 'expanded',
1279
- includePaths: ['node_modules/bootstrap']
1280
- }
1281
- }
1282
- }
1283
- })
1284
- ```
1285
-
1286
- ## Views
1287
-
1288
- The `views` transform option controls how `.liquid` file types should be handled. Snippets, Templates, Sections and Layout paths are typically where liquid files are used. Options defined here will be used when Syncify is processing such types.
1289
-
1290
- ### Sections
1291
-
1292
- Syncify provides sub-directory grouping and rename prefixing capabilities when handling theme sections. You might be accustom to storing sections within a single directory and despite Shopify using this approach in their Dawn theme, it is restrictive and rather chaotic to the developer experience. A far better approach is to take advantage of the sub-directory grouping feature which Syncify provides.
1293
-
1294
- **Sub-directory Grouping**
1295
-
1296
- Shopify shipped "sections everywhere" capabilities in Online Store 2.0 and while this is a great feature to have it opens the door to inconsistent structures. The logic of Shopify here has been to provide store developers "freedom" but it is a double edged sword. Sections everywhere has consequently resulted in developers indirectly facilitating merchants the ability to leverage sections on pages where they should otherwise be avoided. For instance, enabling merchants to add a featured-collection, featured-blog or full-screen hero image to product pages is not necessarily a good idea. Developers may be more inclined to provide such section types when working from within a single directory structure that is without organized order.
1297
-
1298
- Shopify tends to push a DRY infrastructure approach for the theme development wherein store sections _should_ be capable of appropriation within any template. This is great in theory but in order to achieve aesthetic fluidity it is not realistic when we go beyond a Dawn structure and even there we find the utter chaos. Approaching things in a compartmentalized manner is just better approach but this is difficult when working from a single level structured directory.
1299
-
1300
- Grouping section into sub-directories results is far better consideration, organization and order at the development level. Syncify provides these capabilities while still respecting developer personal preferences. Below is an example of how you can leverage Syncify to use sub-directories together with pre-fixing capabilities.
1301
-
1302
- <!-- prettier-ignore -->
1303
- <table>
1304
- <thead>
1305
- <tr>
1306
- <th>Syncify Options</th>
1307
- <th>Source Structure</th>
1308
- <th>Theme Output</th>
1309
- </tr>
1310
- </thead>
1311
- <tbody>
1312
- <td>
1313
-
1314
- <!-- prettier-ignore -->
1315
- ```json
1316
- {
1317
- "paths": {
1318
- "sections": [
1319
- "sections/**/*"
1320
- ]
1321
- },
1322
- "sections": {
1323
- "prefix": true,
1324
- "prefixSeparator": "-",
1325
- "prefixDuplicates": true,
1326
- "globals": [
1327
- "shared",
1328
- "layout",
1329
- "related.liquid"
1330
- ]
1331
- }
1332
- }
1333
- ```
1334
-
1335
- </code>
1336
- </td>
1337
- <td>
1338
- <pre>
1339
- <code>ㅤ
1340
- source
1341
-
1342
- └─ sections
1343
- ├─ collection
1344
- │ ├─ filter.liquid
1345
- │ └─ search.liquid
1346
- ├─ product
1347
- │ ├─ images.liquid
1348
- │ ├─ on-sale.liquid
1349
- │ └─ related.liquid
1350
- ├─ layout
1351
- │ ├─ header.liquid
1352
- │ └─ footer.liquid
1353
- └─ shared
1354
- ├─ banner.liquid
1355
- └─ slideshow.liquid
1356
- </code>
1357
- </pre>
1358
- </td>
1359
- <td>
1360
- <pre>
1361
- <code>
1362
-
1363
-
1364
- theme
1365
-
1366
- └─ sections
1367
- ├─ banner.liquid
1368
- ├─ collection-filter.liquid
1369
- ├─ collection-search.liquid
1370
- ├─ footer.liquid
1371
- ├─ header.liquid
1372
- ├─ product-images.liquid
1373
- ├─ product-on-sale.liquid
1374
- ├─ related.liquid
1375
- └─ slideshow.liquid
1376
-
1377
-
1378
- </code>
1379
- </pre>
1380
- </td>
1381
- </tr>
1382
- </tbody>
1383
- </table>
1384
-
1385
- Notice how we can nest sections within sub-directories and also apply prefixing to the section output filenames. We also inform Syncify that some of our sections should be considered **global** and this allows those defined there to pass through without name augmentation (prefixing). We passed a `true` value to the `prefix` option, this informed Syncify that section files which are not explicitly defined as **global** should have their output filename prefixed with the **parent** directory name they are contained within.
1386
-
1387
- <details>
1388
- <summary>
1389
- <strong><code>Sections</code></strong>
1390
- </summary>
1391
- <p>
1392
-
1393
- **prefix**
1394
-
1395
- **prefixDuplicates**
1396
-
1397
- **prefixSeparator**
1398
-
1399
- **globals**
1400
-
1401
- </p>
1402
- </details>
1403
-
1404
- <details>
1405
- <summary>
1406
- <strong><code>Minify</code></strong>
1407
- </summary>
1408
- <p>
1409
-
1410
- **env**
1411
-
1412
- `never`
1413
-
1414
- **minifyJS**
1415
-
1416
- `boolean`
1417
-
1418
- **minifyCSS**
1419
-
1420
- `boolean`
1421
-
1422
- **removeComments**
1423
-
1424
- `boolean`
1425
-
1426
- **collapseWhitespace**
1427
-
1428
- `boolean`
1429
-
1430
- **trimCustomFragments**
1431
-
1432
- `boolean`
1433
-
1434
- **ignoreCustomFragments**
1435
-
1436
- `string[]`
1437
-
1438
- **minifySectionSchema**
1439
-
1440
- `boolean`
1441
-
1442
- **removeLiquidComments**
1443
-
1444
- `boolean`
1445
-
1446
- **removeAttributeNewlines**
1447
-
1448
- `boolean`
1449
-
1450
- **removeRedundantDashTrims**
1451
-
1452
- `boolean`
1453
-
1454
- **ignoredLiquidTags**
1455
-
1456
- `string[]`
1457
-
1458
- **exclude**
1459
-
1460
- `string[]`
1461
-
1462
- </p>
1463
- </details>
1464
-
1465
- ### Json
1466
-
1467
- The `json` transform option controls how `.json` files should be processed. Templates, Config, Locales and Metafields paths typically where JSON files are used. Options defined here will be used when Syncify is processing these file types. In addition, Syncify will also apply handle any Assets that have `.json` extension using these options.
1468
-
1469
- <details>
1470
- <summary>
1471
- <strong><code>Spaces</code></strong>
1472
- </summary>
1473
- <p>
1474
-
1475
- Beautification `2`
1476
-
1477
- </p>
1478
- </details>
1479
-
1480
- <details>
1481
- <summary>
1482
- <strong><code>Minify</code></strong>
1483
- </summary>
1484
- <p>
1485
-
1486
- Minification options
1487
-
1488
- **env**
1489
-
1490
- `never`
1491
-
1492
- **removeSchemaRefs**
1493
-
1494
- `true`
1495
-
1496
- **exclude**
1497
-
1498
- `string[]`
1499
-
1500
- </p>
1501
- </details>
1502
-
1503
- ### Styles
1504
-
1505
- The `styles` transform option accepts an array type. This option requires you have [Dart SASS](#) and/or [PostCSS](#) installed as a development dependencies in your project. Syncify supports the handling of `.sass`, `.scss` and `.css` file types using these tools and the options are convenience wrappers for them.
1506
-
1507
- <details>
1508
- <summary>
1509
- <strong><code>Input</code></strong>
1510
- </summary>
1511
- <p>
1512
-
1513
- Path `string[]` or `string`
1514
-
1515
- </p>
1516
- </details>
1517
-
1518
- <details>
1519
- <summary>
1520
- <strong><code>Rename</code></strong>
1521
- </summary>
1522
- <p>
1523
-
1524
- Rename Options
1525
-
1526
- `string[]`
1527
-
1528
- </p>
1529
- </details>
1530
-
1531
- <details>
1532
- <summary>
1533
- <strong><code>Watch</code></strong>
1534
- </summary>
1535
- <p>
1536
-
1537
- Watch Options
1538
-
1539
- `string[]`
1540
-
1541
- </p>
1542
- </details>
1543
-
1544
- <details>
1545
- <summary>
1546
- <strong><code>Snippet</code></strong>
1547
- </summary>
1548
- <p>
1549
-
1550
- `boolean`
1551
-
1552
- </p>
1553
- </details>
1554
-
1555
- <details>
1556
- <summary>
1557
- <strong><code>PostCSS</code></strong>
1558
- </summary>
1559
- <p>
1560
-
1561
- PostCSS options
1562
-
1563
- **env**
1564
-
1565
- `all`, `dev`, `prod` `never`
1566
-
1567
- </p>
1568
- </details>
1569
-
1570
- <details>
1571
- <summary>
1572
- <strong><code>SASS</code></strong>
1573
- </summary>
1574
- <p>
1575
-
1576
- **logWarnings**
1577
-
1578
- `boolean`
1579
-
1580
- **sourcemap**
1581
-
1582
- `boolean`
1583
-
1584
- **style**
1585
-
1586
- `compressed` or `expanded`
1587
-
1588
- </p>
1589
- </details>
1590
-
1591
- # Processors
1592
-
1593
- In Syncify, **processors** refer to the external tools used in [Transforms](#transform) (i.e: SVGO, ESBuild SASS etc). The `processors` configuration option provides developers a point of control for configuring these (supported) _third party_ modules. The configurations defined in processors will used as the defaults bundling options of each transform and allows developers to retain a single point of control from which all _third party_ processor operations will refer, this saves you having to include multiple external config files in your projects workspace.
1594
-
1595
- <!-- prettier-ignore -->
1596
- ```ts
1597
- import { defineConfig } from '@syncify/cli'
1598
-
1599
- export default defineConfig({
1600
-
1601
- // ...
1602
-
1603
- processors: {
1604
- json: {}, // applied to json transforms
1605
- esbuild: {}, // applied to script transforms
1606
- sass: {}, // applied to style transforms
1607
- postcss: [], // applied to style transforms
1608
- tailwind: {}, // applied to style transforms
1609
- svgo: {}, // applied to svg transforms
1610
- sprite: {}, // applied to svg transforms
1611
- sharp: {}, // applied to img transforms
1612
- }
1613
- })
1614
- ```
1615
-
1616
- > Using processors requires installing the relative module you'd like to leverage. This is an opt-in capability.
1617
-
1618
- ### External Config Files
1619
-
1620
- Some third party tools allow (or require) config file usage (e.g: `postcss.config.js`, `tailwind.config.js` etc etc). Syncify will check for the existence of configuration files in the workspace and use them as the processor defaults. In situations where an external config file is detected and you've defined custom `processor` settings which differ from the Syncify defaults then options of the external config will overwritten (or merged) by those defined on `processor` configuration.
1621
-
1622
- Say you're using a `postcss.config.js` file to provide a couple of plugins in your project, for example:
1623
-
1624
- <!-- prettier-ignore -->
1625
- ```js
1626
- // postcss.config.js
1627
-
1628
- module.exports = {
1629
- plugins: [
1630
- require('postcss-nested')(),
1631
- require('autoprefixer')()
1632
- ]
1633
- };
1634
-
1635
- ```
1636
-
1637
- Syncify will automatically detect and digest this file at runtime. It will use the export value when processing CSS with PostCSS and will consider it the **default** value, assigning it to `processors.postcss`. Instead of providing a `postcss.config.js` file, you _could_ instead just pass this to the **postcss** processor option, for example:
1638
-
1639
- <!-- prettier-ignore -->
1640
- ```js
1641
- // syncify.config.ts
1642
-
1643
- import { defineConfig } from '@syncify/cli';
1644
-
1645
- export default defineConfig({
1646
- // ...
1647
- processors: {
1648
- postcss: [
1649
- require('postcss-nested')(),
1650
- require('autoprefixer')()
1651
- ]
1652
- }
1653
- });
1654
- ```
1655
-
1656
- ### Transform Overrides
1657
-
1658
- You can overwrite processor defaults on a per-file basis at the transform level. Each transform exposes a processor property which accepts the same options which will apply an immutable merge with processor defaults. This is helpful when you require file specific transforms.
1659
-
1660
- Take the following code sample, notice how we've passed an SASS override on certain files. In this example the `style.scss` transform will use the `processor.sass` configuration, whereas the the `example.scss` file will override the `processor.sass` defaults and use a different set of configuration options.
1661
-
1662
- <!-- prettier-ignore -->
1663
- ```js
1664
- // syncify.config.ts
1665
-
1666
- import { defineConfig } from '@syncify/cli';
1667
-
1668
- export default defineConfig({
1669
- // ...
1670
- processor: {
1671
- sass: {
1672
- sourcemap: true,
1673
- style: 'compressed',
1674
- include: ['node_modules/'], // the style.scss include path
1675
- }
1676
- },
1677
- transform: {
1678
- style: [
1679
- {
1680
- input: 'styles/style.scss',
1681
- postcss: true
1682
- },
1683
- {
1684
- input: 'styles/example.scss',
1685
- snippet: true,
1686
- sass: {
1687
- style: 'expanded', // we override the output style
1688
- include: ['some/dir'] // we override the include path
1689
- }
1690
- }
1691
- ]
1692
- }
1693
- });
1694
- ```
1695
-
1696
- ### Usage Proposition
1697
-
1698
- Processors (and transforms) are optional in Syncify and may not fit your use case but there is an added benefit to using them. If you are leveraging HOT reloads or require different outputs be generated, then they are a great help. They also take a lot of the guess work out of bundling, so you can focus on writing code without worrying about bundler configurations.
1699
-
1700
- [Spawn](#spawn) processes are another option available for cases where you require a different complier which is not supported by Syncify, but please note that spawned processes will not apply HOT reloads and execute in child process. Whatever the case may be, it is important you weigh up the usage proposition for your project and determine which works best for you and your development workflow.
1701
-
1702
- ### Supported Processors
1703
-
1704
- Syncify provides extendable support with the following build tools:
1705
-
1706
- - [ESBuild](#esbuild)
1707
- - [SASS](#sass)
1708
- - [PostCSS](#postcss)
1709
- - [Tailwind](#tailwind-support)
1710
- - [SVGO](#svgo)
1711
- - [Sprite](#sprite)
1712
- - [Sharp](#sharp)
1713
-
1714
- # ESBuild
1715
-
1716
- Syncify provides integrated support with ESBuild for processing TypeScript, JavaScript, JSX and TSX file types. ESBuild provides wonderful capabilities like code splitting and tree shaking.
1717
-
1718
- See also [Script Transforms](#).
1719
-
1720
- ### Using Config File
1721
-
1722
- ESBuild Configuration files `esbuild.config.js` are not supported for script transforms.
1723
-
1724
- ### Using Processors
1725
-
1726
- The `esbuild` property is were ESBuild configuration option defaults can be provided.
1727
-
1728
- <!-- prettier-ignore -->
1729
- ```ts
1730
- import { defineConfig } from '@syncify/cli'
1731
-
1732
- export default defineConfig({
1733
- processors: {
1734
- esbuild: {} // ESBuild Options
1735
- }
1736
- })
1737
- ```
1738
-
1739
- # SASS
1740
-
1741
- Syncify provides integrated support with SASS Dart for processing SASS/SCSS file types. Syncify implements its own handling when for usage with SASS and allows you to use it together with [PostCSS](#postcss).
1742
-
1743
- See also [Style Transforms](#).
1744
-
1745
- ### Config File is not supported
1746
-
1747
- SASS Configuration files are not supported for style transforms.
1748
-
1749
- ### Using Processors
1750
-
1751
- The `sass` property is were SASS configuration option defaults can be provided.
1752
-
1753
- <!-- prettier-ignore -->
1754
- ```ts
1755
- import { defineConfig } from '@syncify/cli'
1756
-
1757
- export default defineConfig({
1758
- processors: {
1759
- sass: {} // SASS Options
1760
- }
1761
- })
1762
- ```
1763
-
1764
- # PostCSS
1765
-
1766
- Syncify provides integrated support with PostCSS for processing CSS file types. You can leverage PostCSS together with the SASS processor for CSS files.
1767
-
1768
- See also [Style Transforms](#).
1769
-
1770
- ### Using Config File
1771
-
1772
- Provide a `postcss.config.js` file in the root of your project or within the defined `config` path.
1773
-
1774
- ### Using Processors
1775
-
1776
- The `postcss` property accepts an array list of PostCSS plugins.
1777
-
1778
- <!-- prettier-ignore -->
1779
- ```ts
1780
- import { defineConfig } from '@syncify/cli'
1781
-
1782
- export default defineConfig({
1783
- processors: {
1784
- postCSS: [] // PostCSS Plugins
1785
- }
1786
- })
1787
- ```
1788
-
1789
- # SVGO
1790
-
1791
- Syncify provides integrated support with SVGO for processing SVG file types. If you would like to produce SVG Sprites, then refer to [Sprites](#) section which uses SVGO under the hood.
1792
-
1793
- See also [SVG Transforms](#).
1794
-
1795
- ### Using Config File
1796
-
1797
- Provide a `svgo.config.js` file in the root of your project or within the defined `config` path.
1798
-
1799
- ### Using Processors
1800
-
1801
- The `svgo` property accepts SVGO configuration options.
1802
-
1803
- <!-- prettier-ignore -->
1804
- ```ts
1805
- import { defineConfig } from '@syncify/cli'
1806
-
1807
- export default defineConfig({
1808
- processors: {
1809
- svgo: {} // SVGO Options
1810
- }
1811
- })
1812
- ```
1813
-
1814
- # Sprite
1815
-
1816
- Syncify provides integrated support for creating SVG Sprites using [SVG Sprites](#). SVG Sprite is a low level module that optimizes SVGs and bakes them into sprites that Syncify can inline and output.
1817
-
1818
- See also [SVG Transforms](#).
1819
-
1820
- ### Config File is not supported
1821
-
1822
- SVG Sprites Configuration files are not supported for Sprite transforms.
1823
-
1824
- ### Using Processors
1825
-
1826
- The `sprite` property accepts SVG Sprite configuration options.
1827
-
1828
- <!-- prettier-ignore -->
1829
- ```ts
1830
- import { defineConfig } from '@syncify/cli'
1831
-
1832
- export default defineConfig({
1833
- processors: {
1834
- sprite: {} // SVG Sprite Options
1835
- }
1836
- })
1837
- ```
1838
-
1839
- # Sharp
1840
-
1841
- Syncify provides integrated support for convert large images in common formats to smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions using the Sharp.
1842
-
1843
- See also [Image Transforms](#)
1844
-
1845
- ### Config File is not supported
1846
-
1847
- Sharp Configuration files are not supported for Image transforms.
1848
-
1849
- ### Using Processors
1850
-
1851
- The `sharp` property accepts Sharp configuration options.
1852
-
1853
- <!-- prettier-ignore -->
1854
- ```ts
1855
- import { defineConfig } from '@syncify/cli'
1856
-
1857
- export default defineConfig({
1858
- processors: {
1859
- sharp: {} // Sharp Options
1860
- }
1861
- })
1862
- ```
1863
-
1864
- # Terser
1865
-
1866
- The **Terser** option is for minification configuration options. Syncify supports minification and compression of Liquid, HTML JSON and also provides handling around Script and Style transform file types. Terse output is core to theme development using Syncify and developers should indeed get into a habit a distributing themes in terse a format.
1867
-
1868
- ### Does Liquid Minification Matter?
1869
-
1870
- When we are talking about Liquid syntax specifically, there is no real measurable performance increase one gets removing whitespace and newlines but Syncify does more than just strip whitespace, it also performs code elimination. The Syncify minification process will remove comments, strip extraneous delimiter trims and where possible it replaces syntax occurrences for faster equivalents.
1871
-
1872
- ### Usage
1873
-
1874
- Produce terse output by passing the `--terse` command flag. The `--prod` flag will also produce terse output. You can pass a boolean `false` to options to skip minification. The `terser` options defined within your Syncify configuration file will be used when performing minification. If all terser options are set to `false` then (logically) terse minification will not be applied.
1875
-
1876
- ### Terse Options
1877
-
1878
- Below is is the default configuration Syncify uses for minification. The `json`, `liquid`, `markup` and `script` options accept either an object or a boolean value. Passing boolean `true` will use defaults, whereas boolean `false` will skip minification.
1879
-
1880
- <!-- prettier-ignore -->
1881
- ```ts
1882
- import { defineConfig } from '@syncify/cli'
1883
-
1884
- export default defineConfig({
1885
- terser: {
1886
- json: {
1887
- assets: true,
1888
- config: true,
1889
- locales: true,
1890
- metafields: true,
1891
- metaobject: true,
1892
- groups: true,
1893
- templates: true,
1894
- exclude: []
1895
- },
1896
- liquid: {
1897
- collapseWhitespace: true,
1898
- collapseInner: false,
1899
- removeComments: true,
1900
- minifyJavascript: false,
1901
- minifySchema: false,
1902
- minifyStyle: false,
1903
- minifyStylesheet: false,
1904
- stripDashes: true,
1905
- exclude: []
1906
- },
1907
- markup: {
1908
- collapseWhitespace: true,
1909
- minifyScriptJSON: true,
1910
- minifyScript: true,
1911
- minifyStyle: true,
1912
- removeComments: true,
1913
- exclude: []
1914
- },
1915
- // Requires ESBuild to be installed
1916
- script: {
1917
- mangleProps: true,
1918
- keepNames: false,
1919
- legalComments: true,
1920
- keepNames: false,
1921
- legalComments: "inline",
1922
- mangleProps: undefined,
1923
- minifyIdentifiers: true,
1924
- minifySyntax: true,
1925
- minifyWhitespace: true,
1926
- mangleQuoted: true,
1927
- exclude: []
1928
- }
1929
- }
1930
- });
1931
- ```
1932
-
1933
- # CLI Usage
1934
-
1935
- Syncify ships with a powerful command line interface that supports prompt execution. If you have installed Syncify globally, you can call `syncify` or `sync` from any project but you should avoid this and instead install the module as a development dependency on a per-project basis.
1936
-
1937
- If you are using a package manager like [pnpm](https://pnpm.js.org/en/cli/install) you can simply call `pnpm syncify` (or `pnpm sync`) but if you are using npm or yarn then you may need to create reference script within your `package.json` file, eg:
1938
-
1939
- ```json
1940
- {
1941
- "scripts": {
1942
- "syncify": "syncify"
1943
- }
1944
- }
1945
- ```
1946
-
1947
- > If you are not using [pnpm](https://pnpm.js.org/en/cli/install) then you should really consider adopting it within your stack. It is a wonderful addition to any JavaScript project.
1948
-
1949
- ### Commands
1950
-
1951
- ### PARTIALLY INCOMPLETE - NOT ALL COMMANDS WORK
1952
-
1953
- The Syncify CLI supports the following commands.
1954
-
1955
- ```bash
1956
- Default:
1957
- syncify Starts interactive CLI command prompt
1958
-
1959
- Aliases:
1960
- sync An alias of syncify (can be used instead of syncify)
1961
-
1962
- Commands:
1963
- syncify Starts interactive CLI command prompt
1964
- syncify <store> --flags Store name or comma separated list of stores and flags
1965
-
1966
- Flags:
1967
- -t, --theme <targets> A comma separated list of theme targets
1968
- -b, --build Triggers a build, use with upload to run build before uploading
1969
- -w, --watch Starts watching for changes of files building when they occur
1970
- -u, --upload Uploads theme to online store, use with -t to target theme
1971
- -d, --download Downloads themes/s from specified stores
1972
- -c, --config <path> An optional config path to the syncify.config.js file.
1973
- -h, --hot HOT Reloading (available in watch mode only)
1974
- -p, --package Package theme and export to a .zip file
1975
- -s, --spawn, <name> Target a specific spawn (use with -w or -b flags to specify mode)
1976
- -o, --output <path> A path value (used in download and build mode only)
1977
- -h, --help, Prints command list and some help information
1978
- -f, --filter <filter> Query online store data API, eg: themes, metafields assets
1979
- -v, --version <action> Version control resource mode (see version arguments)
1980
-
1981
- Resource Modes:
1982
- --metafields Metafields resource mode
1983
- --locales Locales resource mode
1984
- --settings Settings resource mode
1985
- --redirects Redirects resource mode
1986
-
1987
- Version Arguments:
1988
- patch Increments the package.json version patch, eg: 1.0.0 > 1.0.1
1989
- minor Increments the package.json version minor, eg: 1.0.0 > 1.1.0
1990
- major Increments the package.json version major, eg: 1.0.0 > 2.0.0
1991
-
1992
- Operation Flags:
1993
- --clean Removes all output files, use with --build to clean before bundling
1994
- --status Checks development environment and connections are valid.
1995
- --pull Pull data from online store
1996
- --merge Merge online data with local references
1997
- --force Forces a sync, replacing remote source with local one
1998
- --silent Silence the logger, omit only errors
1999
-
2000
- Generator Flags:
2001
- --vsc Generates JSON schema spec for vscode users
2002
- --strap <name> Generates a Syncify theme strap, eg: --strap dawn
2003
-
2004
- Environment Flags:
2005
- --dev, --development Run in development mode (default)
2006
- --prod, --production Run in production mode
2007
- ```
2008
-
2009
- > Please keep in mind that not all commands are active as the project is still in beta.
2010
-
2011
- ## Examples
2012
-
2013
- CLI usage aims to be as simple as possible. A typical project will be targeting a single Shopify theme but you can target multiple themes and stores in a seamless manner. When targeting multiple stores or themes the CLI employs a flag based naming approach.
2014
-
2015
- **Generate theme targets**
2016
-
2017
- ```bash
2018
- $ syncify store-name -q themes
2019
- ```
2020
-
2021
- Prompt interface will be initialized
2022
-
2023
- 1. Target **store-name**
2024
- 2. Initialize Query resource
2025
- 3. Inform query we want the "themes" endpoint
2026
-
2027
- **Generate local metafields**
2028
-
2029
- ```bash
2030
- $ syncify store-name --metafields --pull
2031
- ```
2032
-
2033
- Prompt interface will be initialized
2034
-
2035
- 1. Target **store-name**
2036
- 2. Initialize Metafields resource
2037
- 3. Pull data from online-store
2038
-
2039
- **Upload theme to online store**
2040
-
2041
- ```bash
2042
- $ syncify store-name -t theme-1,theme-2 --clean -b -u --prod
2043
- ```
2044
-
2045
- Exchange interface will be initialized
2046
-
2047
- 1. Target **store-name**
2048
- 2. Theme targets are **theme-1** and **theme-2**
2049
- 3. Trigger Clean
2050
- 4. Trigger Build (production build because of --prod flag)
2051
- 5. Trigger Upload
2052
-
2053
- **Watching 1 store and 1 theme**
2054
-
2055
- ```bash
2056
- $ syncify shop -w -t dev
2057
- ```
2058
-
2059
- <details>
2060
- <summary>
2061
- Breakdown
2062
- </summary>
2063
-
2064
- The above command is calling `watch` on a store named `cool-shop` and will upload changes to a theme named `dev`. We are using the shorthand `--theme` flag (`-t`) to inform upon the theme we want changes uploaded.
2065
-
2066
- </details>
2067
-
2068
- <details>
2069
- <summary>
2070
- Configuration
2071
- </summary>
2072
-
2073
- The `package.json` configuration for the command would look like this:
2074
-
2075
- ```jsonc
2076
- {
2077
- "syncify": {
2078
- "stores": {
2079
- "domain": "cool-shop", // The store name
2080
- "themes": {
2081
- "dev": 123456789 // The theme id and target name
2082
- }
2083
- }
2084
- }
2085
- }
2086
- ```
2087
-
2088
- </details>
2089
-
2090
- **Watching 1 store and 2 themes**
2091
-
2092
- ```bash
2093
- $ syncify shop -t dev,prod -w
2094
- ```
2095
-
2096
- <details>
2097
- <summary>
2098
- Breakdown
2099
- </summary>
2100
-
2101
- The above command is calling `watch` on a store named `my-shop` and will upload changes to 2 different themes in that store we have named `dev` and `prod`.
2102
-
2103
- </details>
2104
-
2105
- <details>
2106
- <summary>
2107
- Configuration
2108
- </summary>
2109
-
2110
- The `package.json` configuration for the command would look like this:
2111
-
2112
- ```jsonc
2113
- {
2114
- "syncify": {
2115
- "stores": {
2116
- "domain": "my-shop", // The store name
2117
- "themes": {
2118
- "dev": 123456789, // The theme id and target name
2119
- "prod": 123456789 // The theme id and target name
2120
- }
2121
- }
2122
- }
2123
- }
2124
- ```
2125
-
2126
- </details>
2127
-
2128
- **Watching 2 stores and multiple themes**
2129
-
2130
- ```bash
2131
- $ syncify shop1,shop2 --shop1=test --shop2=dev,stage,prod -w
2132
- ```
2133
-
2134
- <details>
2135
- <summary>
2136
- Breakdown
2137
- </summary>
2138
-
2139
- The above command is calling `watch` on 2 stores, `shop1` and `shop2`. We are targeting a theme named `test` in the store `shop1` and 3 different themes in `shop2` named `dev`, `stage` and `prod`. Syncify will upload changes to both store and all the defined themes. Notice how we target different store themes in the command using the store name as a flag.
2140
-
2141
- </details>
2142
-
2143
- <details>
2144
- <summary>
2145
- Configuration
2146
- </summary>
2147
-
2148
- The `package.json` configuration for the command would look like this:
2149
-
2150
- ```json
2151
- {
2152
- "syncify": {
2153
- "stores": [
2154
- {
2155
- "domain": "shop1", // The store name
2156
- "themes": {
2157
- "test": 123456789 // The theme id and target name
2158
- }
2159
- },
2160
- {
2161
- "domain": "shop2", // The store name
2162
- "themes": {
2163
- "dev": 123456789,
2164
- "stage": 123456789,
2165
- "prod": 123456789
2166
- }
2167
- }
2168
- ]
2169
- }
2170
- }
2171
- ```
2172
-
2173
- </details>
2174
-
2175
- ### Prompts
2176
-
2177
- Syncify provides a helpful command prompt feature. Running `syncify` will provide you a simple prompt interface from which you can use to explore endpoints directly from your CLI or trigger commands.
2178
-
2179
- **Options**
2180
-
2181
- **Queries**
2182
-
2183
- # API
2184
-
2185
- Syncify can be initialized within scripts. This approach is a little more feature-full and allows you to integrate it with different build tools. You can hook into the transit process of files and apply modifications before they are uploaded to your store/s with this approach.
2186
-
2187
- ### Usage
2188
-
2189
- Syncify exports a function that has several methods which you can use to trigger specific modes. The default export can also target multiple hooks in accordance with what was passed from the command line.
2190
-
2191
- ```ts
2192
- import { syncify } from '@syncify/cli';
2193
-
2194
- // Build hook
2195
- syncify.build(options: {}, async function(content?: Buffer): Promise<Buffer|string|void|false>);
2196
-
2197
- // Watch hook
2198
- syncify.watch(options: {}, async function(content?: Buffer): Promise<Buffer|string|void|false>);
2199
-
2200
- // Upload hook
2201
- syncify.upload(options: {}, async function(content?: Buffer): Promise<Buffer|string|void|false>);
2202
-
2203
- // Download hook
2204
- syncify.download(options: {}, async function(content?: Buffer): Promise<Buffer|string|void|false>);
2205
-
2206
- // Targeting all hooks
2207
- syncify(options: {})({
2208
- async build(content?: Buffer): Promise<Buffer|string|void|false>,
2209
- async watch(content?: Buffer): Promise<Buffer|string|void|false>,
2210
- async upload(content?: Buffer): Promise<Buffer|string|void|false>,
2211
- async download(content?: Buffer): Promise<Buffer|string|void|false>,
2212
- });
2213
-
2214
- ```
2215
-
2216
- ### Utilities
2217
-
2218
- Utilities will return some basic information about the Syncify instance. These are extremely helpful when when you are executing [spawned](#spawn) processes and need to control what feature to load. For example, if you are spawning a webpack process for compiling JavaScript assets and need to inform upon watch mode you'd use `util.resource('watch')` utility which returns a boolean value when running in watch mode.
2219
-
2220
- ```typescript
2221
- import { util, env } from '@syncify/cli'
2222
-
2223
- // Environment Conditions
2224
- env.prod: boolean;
2225
- env.dev: boolean;
2226
- env.build: boolean;
2227
- env.watch: boolean;
2228
- env.download: boolean;
2229
- env.upload: boolean;
2230
-
2231
- // Returns environment
2232
- util.env('dev' | 'prod'): boolean
2233
-
2234
- // Returns the current resource
2235
- util.mode('build' | 'watch' | 'upload' | 'download'): boolean
2236
-
2237
- // Returns spawns
2238
- util.spawned(): string[]
2239
-
2240
- ```
2241
-
2242
- # Contributing
2243
-
2244
- This project uses [pnpm](https://pnpm.js.org/en/cli/install). Fork the project, run `pnpm i` and you're good to go.
2245
-
2246
- # Author
2247
-
2248
- Created by [Nίκος Σαβίδης](https://github.com/panoply).
2249
-
2250
- ### Acknowledgements
2251
-
2252
- Special thanks to a couple of talented developers that helped work through ideas and edge-cases on the project.
2253
-
2254
- - [Joseph Curtis](#)
2255
- - [David Warrington](https://ellodave.dev/)
2256
- - [Mansedan](#)
190
+ If you are an **individual** looking to express gratitude financially, I would much prefer you donate to your local animal shelter and share the story with me on [X](https://x.com/niksavvidis). If you are a business, agency, or representing an enterprise using Syncify and interested in discussing partnerships, opportunities, or custom solutions, you can reach me via [email](mailto:n.savvidis@gmx.com) or message me on [X](https://x.com/niksavvidis).
2257
191
 
2258
- # Changelog
192
+ ### License
2259
193
 
2260
- Refer to the [Changelog](changelog.md) for each per-version update and/or fixes.
194
+ The project is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).