├── .github └── workflows │ ├── deploy-to-npm-major.yml │ ├── deploy-to-npm-minor.yml │ ├── deploy-to-npm-patch.yml │ ├── deploy-to-npm-prerelease.yml │ ├── execute-sync.yml │ ├── execute.yml │ └── test.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── documentation ├── .gitignore ├── content │ ├── docs │ │ ├── commands.md │ │ ├── contributing.md │ │ ├── critical-css.md │ │ ├── developer-themes.md │ │ ├── getting-started.md │ │ ├── gitlab-integration.md │ │ ├── index.md │ │ ├── installation.md │ │ ├── javascript-chunking.md │ │ ├── linting.md │ │ ├── local-development.md │ │ ├── repo-sync.md │ │ ├── testing-on-mobile.md │ │ ├── theme-kit-access-tokens.md │ │ ├── theme-naming.md │ │ ├── theme-setup.md │ │ └── thinking-modular.md │ └── settings │ │ ├── browsersync.md │ │ ├── css.md │ │ ├── environment.md │ │ ├── git.md │ │ ├── javascript.md │ │ ├── path.md │ │ ├── shopify.md │ │ └── theme-name.md ├── gridsome.config.js ├── gridsome.server.js ├── netlify.toml ├── package.json ├── src │ ├── assets │ │ └── favicon.png │ ├── components │ │ ├── LayoutHeader.vue │ │ ├── Logo.vue │ │ ├── NextPrevLinks.vue │ │ ├── OnThisPage.vue │ │ ├── README.md │ │ ├── Search.vue │ │ ├── Sidebar.vue │ │ └── ToggleDarkMode.vue │ ├── favicon.png │ ├── layouts │ │ ├── Default.vue │ │ └── README.md │ ├── main.js │ ├── pages │ │ ├── 404.vue │ │ ├── Index.vue │ │ └── README.md │ └── templates │ │ ├── MarkdownPage.vue │ │ └── README.md ├── static │ ├── README.md │ └── logo.jpg ├── tailwind.config.js └── yarn.lock ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── cli │ ├── README.md │ ├── cli.js │ ├── lib │ │ └── getPackageInformation.js │ ├── package-lock.json │ └── package.json ├── configure │ ├── README.md │ ├── configure.js │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── constants.js │ │ ├── defaults.js │ │ ├── defaults │ │ ├── browserSync.js │ │ ├── css.js │ │ ├── cypress.js │ │ ├── debug.js │ │ ├── git.js │ │ ├── javascript.js │ │ ├── path.js │ │ ├── shopify.js │ │ └── themeName.js │ │ ├── emitter.js │ │ └── utils.js ├── gitlab-kit │ ├── README.md │ ├── gitlab-kit.js │ ├── package-lock.json │ ├── package.json │ ├── services │ │ └── github.js │ └── test │ │ └── githubService.js ├── glob-loader │ ├── README.md │ ├── index.js │ ├── javascript-loader.js │ ├── package-lock.json │ ├── package.json │ ├── plugin.js │ ├── src │ │ ├── regex.js │ │ └── util.js │ └── style-loader.js ├── shopify-kit │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── services │ │ ├── assetUpload │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ └── throttledQueue.js │ │ ├── developerThemes │ │ │ └── index.js │ │ ├── stylesheetChunking │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── liquidSnippet.js │ │ │ │ ├── liquidSnippetTemplate.js │ │ │ │ ├── tokenization.js │ │ │ │ └── util.js │ │ ├── themeNaming │ │ │ └── index.js │ │ ├── tokenization │ │ │ └── index.js │ │ └── util.js │ ├── shopify-kit.js │ └── test │ │ ├── assetUpload.js │ │ ├── ignoringFilesGlob.js │ │ ├── mocks │ │ ├── fileTokens.js │ │ └── main.min.css.liquid.js │ │ ├── productionThemeProtection.js │ │ ├── stylesheetChunkingService.js │ │ └── tokenizationService.js ├── shopify-loader │ ├── README.md │ ├── package-lock.json │ ├── package.json │ └── shopify-loader.js ├── terminal-kit │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── protect.js │ ├── src │ │ ├── atoms.js │ │ ├── constants.js │ │ ├── logo.js │ │ ├── molecules.js │ │ ├── organisms.js │ │ └── utils.js │ ├── terminal-kit.js │ └── test │ │ └── molecules.js ├── theme │ ├── basic-built-theme-test │ │ ├── .gitignore │ │ ├── .kit-mapping.json │ │ ├── assets │ │ │ ├── main.js │ │ │ └── main.min.css.liquid │ │ ├── config │ │ │ └── settings_schema.json │ │ ├── kit.config.js │ │ ├── layout │ │ │ └── theme.liquid │ │ ├── locales │ │ │ └── en.default.json │ │ ├── package.json │ │ ├── snippets │ │ │ ├── foo.liquid │ │ │ └── snippet.liquid │ │ └── templates │ │ │ └── product.liquid │ ├── basic-test │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .stylelintrc.js │ │ ├── README.md │ │ ├── kit.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ ├── assets │ │ │ │ ├── css │ │ │ │ │ ├── lib │ │ │ │ │ │ └── _align.scss │ │ │ │ │ └── main.scss │ │ │ │ └── js │ │ │ │ │ └── main.js │ │ │ ├── config │ │ │ │ ├── lib │ │ │ │ │ └── general.json │ │ │ │ └── settings_data.json │ │ │ ├── layout │ │ │ │ └── theme.liquid │ │ │ ├── locales │ │ │ │ └── en.default.json │ │ │ ├── modules │ │ │ │ └── foo │ │ │ │ │ ├── foo.js │ │ │ │ │ ├── foo.liquid │ │ │ │ │ └── foo.scss │ │ │ ├── snippets │ │ │ │ └── snippet.liquid │ │ │ └── templates │ │ │ │ ├── .keep │ │ │ │ ├── index.json │ │ │ │ └── product.liquid │ │ └── webpack.config.js │ └── bootstrap │ │ └── .keep └── webpacker │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── console.js │ ├── cookie-handling.js │ ├── lint.js │ ├── setUpProxy.js │ └── webpack.config.js │ ├── test │ ├── mocks │ │ ├── webpack-response.js │ │ └── webpack.config.js │ └── webpacker.js │ └── webpacker.js └── test ├── helpers └── dependency-interceptor.js └── scripts ├── validate-filtered-files.js └── validate-source-sync.sh /.github/workflows/deploy-to-npm-major.yml: -------------------------------------------------------------------------------- 1 | name: deploy-to-npm-major 2 | on: workflow_dispatch 3 | jobs: 4 | deploy-major: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - uses: actions/setup-node@v2 9 | with: 10 | node-version: '14.21.3' 11 | - uses: shimataro/ssh-key-action@v2 12 | with: 13 | key: ${{ secrets.SYNC_SSH_KEY_GITHUB_DEPLOY_TO_NPM }} 14 | known_hosts: ${{ secrets.SYNC_KNOWN_HOSTS_GITHUB }} 15 | - name: Save NPM auth details to .npmrc 16 | run: echo //registry.npmjs.org/:_authToken=$NPM_PUBLISH_KEY >> .npmrc 17 | env: 18 | NPM_PUBLISH_KEY: ${{ secrets.NPM_PUBLISH_KEY }} 19 | - run: npm whoami 20 | - run: git config --global user.email team@halfhelix.com 21 | - run: git config --global user.name Deployments 22 | - run: npm i -g lerna 23 | - run: lerna bootstrap 24 | - run: lerna publish major --no-verify-access --yes 25 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-npm-minor.yml: -------------------------------------------------------------------------------- 1 | name: deploy-to-npm-minor 2 | on: workflow_dispatch 3 | jobs: 4 | deploy-minor: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v3 8 | - uses: actions/setup-node@v3 9 | with: 10 | node-version: '14.21.3' 11 | - name: Save NPM auth details to .npmrc 12 | run: echo //registry.npmjs.org/:_authToken=$NPM_PUBLISH_KEY >> .npmrc 13 | env: 14 | NPM_PUBLISH_KEY: ${{ secrets.NPM_PUBLISH_KEY }} 15 | - run: npm whoami 16 | - run: git config --global user.email team@halfhelix.com 17 | - run: git config --global user.name Deployments 18 | - run: npm i -g lerna 19 | - run: lerna bootstrap 20 | - run: lerna publish minor --no-verify-access --yes --exact 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-npm-patch.yml: -------------------------------------------------------------------------------- 1 | name: deploy-to-npm-patch 2 | on: workflow_dispatch 3 | jobs: 4 | deploy-patch: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - uses: actions/setup-node@v2 9 | with: 10 | node-version: '14.21.3' 11 | - uses: shimataro/ssh-key-action@v2 12 | with: 13 | key: ${{ secrets.SYNC_SSH_KEY_GITHUB_DEPLOY_TO_NPM }} 14 | known_hosts: ${{ secrets.SYNC_KNOWN_HOSTS_GITHUB }} 15 | - name: Save NPM auth details to .npmrc 16 | run: echo //registry.npmjs.org/:_authToken=$NPM_PUBLISH_KEY >> .npmrc 17 | env: 18 | NPM_PUBLISH_KEY: ${{ secrets.NPM_PUBLISH_KEY }} 19 | - run: npm whoami 20 | - run: git config --global user.email team@halfhelix.com 21 | - run: git config --global user.name Deployments 22 | - run: npm i -g lerna 23 | - run: lerna bootstrap 24 | - run: lerna publish patch --no-verify-access --yes --exact 25 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-npm-prerelease.yml: -------------------------------------------------------------------------------- 1 | name: deploy-to-npm-prerelease 2 | on: workflow_dispatch 3 | jobs: 4 | deploy-prerelease: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - uses: actions/setup-node@v2 9 | with: 10 | node-version: '14.21.3' 11 | - uses: shimataro/ssh-key-action@v2 12 | with: 13 | key: ${{ secrets.SYNC_SSH_KEY_GITHUB_DEPLOY_TO_NPM }} 14 | known_hosts: ${{ secrets.SYNC_KNOWN_HOSTS_GITHUB }} 15 | - name: Save NPM auth details to .npmrc 16 | run: echo //registry.npmjs.org/:_authToken=$NPM_PUBLISH_KEY >> .npmrc 17 | env: 18 | NPM_PUBLISH_KEY: ${{ secrets.NPM_PUBLISH_KEY }} 19 | - run: npm whoami 20 | - run: git config --global user.email team@halfhelix.com 21 | - run: git config --global user.name Deployments 22 | - run: npm i -g lerna 23 | - run: lerna bootstrap 24 | - run: lerna publish prerelease --no-verify-access --yes 25 | -------------------------------------------------------------------------------- /.github/workflows/execute-sync.yml: -------------------------------------------------------------------------------- 1 | name: execute-sync 2 | on: 3 | push: 4 | branches-ignore: 5 | - 'master' 6 | - 'production' 7 | jobs: 8 | sync-to-build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v2 13 | with: 14 | node-version: '14.21.3' 15 | - uses: shimataro/ssh-key-action@v2 16 | with: 17 | key: ${{ secrets.SYNC_SSH_KEY_GITHUB }} 18 | known_hosts: ${{ secrets.SYNC_KNOWN_HOSTS_GITHUB }} 19 | - run: git config --global init.defaultBranch master 20 | - run: git config --global user.email "ci@halfhelix.com" 21 | - run: git config --global user.name "Half Helix" 22 | - run: npm i -g lerna 23 | - run: lerna bootstrap 24 | - name: Installing theme dependencies 25 | working-directory: ./packages/theme/basic-test 26 | run: npm i 27 | - name: Run sync to build repo command 28 | working-directory: ./packages/theme/basic-test 29 | run: node ../../cli/cli.js build --sync-with-repo 30 | env: 31 | BUILT_THEME_REPO_URL: ${{ secrets.BUILT_THEME_REPO_URL }} 32 | - run: node ./test/scripts/validate-filtered-files.js 33 | sync-to-source: 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v2 37 | - uses: actions/setup-node@v2 38 | with: 39 | node-version: '14.21.3' 40 | - uses: shimataro/ssh-key-action@v2 41 | with: 42 | key: ${{ secrets.SYNC_SSH_KEY_GITHUB_TO_SOURCE }} 43 | known_hosts: ${{ secrets.SYNC_KNOWN_HOSTS_GITHUB }} 44 | - run: git config --global init.defaultBranch master 45 | - run: git config --global user.email "ci@halfhelix.com" 46 | - run: git config --global user.name "Half Helix" 47 | - run: npm i -g lerna 48 | - run: lerna bootstrap 49 | - name: Installing theme dependencies 50 | working-directory: ./packages/theme/basic-built-theme-test 51 | run: npm i 52 | - name: Run sync to source repo command 53 | working-directory: ./packages/theme/basic-built-theme-test 54 | run: node ../../cli/cli.js sync-back-to-source-repo 55 | env: 56 | SRC_THEME_REPO_URL: ${{ secrets.SRC_THEME_REPO_URL }} 57 | - name: Validate files exit in source repo 58 | run: ./test/scripts/validate-source-sync.sh 59 | env: 60 | SRC_THEME_REPO_URL: ${{ secrets.SRC_THEME_REPO_URL }} 61 | -------------------------------------------------------------------------------- /.github/workflows/execute.yml: -------------------------------------------------------------------------------- 1 | name: execute 2 | on: 3 | push: 4 | branches-ignore: 5 | - 'master' 6 | - 'production' 7 | jobs: 8 | exec-lint: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v2 13 | with: 14 | node-version: '14.21.3' 15 | - run: npm i -g lerna 16 | - run: lerna bootstrap 17 | - name: Installing theme dependencies 18 | working-directory: ./packages/theme/basic-test 19 | run: npm i 20 | - name: Run linting command 21 | working-directory: ./packages/theme/basic-test 22 | run: node ../../cli/cli.js lint 23 | exec-build: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: actions/setup-node@v2 28 | with: 29 | node-version: '14.21.3' 30 | - run: npm i -g lerna 31 | - run: lerna bootstrap 32 | - name: Installing theme dependencies 33 | working-directory: ./packages/theme/basic-test 34 | run: npm i 35 | - name: Run build command 36 | working-directory: ./packages/theme/basic-test 37 | run: node ../../cli/cli.js build 38 | exec-deploy: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - uses: actions/checkout@v2 42 | - uses: actions/setup-node@v2 43 | with: 44 | node-version: '14.21.3' 45 | - run: npm i -g lerna 46 | - run: lerna bootstrap 47 | - name: Installing theme dependencies 48 | working-directory: ./packages/theme/basic-test 49 | run: npm i 50 | - name: Run deploy command 51 | working-directory: ./packages/theme/basic-test 52 | run: node ../../cli/cli.js deploy 53 | env: 54 | THEME_ID: ${{ secrets.THEME_ID }} 55 | PASSWORD: ${{ secrets.PASSWORD }} 56 | STORE: ${{ secrets.STORE }} 57 | - run: node ./test/scripts/validate-filtered-files.js 58 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: push 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - uses: actions/setup-node@v2 9 | with: 10 | node-version: '14.21.3' 11 | - run: npm i -g lerna 12 | - run: lerna bootstrap 13 | - run: npm ci 14 | - run: npm run test 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | lerna-debug.log 4 | tmp 5 | *.log 6 | builds 7 | temp 8 | logs 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Node 2 | **/node_modules 3 | **/package.json 4 | **/package-lock.json 5 | 6 | # Generated 7 | **/bower.json 8 | **/lerna.json 9 | 10 | # Build 11 | **/build 12 | **/dist 13 | **/public 14 | **/coverage 15 | **/storybook-static 16 | 17 | # Nitro 18 | **/project/blueprints 19 | **/.yo-rc.json 20 | 21 | # File Types 22 | *.html 23 | *.liquid -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "none" 6 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.formatOnType": true 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-present Half Helix Kit Contributors 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Half Helix / Kit 2 | 3 | This is a toolkit that we use internally at Half Helix to develop our frontend Shopify themes. It enables us to develop websites the way that we want to, with a focus on modularity. We developed this tool for our own team but hey, we thought that there might be other people out there that could enjoy this so we made it public. 4 | 5 | ### Installation 6 | 7 | ``` 8 | npm i -g @halfhelix/kit 9 | ``` 10 | 11 | ### Documentation 12 | 13 | Documentation for this tool is available at [kit.halfhelix.com](https://kit.halfhelix.com) 14 | -------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .cache 3 | .DS_Store 4 | src/.temp 5 | node_modules 6 | dist 7 | !.env.example 8 | .env 9 | .env.* 10 | -------------------------------------------------------------------------------- /documentation/content/docs/commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Core Commands 9 | 10 | The main commands with Kit are `kit watch`, `kit build` & `kit deploy`. 11 | 12 | ## Kit Watch 13 | 14 | ``` 15 | kit watch 16 | ``` 17 | 18 | If you are a developer, this is likely the command that you'll most frequently use. Here's what this command does: 19 | 20 | 1. Interprets configuration information 21 | 1. Generates a Webpack configuration object in memory 22 | 1. Starts a Webpack watch session using the JS interface of Webpack 23 | 1. Creates a BrowserSync session, connected to Webpack 24 | 1. Waits for initial files to be compiled by Webpack 25 | 1. Opens your default browser 26 | 1. Listens for changes 27 | 28 | ## Kit Build 29 | 30 | ``` 31 | kit build --env {environment} 32 | ``` 33 | 34 | This command will build the theme locally without deploying it to Shopify. Here's what this command does: 35 | 36 | 1. Interprets configuration information 37 | 1. Generates a Webpack configuration object in memory 38 | 1. Starts a Webpack build session using the JS interface of Webpack 39 | 1. Waits for Webpack to compile files 40 | 1. Merges compiled files with files that Webpack is not informed about (e.g Liquid) 41 | 1. Tokenizes all files, mapping each file to their final destination in the build directory 42 | 1. Copies all theme files over 43 | 44 | ## Kit Deploy 45 | 46 | ``` 47 | kit deploy --env {environment} 48 | ``` 49 | 50 | This command will build the theme for deployment to Shopify, only copying the Webpack compiled files to the build directory. Here's what this command does: 51 | 52 | 1. Interprets configuration information 53 | 1. Generates a Webpack configuration object in memory 54 | 1. Starts a Webpack build session using the JS interface of Webpack 55 | 1. Waits for Webpack to compile files 56 | 1. Merges compiled files with files that Webpack is not informed about (e.g Liquid) 57 | 1. Tokenizes all files, mapping each file to their final destination in memory 58 | 1. Creates a queue that controls a throttled deployment to Shopify 59 | 1. Optionally renames the Shopify theme at the end of the deployment 60 | 61 | ### Deploy Compiled Only 62 | 63 | Note the following flag will only deploy Webpack compiled files (usually CSS and JS) 64 | 65 | ``` 66 | kit deploy --env {environment} --compiled-only 67 | ``` 68 | 69 | ## Other commands 70 | 71 | In addition to these three main commands, Kit also exposes the following commands: 72 | 73 | - `kit lint` (see [Linting](/docs/linting)) 74 | - `kit gitlab` (see [Gitab](/docs/gitlab-integration)) 75 | - `kit theme` (see [Developer Themes](/docs/developer-themes)) 76 | - `kit --version` (print your current version of kit) 77 | 78 | And run `kit` or `kit help` to print an outline of what is available. 79 | -------------------------------------------------------------------------------- /documentation/content/docs/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Contributing 9 | 10 | ## Structure 11 | 12 | [Lerna](https://github.com/lerna/lerna) is used to break the underlying source code of this package into smaller NPM packages contained in the same repository. You'll see these packages in the `packages/` directory. `packages/cli` is the CLI entrypoint. `packages/configure` handles settings and stores defaults. 13 | 14 | ## Getting Setup 15 | 16 | Follow these steps to spin up a development environment. This gives a basic rundown but adapt these as needed if you would like to fork the repo and submit an MR with an update to the source code. 17 | 18 | ```bash 19 | npm uninstall -g @halfhelix/kit # (if already installed) 20 | git clone https://github.com/halfhelix/Kit.git kit 21 | cd kit && npm i 22 | lerna bootstrap 23 | cd ./packages/cli 24 | npm i -g $(PWD) 25 | ``` 26 | 27 | Once these steps have been successfully carried out, you should be able to run `kit {command}` commands globally and have the command be controlled by this local copy of Kit rather than a copy of the code in your npm global `node_modules` directory (as would be standard if you were to run `npm i -g @halfhelix/kit`). 28 | 29 | ## Unit Testing 30 | 31 | We use [ava](https://github.com/avajs/ava) for unit tests. Unit tests for this package are present but not exhaustive. If you are taking the time to contribute to the source code, please create a test to go alongside your source code update. 32 | 33 | ## Code Formatting 34 | 35 | We use [Prettier](https://prettier.io/) for code formatting. Please ensure your IDE is setup to support the `.prettierrc` file in this repo. 36 | -------------------------------------------------------------------------------- /documentation/content/docs/developer-themes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Developer Themes 9 | 10 | Development themes were introduced by Shopify to provide separation between developer and non-developer workflows, and help avoid a merchant from hitting their Shopify theme limit. 11 | 12 | The developer flow here is focused on allowing a developer to have **one development theme per branch**. We have introduced a `.kit-themes.json` file that tracks the theme ID to the branch name. This file will be different for each developer, hence this file should be .gitignore'd. 13 | 14 | **Note: Development themes do not show in the Shopify Admin UI.** 15 | 16 | ## Commands 17 | 18 | Here are a list of commands added to support developer themes: 19 | 20 | ```bash 21 | # Create new developer theme 22 | kit theme init 23 | 24 | # Get info about current theme 25 | kit theme info 26 | 27 | # Deploy local build to current theme 28 | kit theme deploy (or kit deploy --developer) 29 | 30 | # Develop against the current theme 31 | kit theme watch (or kit watch --developer) 32 | 33 | # Destroy current theme 34 | kit theme destroy 35 | ``` 36 | 37 | When interacting with Shopify, these commands will use the store myshopify.com URL and password properties that have been configured in your project's kit.config.js file. 38 | 39 | ## kit theme init 40 | 41 | ``` 42 | kit theme init 43 | ``` 44 | 45 | Create a new development theme for the current branch. If a theme ID is already tracked to the branch name in the `{project}/.kit-themes.json` file, then a new theme is not created and the current theme's information is printed in your terminal window. You can remove the current mapping by running `kit theme destroy` or deleting the reference in the `{project}/.kit-themes.json` using your IDE. 46 | 47 | Note: This simply creates an empty theme. Using `kit theme deploy` to update this theme with new files. 48 | 49 | ## kit theme info 50 | 51 | ``` 52 | kit theme info 53 | ``` 54 | 55 | Prints out information about the current branch's developer theme. You'll get an error messaging if you haven't mapped a theme to the current branch already using `kit theme init`. 56 | 57 | ## kit theme deploy 58 | 59 | ``` 60 | kit theme deploy (or kit deploy --developer) 61 | ``` 62 | 63 | Deploys theme assets to the current branch's developer theme. This should be run before starting development against a brand new theme. 64 | 65 | ## kit theme watch 66 | 67 | ``` 68 | kit theme watch (or kit watch --developer) 69 | ``` 70 | 71 | Start a developer environment against the current branch's developer theme. If a developer theme has not been mapped to the current branch, the theme mapped to your current --env setting in your `kit.config.js` will be used (and a notice will be shown in your terminal window). 72 | 73 | ## kit theme destroy 74 | 75 | ``` 76 | kit theme destroy 77 | ``` 78 | 79 | Note: This action will have immediate effect without an interstitial prompt. 80 | 81 | This allows a developer to remove a theme from Shopify once the need for the theme has been satisfied. Generally speaking, the developer who created the theme originally should be the person who removes the theme once they are finished with it. 82 | -------------------------------------------------------------------------------- /documentation/content/docs/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Getting Started 9 | 10 | Once you have [**Installed Kit**](/docs/) and [**Setup Your Theme**](/docs/theme-setup), we can move onto the following steps: 11 | 12 | 1. Install theme dependencies 13 | 1. Build the theme for the first time 14 | 1. Upload the built theme to Shopify 15 | 1. Setup your connection To Shopify 16 | 1. Test out you development environment 17 | 18 | ## Install theme dependencies 19 | 20 | We are not going to spend too much time on this step. Ensure that you have installed your project dependencies by running `npm install` or `yarn` while you are in the root directory of your project. 21 | 22 | ## Build the theme for the first time 23 | 24 | This step will help us validate that our theme setup is correct, Webpack is able to compile our JS and CSS assets and the Kit is able to copy over theme assets to the build directly (which defaults to `{project}/dist`). Running this command is always a good initial step when validating a new project. 25 | 26 | Run: `kit build --env production` 27 | 28 | #### Some problems you might encounter 29 | 30 | ``` 31 | Error: No settings for current env: development 32 | ``` 33 | 34 | This usually means that there is an issue finding the configuration file. Make sure that you have a kit.config.js file in the root of your project and this file follows the format outlined [**in the Theme Setup section**](/docs/theme-setup/#kitconfigjs). 35 | 36 | ``` 37 | UnhandledPromiseRejectionWarning: Error: Cannot find module {module} 38 | ``` 39 | 40 | Make sure that any NPM module you are using in `webpack.config.js` or `kit.config.js` has been installed into the project. This can often be related to Babel plugins, Eslint plugins or Webpack plugins that are specific to your project. 41 | 42 | ## Upload the built theme to Shopify 43 | 44 | It is essential that we have an accurate development theme in your Shopify instance that matches your local environment. 45 | 46 | A way to do this when starting a new project is to zip up the build directory (defaults to `{project}/dist`) after the theme has been successfully built and upload it to Shopify using the "Upload Theme" functionality in the Shopify Admin UI. 47 | 48 | ## Setup your connection To Shopify 49 | 50 | Here, we setup the three main variables that we need to get a development environment going: 51 | 52 | - The {instance}.myshopify.com URL. 53 | - A private app password that we can use to establish an API connection (this can be a [Theme Kit Access Tokens](/docs/theme-kit-access-tokens)). 54 | - The theme ID of the theme we'll be developing against. 55 | 56 | **The .myshopify.com URL** 57 | 58 | This should be easy to get ahold of. Head over to your Shopify instance, head over to `/admin/` and copy the `{handle}.myshopify.com` portion of the URL. Don't worry about the HTTP/S protocol. This should look something like `i-love-kit.myshopify.com`. 59 | 60 | **Private App Password** 61 | 62 | Head over to the Apps section of the Shopify instance admin, click "Manage Private Apps" and create a new private app that has permissions to read and write theme files. Here, we want the **"Password"** property, not the **"Api Key"** property. 63 | 64 | Note: See the [Theme Kit Access Tokens](/docs/theme-kit-access-tokens) section if Theme Kit Access Tokens are preferred over private app passwords. 65 | 66 | **Theme ID** 67 | 68 | Head over to the Theme section of the Shopify instance admin, find your corresponding theme and click "Customize". Grab the ID out of the URL bar. (Note: You'll need to make sure that you your local theme state matches a theme that has been deployed to Shopify servers). 69 | 70 | Now that you've acquired these three properties, add them to your `{project}/.env` file following the format in [**Theme Setup / .env**](/docs/theme-setup/#env). 71 | 72 | ## Test out your dev environment 73 | 74 | Alright, lets spin things up! If we've done the setup correctly, this should be nice n' simple. 75 | 76 | Run: `kit watch` 77 | 78 | Head over to [**Commands / Watch**](/docs/commands#watch) for a run down on what happens in this command. 79 | -------------------------------------------------------------------------------- /documentation/content/docs/gitlab-integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Gitlab Integration 9 | 10 | There is functionality included that: 11 | 12 | - Automatically creates merge requests in Gitlab when code is pushed to Gitlab 13 | - Lints Git authors and messages after a merge requests have been pushed 14 | 15 | This functionality is configurable via settings that follow the pattern "git.{settingName}", more information on these settings can be found in the [Settings > Git](/settings/git/) section below. 16 | 17 | ## Commands 18 | 19 | ```bash 20 | # Create a new MR in Gitlab for current branch 21 | kit gitlab --routine merge-request/create 22 | # Create a new MR in Gitlab & lint Git commit history 23 | kit gitlab --routine commits/lint 24 | ``` 25 | 26 | ## Example .gitlab-ci.yml 27 | 28 | This has been simplified to include only relevant properties: 29 | 30 | ```yml 31 | image: node:{version} 32 | 33 | before_script: 34 | - yarn install 35 | - yarn add @halfhelix/kit@{version} 36 | 37 | Check Git: 38 | script: 39 | - yarn gitlab:lint 40 | except: 41 | - master 42 | - production 43 | ``` 44 | 45 | ## Example kit.config.js 46 | 47 | This has been simplified to include only relevant properties: 48 | 49 | ```js 50 | module.exports = { 51 | 'git.gitlabToken': process.env.GITLAB_TOKEN, 52 | 'git.maintainer': 'gitlabhandle' 53 | } 54 | ``` 55 | -------------------------------------------------------------------------------- /documentation/content/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Introduction 9 | 10 | At Half Helix, we've been using this build and development tool for all of our Shopify themes since late 2019. We built and incorporated it into our workflows since we saw a need to have a scalable developer experience that can be purposed on a wide range of Shopify theme projects without our developers having to worry about setup. 11 | 12 | We are in 2021 now and there are new tools and features that greatly help with Shopify theme development. Shopify has introduced [Dawn](https://github.com/Shopify/dawn) and with it a set of standards that encourage adoption of simpler approaches to theme development and a preference for JIT asset pipelines. [Shopify CLI for Themes](https://shopify.dev/themes/tools/cli/theme-commands) has been introduced to encourage this approach over robust tooling and file mutations. In part this is an expression of the maturity of modern browser APIs and our ability as a community to leverage greenfield features, like native javascript syntax and APIs like Web Components. 13 | 14 | To provide an option for Shopify themes that benefit from having asset piplines we'll be supporting this tool and continuing to integrate features that allow theme developers to get the most out of Shopify. Feel free to review our recent Online Store 2.0 feature additions which we'll continue to add to. 15 | 16 | ## Philosophy & Contributing 17 | 18 | This tool was made for our team at Half Helix and currently our focus is on maintaining it for our immediate stakeholders. If you have an idea or notice a bug please feel free to reach out and submit a Merge Request. 19 | 20 | ## Dependencies 21 | 22 | This tool is built upon Webpack 4 and it is certainly time to upgrade to Webpack 5. There are a number of vulnerability flags that we'll get removed with this pending update. 23 | 24 | ## Online Store 2.0 Features 25 | 26 | During Unite in 2021, Shopify released a number of features under the name "Online Store 2.0". We explore how this tool supports these features in the "Online Store 2.0" section. Here are the features that we've added: 27 | 28 | - Github Support 29 | - Theme Kit Access Tokens 30 | - Developer Themes 31 | -------------------------------------------------------------------------------- /documentation/content/docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Installation 9 | 10 | This package is designed to be installed globally on your local computer. However, you should be able to install it locally as a project dependency too (for example, we do this when running CI/CD builds so we can cache the package in a relative folder between jobs). 11 | 12 | In most instances you can get going by simply installing the package globally via the commands below. However, see the bottom section on some issues we've encountered in the past when going through the installation process. 13 | 14 | ## Using NPM 15 | 16 | You can simply run: 17 | 18 | ```bash 19 | npm i -g @halfhelix/kit 20 | ``` 21 | 22 | After that run `kit --version` to verify that the tool is working. 23 | 24 | ## Using Yarn 25 | 26 | If you would prefer to use Yarn, you can run: 27 | 28 | ```bash 29 | yarn global add @halfhelix/kit 30 | ``` 31 | 32 | After that run `kit --version` to verify that the tool is working. 33 | 34 | ## Installation troubleshooting 35 | 36 | In order to install this package we write to the local computer directory that is set to store NPM global packages, and we do install Node Sass (at least until we release a new version using Dart Sass). If there is an issue with permissions for this global directory, or issues with Sass having been built for another version of Node, issues may arise in the installation process. 37 | 38 | ### Node Sass binding issues 39 | 40 | If you run into an error relating to Node Sass about non-compatible binaries "Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js" you may need to rebuild node-sass from within the kit node_modules folder: 41 | 42 | ```bash 43 | # For Mac OSX Users 44 | cd "$(npm root -g)/@halfhelix/kit" && npm rebuild node-sass; 45 | ``` 46 | 47 | _Note: Its on our roadmap to release a new version with Dart Sass support since [Node Sass is now deprecated](https://www.npmjs.com/package/node-sass)._ 48 | 49 | ### Permission issues 50 | 51 | See [this link](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally) on resolving permission issues when installing global packages. 52 | -------------------------------------------------------------------------------- /documentation/content/docs/javascript-chunking.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Javascript Chunking 9 | 10 | There is functionality included to split Javascript into chunks based on folder name, under the assumption that folder names map to finite locations of a theme, like the home page, or a specific page template. The aim here is to help prevent say, an extensive amount of javascript required for a robust page template to impact a part of the site that is separate, like the home page. 11 | 12 | The [Thinking Modular](/docs/thinking-modular) section is important to read, since this functionality is baked on top of the way modules are sorted into directories as explained there. Lets take a directory structure as follows: 13 | 14 | ```js 15 | src 16 | |- assets/ 17 | |- config/ 18 | |- layout/ 19 | |- locales/ 20 | |- sections/ 21 | |- snippets/ 22 | |- templates/ 23 | |- modules 24 | |- global/ 25 | | |- module-a/ 26 | | | |- module-a.js 27 | | | |- module-a.liquid 28 | | | |- module-a.scss 29 | | |- module-b/ 30 | |- index 31 | | |- module-c/ 32 | | | |- module-c.js 33 | | |- module-d/ 34 | | | |- module-d.js 35 | |- page-landing 36 | | |- module-e/ 37 | | | |- module-e.js 38 | | |- module-f/ 39 | | | |- module-f.js 40 | |- ... 41 | ``` 42 | 43 | This functionality will leverage Webpack to attempt to separate the landing page module JS from the index page JS, but have both areas of the site (the homepage and a page using a "landing" template) access the necessary global javascript. By using folder names to dictate Webpack chunks, we aim to provide an out of the box performance enhancement that can be configured as need be. 44 | 45 | Behind the scenes, the implementation is quite simple, we are ingesting the path of the chunk in a custom Webpack loader, and using the top level module folder as the value for the `webpackChunkName` of the module's javascript file. 46 | 47 | Note that there is still a single JS bundle entrypoint that Webpack creates to control the loading of subsequent JS chunks. 48 | 49 | ### Defining custom JS chunks 50 | 51 | Sometimes we might have a specific module, or collection of modules that use some big NPM dependencies (e.g. like GSAP, ScrollMagic, etc). Using Kit and under the hood, Webpack, we can ensure that these dependencies only get loaded in the parts of the theme that they are relevant to. 52 | 53 | #### Custom JS chunk configuration example 54 | 55 | ```js 56 | // src/modules/global/vertical-scroll.js 57 | 58 | export default function (el) { 59 | Promise.all([ 60 | import(/* webpackChunkName: "vertical-scroll" */ 'scrollmagic'), 61 | import(/* webpackChunkName: "vertical-scroll" */ 'gsap'), 62 | import(/* webpackChunkName: "vertical-scroll" */ 'scrollmagic-plugin-gsap') 63 | ]).then(([ScrollMagic, { gsap }, { ScrollMagicPluginGsap }]) => { 64 | ScrollMagicPluginGsap(ScrollMagic, gsap) 65 | 66 | // module code... 67 | } 68 | } 69 | 70 | ``` 71 | 72 | In this example, we communicate to Webpack that certain dependencies should be in the custom javascript bundle "vertical-scroll". Further, by using `import()` we let Webpack load these in asynchronously and once they are all loaded, we run our module code. 73 | 74 | In this way, we only load dependencies in the `vertical-scroll` bundle when we actually have the module on the page. If the module is not on a page, we don't load the dependencies in the browser. 75 | -------------------------------------------------------------------------------- /documentation/content/docs/linting.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Eslint & Stylelint 9 | 10 | This tool encourages a development workflow that lints JS through using Eslint, and lints CSS using Stylelint. 11 | 12 | ## Commands 13 | 14 | ```bash 15 | # Lint both JS and CSS 16 | kit lint 17 | 18 | # Lint JS 19 | kit lint --include js 20 | 21 | # Lint CSS 22 | kit lint --include css 23 | ``` 24 | 25 | ## Eslint 26 | 27 | Add an `eslintrc.js` file to your project root. The contents of this file will be informed by your own opinions on syntax. However, here is an example: 28 | 29 | ```js 30 | module.exports = { 31 | parserOptions: { 32 | sourceType: 'module', 33 | ecmaVersion: 2018 34 | }, 35 | extends: ['standard'], 36 | rules: { 37 | 'no-unused-vars': 0, 38 | 'no-undef': 0, 39 | 'no-extra-boolean-cast': 0, 40 | 'dot-notation': 0, 41 | 'import/first': 0, 42 | 'import/no-webpack-loader-syntax': 0 43 | } 44 | } 45 | ``` 46 | 47 | Eslint can be activated by adding in the `eslint-loader` to your pipeline via the `webpack.config.js` 48 | 49 | ```js 50 | const path = require('path') 51 | // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 52 | 53 | module.exports = { 54 | ... 55 | module: { 56 | rules: [ 57 | { 58 | enforce: "pre", 59 | test: /\.js$/, 60 | exclude: /node_modules/, 61 | loader: "eslint-loader", 62 | options: { 63 | fix: true 64 | } 65 | }, 66 | ... 67 | ] 68 | }, 69 | resolve: {}, 70 | plugins: [], 71 | } 72 | ``` 73 | 74 | ## Stylelint 75 | 76 | Add a `.stylelintrc.js` file to your project root. Similar to the above, the contents of this file will be informed by your own opinions on syntax. However, here is an example: 77 | 78 | ```js 79 | module.exports = { 80 | extends: 'stylelint-config-standard', 81 | rules: { 82 | 'selector-class-pattern': '^[a-z-_]+$', 83 | 'at-rule-no-unknown': null, 84 | 'no-descending-specificity': null, 85 | 'max-nesting-depth': 3 86 | } 87 | } 88 | ``` 89 | 90 | ### Configuration 91 | 92 | - Stylelint can be turned off via the `css.lintStyles` property in your kit.config.js 93 | - You can configure paths that are linted with the `css.stylelintPaths` property 94 | 95 | ```js 96 | { 97 | 'css.lintStyles': true, 98 | 'css.stylelintPaths'(settings) { 99 | return [ 100 | // `src/assets/css/**/*.scss`, 101 | `src/assets/scss/**/*.scss`, 102 | `src/modules/**/*.scss`, 103 | `src/sections/**/*.scss` 104 | ] 105 | }, 106 | } 107 | ``` 108 | -------------------------------------------------------------------------------- /documentation/content/docs/local-development.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Local Development 9 | 10 | Here, we are going to spend some time talking about how local development works since there is a little bit happening behind the scenes. 11 | 12 | ## Behind the scenes of "kit watch" 13 | 14 | When you trigger "kit watch", this tool will execute the following actions: 15 | 16 | - Parse your .env and interpret your `kit.config.js` settings. 17 | - Get your theme information from Shopify via an API call. 18 | - Use Webpack to create your asset bundles. 19 | - Use BrowserSync to proxy your Shopify instance address. 20 | - Once Webpack has finished it's initial compilation, BrowserSync establishes a socket connection between your browser and computer. 21 | 22 | ## In-memory CSS and Javascript 23 | 24 | Now, CSS and Javascript are treated a little differently to other types of files. To speed up development, Webpack keeps track of file updates in your local memory rather than saving the files to a disk or uploading them to Shopify. For this reason, if you view the theme outside of your localhost and you haven't run `kit deploy` on theme you are trying to preview, you'll likely see up-to-date liquid files but you'll probably not see your up-to-date CSS and JS because it hasn't been pushed to Shopify yet! 25 | 26 | In order to allow for this in-memory handling of CSS and Javascript and allow changes to be fed to the browser, we use Webpack HMR (Hot Module Reloading) functionality. We also use BrowserSync replacements to change the URL references of your JS and CSS assets from the Shopify CDN destinations to local URLs that are connected to this HMR functionality (when in the localhost only). So if you see your Javascript coming from a URL like `/dev/main.js` while in localhost, this is the reason. 27 | 28 | ## Localhost Proxy Replacements 29 | 30 | So this lead us to the default array of proxy replacement rules that BrowserSync interprets: 31 | 32 | ```js 33 | { 34 | 'bs.proxyReplacements.normal': [ 35 | { 36 | regex: /]*><\/script>/gi, 37 | replacement() {} 38 | }, 39 | { 40 | regex: /]*>/gi, 41 | replacement(settings) { 42 | return `` 43 | } 44 | } 45 | ], 46 | } 47 | ``` 48 | 49 | Note that this is under the setting 'bs.proxyReplacements.normal' (with "normal" at the end because we have a slightly different set of rules when critical CSS functionality is getting leveraged. [Check out this file](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/browserSync.js) to compare these settings) . 50 | 51 | To talk through the "normal" settings above, the first setting actually removes the `//shopify.cdn.com/main.min.js` file from the localhost proxy during local development. This is because the CSS and the Javascript are coming from the same bundle in development, the `/dev/main.js` bundle. The second setting replaces the `//shopify.cdn.com/main.min.css` file with the `/dev/main.js` and thus establishes a connection to the HMR handled bundle. 52 | 53 | For most use cases, having one bundle here, a "main" bundle like we have above works well. However, there are cases when you need to add a different bundle, such as a bundle specifically for modifying a Shopify Plus Checkout layout. In this instance, you want to add the additional bundle to your `webpack.config.js` and you'll want to add to these replacement rules so that your checkout styles can be modified in a nice live reloading environment. In this instance, you'll want to add something like the following to your `kit.config.js` file: 54 | 55 | ```js 56 | { 57 | 'bs.proxyReplacementsFilter'(rules) { 58 | return rules.concat([ 59 | { 60 | regex: /]*><\/script>/gi, 61 | replacement() {} 62 | }, 63 | { 64 | regex: /]*>/gi, 65 | replacement(settings) { 66 | return `` 67 | } 68 | } 69 | ]) 70 | } 71 | } 72 | ``` 73 | 74 | And, modify your webconfig.js by adding in another bundle like so: 75 | 76 | ```js 77 | { 78 | entry: { 79 | "main": [ 80 | './src/assets/css/main.scss', 81 | './src/assets/js/main' 82 | ], 83 | "checkout": [ 84 | './src/assets/css/checkout.scss', 85 | './src/assets/js/checkout' 86 | ] 87 | }, 88 | } 89 | ``` 90 | -------------------------------------------------------------------------------- /documentation/content/docs/testing-on-mobile.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Testing On Mobile 9 | 10 | There are a few settings that allow for easy testing on a mobile device connected to your current local network. 11 | 12 | ## Noteworthy Settings 13 | 14 | ```js 15 | { 16 | "bs.local": 192.168.1.1 // Your local IP address 17 | "js.hmr": false 18 | } 19 | ``` 20 | 21 | With these settings temporarily added to your `kit.config.js` file (you probably shouldn't commit them), you can set the URL of your localhost proxy to use your local IP address and turn off hot module reloading functionality. We turn off HMR in this situation since there are times where reloads are delayed or misfired across a network connection. 22 | -------------------------------------------------------------------------------- /documentation/content/docs/theme-kit-access-tokens.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Theme Kit Access Tokens 9 | 10 | Shopify introduced a workflow around providing developers with access tokens that provide access to theme actions only. We've introduced support for these access tokens. This feature does not have a outwardly facing API, rather it should be something that just works. 11 | 12 | - You can read more about it in Shopify Docs [here](https://shopify.dev/themes/tools/theme-kit/access#how-theme-kit-access-works) 13 | - The Shopify Application that provides these tokens can be found [here](https://apps.shopify.com/theme-kit-access) 14 | 15 | These Theme Kit Access Tokens start off with "`shptka_`" 16 | -------------------------------------------------------------------------------- /documentation/content/docs/theme-naming.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Theme Naming 9 | 10 | There is functionality included that renames the Shopify theme after a deployment. We use this functionality to help create a two-way visual bind between the theme and the deployment (when not using the Shopify Github integration). 11 | 12 | The [Settings > Theme Name](/settings/theme-name/) elaborates on this functionality by outlining relevant configuration settings. 13 | -------------------------------------------------------------------------------- /documentation/content/docs/thinking-modular.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Thinking Modular 9 | 10 | When we create themes at Half Helix using this Kit, we structure our code into contained modules using the theme structure below: 11 | 12 | ```bash 13 | .env 14 | .eslintrc.js 15 | .stylelintrc.js 16 | kit.config.js 17 | webpack.config.js 18 | ... 19 | src 20 | |- assets 21 | | |- scss 22 | | | |- lib 23 | | | |- main.scss 24 | | | 25 | | |- js 26 | | | |- lib 27 | | | |- main.js 28 | | | 29 | | |- images 30 | | |- fonts 31 | | 32 | |- config 33 | | |- lib 34 | | |- section-a.json 35 | | |- section-b.json 36 | | 37 | |- layout 38 | |- locales 39 | |- sections 40 | |- snippets 41 | | |- gtm.liquid 42 | | |- no-index.liquid 43 | | 44 | |- templates 45 | |- modules 46 | |- global 47 | | |- header 48 | | |- header.js 49 | | |- header.liquid 50 | | |- header.scss 51 | | 52 | |- index 53 | | |- hero-slider 54 | | |- hero-slider.js 55 | | |- hero-slider.liquid 56 | | |- hero-slider.scss 57 | |- ... 58 | ``` 59 | 60 | ## Globbing JS and CSS files 61 | 62 | In this example we have our theme code broken down into modules and encapsulated inside the `modules` folder. These module folders are a concept that helps us reuse code and keep track of logic, markup and styles across complex themes. 63 | 64 | This toolbelt enables this architecture by supporting glob patterns like the examples provided below using a custom Webpack loader: 65 | 66 | ```js 67 | // main.scss 68 | // Our Webpack loader takes this glob pattern and injects found 69 | // files into the bundle. 70 | @import "modules/**/*.scss"; 71 | 72 | // main.js 73 | // Our Webpack loader similarly takes this glob pattern and 74 | // injects found files into the bundle. It'll also chunk the 75 | // files together based on folder. 76 | import 'modules/**/*.js' 77 | ``` 78 | 79 | ## File Type Support 80 | 81 | In addition to style and Javascript files, Liquid is taken out of these module folders and sent to the Snippets, Sections or Templates theme directories. For example: 82 | 83 | ```bash 84 | src/modules/global/header/header.liquid > snippets/header.liquid 85 | src/modules/header/header.section.liquid > sections/header.liquid 86 | src/modules/cart/cart.template.liquid > templates/cart.liquid 87 | ``` 88 | 89 | ## Folder Naming Conventions 90 | 91 | If the top-level module folders are named a certain way, CSS chunking and JS asset chunking is more readily supported. The standard convention is to follow the pattern: `{request.page_type}-{template.suffix}`, where `request.page_type` and `template.suffix` are both properties exposed in Liquid. Here is an example of a common structure of top level module folders: 92 | 93 | ```bash 94 | src 95 | |- modules 96 | |- global 97 | | |- header 98 | | |- header.js 99 | | |- header.liquid 100 | | |- header.scss 101 | | 102 | |- account/ 103 | |- cart/ 104 | |- collection/ 105 | |- product/ 106 | |- page-{template} 107 | |- ... 108 | ``` 109 | -------------------------------------------------------------------------------- /documentation/content/settings/browsersync.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # BrowserSync 9 | 10 | - This group of settings follows the pattern "bs.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/browserSync.js). 12 | - Each setting is commented in the link above. 13 | - These settings are focused on the way the [BrowserSync](https://browsersync.io/) localhost proxy is instantiated. 14 | 15 | ### Noteworthy Settings 16 | 17 | #### bs.local 18 | 19 | This property sets the value of the proxy address that appears in browser. For almost all instances, you'll want to keep this as localhost. However, if you want to do something like debug a remote device on a local network you can set this to you local IP address. 20 | 21 | ```js 22 | { 23 | 'bs.local': 'localhost', 24 | } 25 | ``` 26 | 27 | #### bs.target 28 | 29 | This is the opposite of `bs.local`, it sets the root URL that the proxy will... proxy. You should not have to overwrite this setting directly but it's here so you can see what is happing behind the scenes. If you have a `domain` property configured in your `kit.config.js` it will be prioritized. This is helpful when a Shopify site has gone live and the ".myshopify.com" URL is getting redirected to a primary domain. Setting `domain` will ensure the localhost proxy does not follow the redirect and get pulled out of the localhost proxy. 30 | 31 | ```js 32 | { 33 | 'bs.target': settings => { 34 | return `https://${settings.domain || settings.store}?preview_theme_id=${ 35 | settings['theme'] 36 | }` 37 | } 38 | } 39 | ``` 40 | 41 | #### bs.proxyReplacementsFilter 42 | 43 | Take a read of the [Local Development](/docs/local-development/) section to better understand where this setting fits in. We added this setting so that you don't need to override all BrowserSync proxy replacement rules, rather you can add to them as needed and retain the defaults. 44 | 45 | ```js 46 | { 47 | 'bs.proxyReplacementsFilter'(rules, settings) { 48 | return rules 49 | } 50 | } 51 | ``` 52 | 53 | #### bs.https 54 | 55 | This simply proxy's BrowserSync's [https](https://browsersync.io/docs/options#option-https) option but it is powerful since it allows you to add in your own SSL certificates so you can remove the nasty "Your connection to this site is not secure" browser prompt. 56 | 57 | ```js 58 | { 59 | 'bs.https': true 60 | } 61 | ``` 62 | 63 | Example configuration in a kit.config.js file is below. This would allow different developers to use different certificate pairs, or opt-out of using custom certificates. 64 | 65 | ```js 66 | { 67 | "bs.https": process.env.LOCALHOST_CERT ? { 68 | cert: process.env.LOCALHOST_CERT, 69 | key: process.env.LOCALHOST_KEY 70 | } : true, 71 | } 72 | ``` 73 | 74 | See details on how to get setup with this here: 75 | 76 | - https://ryanparman.com/posts/2019/how-to-create-local-tls-certificates-for-development-on-macos/ 77 | - https://blogjunkie.net/2017/04/enable-https-localhost-browsersync/ 78 | -------------------------------------------------------------------------------- /documentation/content/settings/css.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # CSS 9 | 10 | - This group of settings follows the pattern "css.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/css.js). 12 | - Each setting is commented in the link above. 13 | 14 | If you check out the link above, you'll see that there are a hefty amount of settings available and most of then relate to CSS chunking and critical CSS splitting. For this reason, it's worth reading up on the [CSS Chunking & Critical CSS](/docs/critical-css/) section, and the [Thinking Modular](/docs/thinking-modular) section. 15 | 16 | ### Noteworthy Settings 17 | 18 | #### css.lintStyles 19 | 20 | This property toggles [Stylelint](https://stylelint.io/) linting. 21 | 22 | ```js 23 | { 24 | 'css.lintStyles': true 25 | } 26 | ``` 27 | 28 | #### css.stylelintPaths 29 | 30 | This property sets the glob paths that communicate to [Stylelint](https://stylelint.io/) what files to lint (and thus which to not). 31 | 32 | ```js 33 | { 34 | 'css.stylelintPaths'(settings) { 35 | return [ 36 | `src/assets/scss/**/*.scss`, 37 | `src/modules/**/*.scss`, 38 | `src/sections/**/*.scss` 39 | ] 40 | } 41 | } 42 | ``` 43 | 44 | #### css.chunk 45 | 46 | This is the flag that enables a whole host of CSS chunking and critical CSS behavior (configurable by a whole bunch of settings). This is pretty dependant on the modular approach to ordering your files so as mentioned above, it's worth reading up on the [CSS Chunking & Critical CSS](/docs/critical-css/) section, and the [Thinking Modular](/docs/thinking-modular) section. 47 | 48 | See relevant commented settings [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/css.js). 49 | 50 | ```js 51 | { 52 | 'css.chunk': true 53 | } 54 | ``` 55 | 56 | ### CSS chunking and Critical Example 57 | 58 | Here's an example kit.config.js with CSS chunking and Critical CSS enabled, pulled from one of our projects: 59 | 60 | ```js 61 | { 62 | 'css.chunk': true, 63 | 'css.chunk.criticalWhitelist': ['index'], 64 | 'css.chunk.globalFolders': ['global'], 65 | 'css.chunk.globalFiles': [ 66 | 'account-forms.scss' 67 | ], 68 | 'css.chunk.conditionalFolderMapping': { 69 | account: 'customers' 70 | }, 71 | 'css.chunk.conditionalFilter' (obj, defaultString) { 72 | if (obj.key === 'checkout') { 73 | return 'checkout' 74 | } 75 | return defaultString 76 | } 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /documentation/content/settings/environment.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Environment / Core 9 | 10 | Here we list the "core" settings that allow us to connect to Shopify. These settings are not prefixed like the other settings documented in further pages. 11 | 12 | ## Core Settings 13 | 14 | #### theme 15 | 16 | This connects your computer to a dedicated Shopify theme. This connection applies to both `watch` and `deploy` core commands, among others. 17 | 18 | ```js 19 | { 20 | 'theme': process.env.THEME_ID 21 | } 22 | ``` 23 | 24 | #### password 25 | 26 | The password of a private app with Theme Write permissions, or a password generated from the [Kit Theme Access App](https://apps.shopify.com/theme-kit-access). 27 | 28 | ```js 29 | { 30 | 'password': process.env.PASSWORD 31 | } 32 | ``` 33 | 34 | #### store 35 | 36 | The ".myshopify.com" domain of the instance (without the "https://" protocol). 37 | 38 | ```js 39 | { 40 | 'store': process.env.STORE, 41 | } 42 | ``` 43 | 44 | #### ignore (optional) 45 | 46 | Files to not upload and overwrite in the Shopify-hosted theme. 47 | 48 | ```js 49 | { 50 | 'ignore': [ 51 | 'config/settings_data.json', 52 | /templates\/.*[.]json/ // NEW! 53 | ] 54 | } 55 | ``` 56 | 57 | Recently (v1.1.1 onwards), we added support to have regex values in this setting, as documented above with the "NEW" flag. This is helpful if you want to ignore groups of files from a deployment or when a [sync command](http://localhost:8081/docs/repo-sync/#relevant-commands) is running between a source and build repo. The Pull Request which added this change can be seen [here](https://github.com/halfhelix/Kit/pull/20). 58 | 59 | ```` 60 | 61 | #### domain (optional) 62 | 63 | A domain to use as the target for the localhost proxy rather than the ".myshopify.com" domain. This is useful when a site has gone live and the .myshopify.com domain is getting redirected to another domain. In this case, if you do not set the domain you'll get redirected outside of the localhost proxy. 64 | 65 | Note: Make sure you include the "www." subdomain if the primary domain configured in Shopify also includes this subdomain. 66 | 67 | ```js 68 | { 69 | 'domain': "www.store.halfhelix.com" 70 | } 71 | ```` 72 | 73 | ## Per-environment Configurations 74 | 75 | Every setting (even the ones outlined in subsequent pages) can be configured differently for each environment. The common environments are "development", "staging" and "production" but an environment can be anything, it just needs to match the `--env {environment}` value passed into the `kit` command, e.g. `kit watch --env development`. 76 | 77 | Here's an example of a common `kit.config.js` environment setup (the kit.config.js namespace is `themes.{environment}`): 78 | 79 | ```js 80 | module.exports = { 81 | themes: { 82 | development: { 83 | theme: process.env.THEME_ID, 84 | password: process.env.PASSWORD, 85 | store: process.env.STORE, 86 | ignore: [ 87 | 'config/settings_data.json' 88 | ] 89 | }, 90 | staging: { 91 | theme: process.env.STAGING_THEME_ID || process.env.THEME_ID, 92 | password: process.env.STAGING_PASSWORD || process.env.PASSWORD, 93 | store: process.env.STORE, 94 | ignore: [ 95 | 'config/settings_data.json' 96 | ] 97 | }, 98 | production: { 99 | theme: process.env.PRODUCTION_THEME_ID || process.env.THEME_ID, 100 | password: process.env.PRODUCTION_PASSWORD || process.env.PASSWORD, 101 | store: process.env.STORE, 102 | ignore: [ 103 | 'config/settings_data.json' 104 | ] 105 | } 106 | } 107 | ... 108 | } 109 | ``` 110 | 111 | ## Other core properties 112 | 113 | #### isCI 114 | 115 | This property is used to determine if the command is running in a CI context. We look for the existence of "CI_JOB_NAME" by default, a property set in a Gitlab Runner. 116 | 117 | ```js 118 | { 119 | isCI() { 120 | return !!process.env.CI_JOB_NAME || !!process.env.GITHUB_ACTIONS 121 | } 122 | } 123 | ``` 124 | 125 | #### watch 126 | 127 | The source files that trigger file change events. 128 | 129 | ```js 130 | { 131 | watch: settings => { 132 | return `${settings['path.src']}/**/*` 133 | } 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /documentation/content/settings/git.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Git 9 | 10 | - This group of settings follows the pattern "git.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/git.js). 12 | - Each setting is commented in the link above. 13 | 14 | This settings primarily service the Gitab Integration, particularly around automated Gitlab merge request creation and Git history validation. It's worth reading up on the [Gitlab Integration](/docs/gitlab-integration/) section. 15 | 16 | ### Noteworthy Settings 17 | 18 | #### git.gitlabToken 19 | 20 | The Gitlab token to use to authenticate Gitlab API requests with. This can be a Personal Access Token with "api" scope permissions. 21 | 22 | ```js 23 | { 24 | 'git.gitlabToken': '', 25 | } 26 | ``` 27 | 28 | #### git.maintainer 29 | 30 | The Gitlab user handle to use as the assignee for Gitlab merge requests (omit the "@" symbol). 31 | 32 | ```js 33 | { 34 | 'git.maintainer': '' 35 | } 36 | ``` 37 | 38 | #### git.gitlabMergeRequestConfig 39 | 40 | Properties to pass into the Gitlab API request that generates programmatic merge requests. See Gitlab documentation [here](https://docs.gitlab.com/ee/api/merge_requests.html#create-mr). Note that the "source_branch", "title", "target_branch", "assignee_id" properties are automatically set and configurable by other settings (see all Git settings [here](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/git.js)). 41 | 42 | ```js 43 | { 44 | 'git.gitlabMergeRequestConfig': { 45 | remove_source_branch: true 46 | } 47 | } 48 | ``` 49 | 50 | #### git.gitlabMergeRequestTitle 51 | 52 | The title of the programmatic merge request. 53 | 54 | ```js 55 | { 56 | 'git.gitlabMergeRequestTitle'(branch, targetbranch, settings) { 57 | return `[WIP] ${branch} into ${targetbranch}` 58 | } 59 | } 60 | ``` 61 | 62 | #### git.emailRegex 63 | 64 | This sets the emails that are approved when running the Gitlab Git history linting command. If a commit has been signed with an invalid email the CI job running the linting command will fail. 65 | 66 | ```js 67 | { 68 | 'git.emailRegex': /@halfhelix.com/ 69 | } 70 | ``` 71 | 72 | #### git.messageValidator 73 | 74 | This function is used to validate the commit when running the Gitlab Git history linting command. If a commit has been signed with an invalid email the CI job running the linting command will fail. 75 | 76 | ```js 77 | { 78 | 'git.messageValidator'(commit, settings) { 79 | return commit.title.split(' ').length > 1 80 | } 81 | } 82 | ``` 83 | 84 | #### git.branchValidator 85 | 86 | This function is used to validate the branch name when running the Gitlab Git history linting command. If the branch name is invalid the CI job running the linting command will fail. 87 | 88 | ```js 89 | { 90 | 'git.branchValidator'(branch, settings) { 91 | return /master|production|feature\/|bugfix\/|qa\//.test(branch) 92 | } 93 | } 94 | ``` 95 | -------------------------------------------------------------------------------- /documentation/content/settings/javascript.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Javascript 9 | 10 | - This group of settings follows the pattern "js.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/javascript.js). 12 | - Each setting is commented in the link above. 13 | 14 | This settings primary service Webpack config generation, and the way that CSS and Javascript are added to bundles via glob patterns. It's worth reading up on the [Javascript Chunking](/docs/javascript-chunking/) section, and the [Thinking Modular](/docs/thinking-modular) section. 15 | 16 | ### Noteworthy Settings 17 | 18 | #### js.filterWebpackConfig 19 | 20 | Filter the entire Webpack Config Javascript object literal right before it is sent to Webpack in any command. 21 | 22 | ```js 23 | { 24 | 'js.filterWebpackConfig'(config, settings) { 25 | return config 26 | }, 27 | } 28 | ``` 29 | 30 | Note: There are settings available to override the Webpack "mode", "devTool", "performance" and "stats" configurations specifically. 31 | 32 | #### js.hmr 33 | 34 | Toggles the Hot Module Reloading Webpack functionality used to reload the browser when bundled assets are changed on and off. This can be turned off when debugging a network-connected mobile device. 35 | 36 | ```js 37 | { 38 | 'js.hmr': true, 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /documentation/content/settings/path.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Path 9 | 10 | - This group of settings follows the pattern "path.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/path.js). 12 | - Each setting is commented in the link above. 13 | 14 | ### Noteworthy Settings 15 | 16 | #### path.dist 17 | 18 | Name of the dist directory to use when building the theme. 19 | 20 | ```js 21 | { 22 | 'path.dist': path.normalize(`${CWD}/dist`), 23 | } 24 | ``` 25 | 26 | #### path.src 27 | 28 | Name of the src directory to fetch source files from (a child directory of your repo). 29 | 30 | ```js 31 | { 32 | 'path.src': path.normalize(`${CWD}/src`), 33 | } 34 | ``` 35 | 36 | #### path.cdn 37 | 38 | This one is a little unique. Since we are compiling javascript and CSS locally in the `watch` command and not sending these files to Shopify on every change (mentioned in [Local Development](/docs/local-development)), we have found the need to interpret the `asset_url` filter when Liquid has been used on SCSS files. Here, take the Shopify CDN of a theme asset in your instance and add it here. We have a custom loader that will shim `'{{ '{path}.{mine}' | asset_url }}` and add in this property value. 39 | 40 | We will note here that using Liquid in SCSS files does have a performance impact and should typically be avoided. 41 | 42 | ```js 43 | { 44 | 'path.cdn': 'https://cdn.shopify.com/replace-this', 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /documentation/content/settings/shopify.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Shopify 9 | 10 | - This group of settings follows the pattern "shopify.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/shopify.js). 12 | - Each setting is commented in the link above. 13 | 14 | ### Noteworthy Settings 15 | 16 | #### shopify.requestsPerInterval 17 | 18 | The amount of requests that can be handled simultaneously when deploying assets. This can be set to "4" when the instance is a Shopify Plus instance. It can be set to "5" as a max but expect certain requests to hit a throttle limit and automatically be retried at the end of the deployment queue. 19 | 20 | ```js 21 | { 22 | 'shopify.requestsPerInterval': 2 23 | } 24 | ``` 25 | 26 | #### shopify.cdnPathVar 27 | 28 | An in-browser variable in the global scope to use to retrieve the Shopify CDN path for the current theme. We use this to allow Webpack to understand the location from which to fetch Javascript file chunks in a runtime context. 29 | 30 | ```js 31 | { 32 | 'shopify.cdnPathVar': '__GLOBAL__.cdn', 33 | } 34 | ``` 35 | 36 | This should be set in the top of the `` of the document. For example: 37 | 38 | ```js 39 | var __GLOBAL__ = { 40 | cdn: "{{ 'test.jpg' | asset_url }}".replace(/test.jpg\?\d*/, '') 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /documentation/content/settings/theme-name.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: '' 3 | sidebar: 'docs' 4 | prev: '/docs' 5 | next: '/docs' 6 | --- 7 | 8 | # Theme Name 9 | 10 | - This group of settings follows the pattern "themeName.{settingName}". 11 | - The defaults for these settings can be found [via this link](https://github.com/halfhelix/Kit/blob/master/packages/configure/src/defaults/themeName.js). 12 | - Each setting is commented in the link above. 13 | 14 | ### Noteworthy Settings 15 | 16 | #### themeName.format 17 | 18 | Determines the theme name format base on the --env flag value. 19 | 20 | ```js 21 | { 22 | 'themeName.format'({ env }) { 23 | if (env === 'production') { 24 | return '[LIVE] {context} - {branch} - {commit} - {date}' 25 | } 26 | if (env === 'staging') { 27 | return '[STAGE] {context} - {branch} - {commit} - {date}' 28 | } 29 | if (env === 'development') { 30 | return '[DEV] {name} - {date}' 31 | } 32 | }, 33 | } 34 | ``` 35 | 36 | The available tokens are applied in this function: 37 | 38 | ```js 39 | const formatName = async (settings, format) => { 40 | const commit = await settings['git.getCommit'](settings, getCommit) 41 | const date = await settings['git.getDate'](settings, getDate) 42 | const branch = await settings['git.getBranch'](settings, getBranch) 43 | const username = await settings['git.getUsername'](settings, getUsername) 44 | 45 | return format 46 | .replace('{context}', settings.isCI() ? 'CI' : '💻') 47 | .replace('{branch}', branch.split('/').pop()) 48 | .replace('{commit}', commit) 49 | .replace('{date}', date) 50 | .replace('{name}', username.split(' ').shift()) 51 | } 52 | ``` 53 | 54 | If you want to override default functionality but simplify the function, you can add it to the specific environment config: 55 | 56 | ```js 57 | module.exports = { 58 | themes: { 59 | development: { 60 | 'themeName.format'({ env }) { 61 | return '[DEV] {context} - {branch} - {commit} - {date}' 62 | } 63 | ... 64 | }, 65 | ... 66 | } 67 | ... 68 | } 69 | ``` 70 | 71 | #### themeName.update 72 | 73 | Determines if the theme name should be updated using the format above as part of the `deploy` command routine. By default, we only allow this in a CI/CD context (see [here](/settings/environment/#isci)) and not in a "development" environment. 74 | 75 | ```js 76 | { 77 | 'themeName.update'(settings) { 78 | return settings.env !== 'development' && settings.isCI() 79 | } 80 | }, 81 | } 82 | ``` 83 | -------------------------------------------------------------------------------- /documentation/gridsome.config.js: -------------------------------------------------------------------------------- 1 | // This is where project configuration and plugin options are located. 2 | // Learn more: https://gridsome.org/docs/config 3 | 4 | // Changes here require a server restart. 5 | // To restart press CTRL + C in terminal and run `gridsome develop` 6 | 7 | module.exports = { 8 | siteName: 'Kit.', 9 | icon: { 10 | favicon: './src/assets/favicon.png', 11 | touchicon: './src/assets/favicon.png' 12 | }, 13 | siteUrl: process.env.SITE_URL 14 | ? process.env.SITE_URL 15 | : 'https://kit.halfhelix.com', 16 | settings: { 17 | web: process.env.URL_WEB || false, 18 | twitter: process.env.URL_TWITTER || false, 19 | github: process.env.URL_GITHUB || false, 20 | nav: { 21 | links: [{ path: '/docs/', title: 'Docs' }] 22 | }, 23 | sidebar: [ 24 | { 25 | name: 'docs', 26 | sections: [ 27 | { 28 | title: 'The Basics', 29 | items: [ 30 | '/docs/', 31 | '/docs/installation/', 32 | '/docs/theme-setup/', 33 | '/docs/getting-started/', 34 | '/docs/commands/', 35 | '/docs/local-development/', 36 | '/docs/thinking-modular/' 37 | // '/docs/deploy/' 38 | ] 39 | }, 40 | { 41 | title: 'Features', 42 | items: [ 43 | '/docs/critical-css/', 44 | '/docs/javascript-chunking/', 45 | '/docs/linting/', 46 | '/docs/gitlab-integration/', 47 | '/docs/theme-naming/' 48 | ] 49 | }, 50 | { 51 | title: 'Online Store 2.0', 52 | items: [ 53 | '/docs/repo-sync/', 54 | '/docs/developer-themes/', 55 | '/docs/theme-kit-access-tokens/' 56 | ] 57 | }, 58 | { 59 | title: 'Settings Reference', 60 | items: [ 61 | '/settings/environment/', 62 | '/settings/browsersync/', 63 | '/settings/css/', 64 | '/settings/git/', 65 | '/settings/javascript/', 66 | '/settings/path/', 67 | '/settings/shopify/', 68 | '/settings/theme-name/' 69 | ] 70 | }, 71 | { 72 | title: 'Other Stuff', 73 | items: ['/docs/contributing/', '/docs/testing-on-mobile/'] 74 | } 75 | ] 76 | } 77 | ] 78 | }, 79 | plugins: [ 80 | { 81 | use: '@gridsome/source-filesystem', 82 | options: { 83 | baseDir: './content', 84 | path: '**/*.md', 85 | typeName: 'MarkdownPage', 86 | remark: { 87 | externalLinksTarget: '_blank', 88 | externalLinksRel: ['noopener', 'noreferrer'], 89 | plugins: ['@gridsome/remark-prismjs'] 90 | } 91 | } 92 | }, 93 | 94 | { 95 | use: 'gridsome-plugin-tailwindcss', 96 | options: { 97 | tailwindConfig: './tailwind.config.js', 98 | purgeConfig: { 99 | // Prevent purging of prism classes. 100 | whitelistPatternsChildren: [/token$/] 101 | } 102 | } 103 | }, 104 | 105 | { 106 | use: '@gridsome/plugin-google-analytics', 107 | options: { 108 | id: process.env.GA_ID ? process.env.GA_ID : 'XX-999999999-9' 109 | } 110 | }, 111 | 112 | { 113 | use: '@gridsome/plugin-sitemap', 114 | options: {} 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /documentation/gridsome.server.js: -------------------------------------------------------------------------------- 1 | // Server API makes it possible to hook into various parts of Gridsome 2 | // on server-side and add custom data to the GraphQL data layer. 3 | // Learn more: https://gridsome.org/docs/server-api/ 4 | 5 | // Changes here require a server restart. 6 | // To restart press CTRL + C in terminal and run `gridsome develop` 7 | 8 | module.exports = function (api) { 9 | api.loadSource(({ addCollection, addMetadata }) => { 10 | // Use the Data Store API here: https://gridsome.org/docs/data-store-api/ 11 | addMetadata('settings', require('./gridsome.config').settings); 12 | }); 13 | 14 | api.createPages(({ createPage }) => { 15 | // Use the Pages API here: https://gridsome.org/docs/pages-api/ 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /documentation/netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | base = "documentation/" 3 | command = "gridsome build" 4 | publish = "dist/" -------------------------------------------------------------------------------- /documentation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "private": true, 4 | "scripts": { 5 | "start": "gridsome develop", 6 | "build": "gridsome build", 7 | "develop": "gridsome develop", 8 | "explore": "gridsome explore" 9 | }, 10 | "dependencies": { 11 | "gridsome": "^0.7.0" 12 | }, 13 | "devDependencies": { 14 | "@gridsome/plugin-google-analytics": "^0.1.0", 15 | "@gridsome/plugin-sitemap": "^0.2.3", 16 | "@gridsome/remark-prismjs": "^0.3.0", 17 | "@gridsome/source-filesystem": "^0.6.2", 18 | "@gridsome/transformer-remark": "^0.5.0", 19 | "fuse.js": "^3.4.6", 20 | "gridsome-plugin-tailwindcss": "^2.2.36", 21 | "node-sass": "^4.13.1", 22 | "prism-themes": "^1.3.0", 23 | "sass-loader": "^8.0.2", 24 | "tailwindcss": "^1.2.0", 25 | "vue-feather-icons": "^5.0.0" 26 | } 27 | } -------------------------------------------------------------------------------- /documentation/src/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meetdomaine/Kit/7af2757671567d32f128949325a508b67d4a747f/documentation/src/assets/favicon.png -------------------------------------------------------------------------------- /documentation/src/components/LayoutHeader.vue: -------------------------------------------------------------------------------- 1 | 62 | 63 | 64 | query { 65 | metadata { 66 | siteName 67 | settings { 68 | web 69 | github 70 | twitter 71 | nav { 72 | links { 73 | path 74 | title 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | 82 | 111 | 112 | 127 | -------------------------------------------------------------------------------- /documentation/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 23 | 43 | 44 | -------------------------------------------------------------------------------- /documentation/src/components/NextPrevLinks.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 58 | -------------------------------------------------------------------------------- /documentation/src/components/OnThisPage.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 121 | -------------------------------------------------------------------------------- /documentation/src/components/README.md: -------------------------------------------------------------------------------- 1 | Add components that will be imported to Pages and Layouts to this folder. 2 | Learn more about components here: https://gridsome.org/docs/components/ 3 | 4 | You can delete this file. 5 | -------------------------------------------------------------------------------- /documentation/src/components/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 44 | query Sidebar { 45 | metadata { 46 | settings { 47 | sidebar { 48 | name 49 | sections { 50 | title 51 | items 52 | } 53 | } 54 | } 55 | } 56 | } 57 | 58 | 59 | 96 | -------------------------------------------------------------------------------- /documentation/src/components/ToggleDarkMode.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 67 | 68 | -------------------------------------------------------------------------------- /documentation/src/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meetdomaine/Kit/7af2757671567d32f128949325a508b67d4a747f/documentation/src/favicon.png -------------------------------------------------------------------------------- /documentation/src/layouts/README.md: -------------------------------------------------------------------------------- 1 | Layout components are used to wrap pages and templates. Layouts should contain components like headers, footers or sidebars that will be used across the site. 2 | 3 | Learn more about Layouts: https://gridsome.org/docs/layouts/ 4 | 5 | You can delete this file. 6 | -------------------------------------------------------------------------------- /documentation/src/main.js: -------------------------------------------------------------------------------- 1 | // This is the main.js file. Import global CSS and scripts here. 2 | // The Client API can be used here. Learn more: gridsome.org/docs/client-api 3 | import DefaultLayout from '~/layouts/Default.vue' 4 | 5 | export default function (Vue, { router, head, isClient }) { 6 | // Set default layout as a global component 7 | Vue.component('Layout', DefaultLayout) 8 | 9 | head.link.push({ 10 | rel: 'stylesheet', 11 | href: 'https://fonts.googleapis.com/css2?family=Cormorant&family=Fira+Sans+Condensed:wght@500&family=Nunito&display=swap' 12 | }) 13 | 14 | router.beforeEach((to, _from, next) => { 15 | head.meta.push({ 16 | key: 'og:url', 17 | name: 'og:url', 18 | content: process.env.GRIDSOME_BASE_PATH + to.path, 19 | }) 20 | next() 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /documentation/src/pages/404.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /documentation/src/pages/README.md: -------------------------------------------------------------------------------- 1 | Pages are usually used for normal pages or for listing items from a GraphQL collection. 2 | Add .vue files here to create pages. For example **About.vue** will be **site.com/about**. 3 | Learn more about pages: https://gridsome.org/docs/pages/ 4 | 5 | You can delete this file. 6 | -------------------------------------------------------------------------------- /documentation/src/templates/MarkdownPage.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | query ($id: ID!) { 23 | markdownPage(id: $id) { 24 | id 25 | title 26 | description 27 | path 28 | timeToRead 29 | content 30 | sidebar 31 | next 32 | prev 33 | headings { 34 | depth 35 | value 36 | anchor 37 | } 38 | } 39 | allMarkdownPage{ 40 | edges { 41 | node { 42 | path 43 | title 44 | } 45 | } 46 | } 47 | } 48 | 49 | 50 | 96 | 97 | -------------------------------------------------------------------------------- /documentation/src/templates/README.md: -------------------------------------------------------------------------------- 1 | Templates for **GraphQL collections** should be added here. 2 | To create a template for a collection called `WordPressPost` 3 | create a file named `WordPressPost.vue` in this folder. 4 | 5 | Learn more: https://gridsome.org/docs/templates/ 6 | 7 | You can delete this file. 8 | -------------------------------------------------------------------------------- /documentation/static/README.md: -------------------------------------------------------------------------------- 1 | Add static files here. Files in this directory will be copied directly to `dist` folder during build. For example, /static/robots.txt will be located at https://yoursite.com/robots.txt. 2 | 3 | This file should be deleted. -------------------------------------------------------------------------------- /documentation/static/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meetdomaine/Kit/7af2757671567d32f128949325a508b67d4a747f/documentation/static/logo.jpg -------------------------------------------------------------------------------- /documentation/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | extend: { 4 | fontFamily: { 5 | display: ['Cormorant', 'serif'] 6 | }, 7 | colors: { 8 | ui: { 9 | background: 'var(--color-ui-background)', 10 | sidebar: 'var(--color-ui-sidebar)', 11 | typo: 'var(--color-ui-typo)', 12 | primary: 'var(--color-ui-primary)', 13 | border: 'var(--color-ui-border)' 14 | } 15 | }, 16 | spacing: { 17 | sm: '24rem' 18 | }, 19 | screens: { 20 | xxl: '1400px' 21 | } 22 | }, 23 | container: { 24 | center: true, 25 | padding: '1rem' 26 | } 27 | }, 28 | variants: {}, 29 | plugins: [], 30 | } 31 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "1.2.0" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@halfhelix/kit", 3 | "version": "0.0.1-beta.0", 4 | "description": "A frontend helper monorepo by the folks at Half Helix", 5 | "scripts": { 6 | "bootstrap": "lerna bootstrap", 7 | "clean": "lerna clean", 8 | "test:watch": "node node_modules/.bin/ava packages/**/test/** -v -w --match='Focus:*'", 9 | "test": "node node_modules/.bin/ava packages/**/test/** -v" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/halfhelix/Kit.git" 14 | }, 15 | "ava": { 16 | "require": [ 17 | "./test/helpers/dependency-interceptor.js" 18 | ] 19 | }, 20 | "homepage": "https://github.com/halfhelix/Kit#readme", 21 | "author": "https://halfhelix.com", 22 | "license": "MIT", 23 | "devDependencies": { 24 | "ava": "^3.8.2", 25 | "lodash.clonedeep": "^4.5.0", 26 | "nock": "^13.0.2", 27 | "pirates": "^4.0.1", 28 | "sinon": "^9.0.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/README.md: -------------------------------------------------------------------------------- 1 | # Half Helix / Kit 2 | 3 | This is a toolkit that we use internally at Half Helix to develop our frontend Shopify themes. It enables us to develop websites the way that we want to, with a focus on modularity. We developed this tool for our own team but hey, we thought that there might be other people out there that could enjoy this so we made it public. 4 | 5 | ### Installation 6 | 7 | ``` 8 | npm i -g @halfhelix/kit 9 | ``` 10 | 11 | ### Documentation 12 | 13 | Documentation for this tool is available at [kit.halfhelix.com](https://kit.halfhelix.com) 14 | -------------------------------------------------------------------------------- /packages/cli/lib/getPackageInformation.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch') 2 | 3 | module.exports.getPackageInformation = (package) => { 4 | return fetch(`https://registry.npmjs.org/${package}`) 5 | .then((response) => { 6 | return response.json() 7 | }) 8 | .then( 9 | ({ name = '', 'dist-tags': distTags = {}, maintainers = [] } = {}) => { 10 | const response = { 11 | name, 12 | distTags, 13 | maintainers 14 | } 15 | if (distTags.latest) { 16 | response['version'] = distTags.latest 17 | } 18 | return Promise.resolve(response) 19 | } 20 | ) 21 | .catch((error) => { 22 | return Promise.resolve({}) 23 | }) 24 | } 25 | 26 | module.exports.getVersionDetails = (details, version) => { 27 | if (details.version) { 28 | return { 29 | message: `${details.version} (latest: ${details.version})`, 30 | isCurrent: '' + details.version === '' + version 31 | } 32 | } 33 | return { 34 | message: version || '', 35 | isCurrent: false 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/cli/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@halfhelix/kit", 3 | "version": "1.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "commander": { 8 | "version": "8.1.0", 9 | "resolved": "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz", 10 | "integrity": "sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA==" 11 | }, 12 | "node-fetch": { 13 | "version": "2.6.1", 14 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 15 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@halfhelix/kit", 3 | "version": "1.2.0", 4 | "description": "A Shopify development toolkit", 5 | "main": "index.js", 6 | "bin": { 7 | "kit": "./cli.js" 8 | }, 9 | "scripts": { 10 | "release": "npm publish --access public", 11 | "lint": "prettier --write {,**/}*.js" 12 | }, 13 | "keywords": [ 14 | "shopify", 15 | "themekit", 16 | "themes" 17 | ], 18 | "homepage": "https://github.com/halfhelix/Kit#readme", 19 | "author": "https://halfhelix.com", 20 | "license": "MIT", 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "dependencies": { 25 | "@halfhelix/configure": "1.2.0", 26 | "@halfhelix/gitlab-kit": "1.2.0", 27 | "@halfhelix/shopify-kit": "1.2.0", 28 | "@halfhelix/terminal-kit": "1.2.0", 29 | "@halfhelix/webpacker": "1.2.0", 30 | "commander": "^8.1.0", 31 | "node-fetch": "^2.6.1" 32 | }, 33 | "gitHead": "436453a333a2db6e13dc024ba070920951f24e43" 34 | } 35 | -------------------------------------------------------------------------------- /packages/configure/README.md: -------------------------------------------------------------------------------- 1 | ![](https://i.imgur.com/emcU0vv.gif) 2 | 3 | > This is an internal dependency for [@halfhelix/kit](https://www.npmjs.com/package/@halfhelix/kit). Please refer to this package for further details. 4 | -------------------------------------------------------------------------------- /packages/configure/configure.js: -------------------------------------------------------------------------------- 1 | const yaml = require('js-yaml') 2 | const fs = require('fs-extra') 3 | const { warning } = require('@halfhelix/terminal-kit') 4 | 5 | require('dotenv').config() 6 | 7 | const defaults = require('./src/defaults') 8 | const utils = require('./src/utils') 9 | const emitter = require('./src/emitter') 10 | 11 | function readConfigFiles() { 12 | const config = defaults['path.config'].reduce((obj, path) => { 13 | if (!fs.existsSync(path)) { 14 | return obj 15 | } 16 | 17 | if (~path.indexOf('yml')) { 18 | return yaml.safeLoad(fs.readFileSync(path)) 19 | } else { 20 | return require(path) 21 | } 22 | }, {}) 23 | 24 | if (fs.existsSync(defaults['path.webpack'])) { 25 | config.webpack = require(defaults['path.webpack']) 26 | } 27 | 28 | return config 29 | } 30 | 31 | function validateConfig(config, env) { 32 | if (!config.themes || !config.themes[env]) { 33 | throw new Error(`No settings for current env: ${env}`) 34 | } 35 | } 36 | 37 | async function getDeveloperTheme() { 38 | const branch = await defaults['git.getBranch'](defaults, utils.getBranch) 39 | const themeLog = utils.readThemeLogFile(defaults) 40 | if (themeLog[branch]) { 41 | return { theme: themeLog[branch] } 42 | } else { 43 | warning(`Developer theme ID for "${branch}" not found`) 44 | warning(`Falling back to kit.config.js theme`) 45 | } 46 | } 47 | 48 | module.exports = async (options) => { 49 | Object.assign(defaults, options) 50 | 51 | process.env.NODE_ENV = options.env 52 | 53 | const config = readConfigFiles() 54 | validateConfig(config, options.env) 55 | 56 | Object.assign( 57 | defaults, 58 | config, 59 | config.themes[options.env], 60 | options, 61 | options.isDeveloper ? await getDeveloperTheme() : {}, 62 | emitter 63 | ) 64 | return defaults 65 | } 66 | 67 | module.exports.settings = defaults 68 | module.exports.utils = utils 69 | -------------------------------------------------------------------------------- /packages/configure/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@halfhelix/configure", 3 | "version": "1.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "argparse": { 8 | "version": "1.0.10", 9 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 10 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 11 | "requires": { 12 | "sprintf-js": "~1.0.2" 13 | } 14 | }, 15 | "dotenv": { 16 | "version": "8.2.0", 17 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", 18 | "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" 19 | }, 20 | "esprima": { 21 | "version": "4.0.1", 22 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 23 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 24 | }, 25 | "fs-extra": { 26 | "version": "8.1.0", 27 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 28 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 29 | "requires": { 30 | "graceful-fs": "^4.2.0", 31 | "jsonfile": "^4.0.0", 32 | "universalify": "^0.1.0" 33 | } 34 | }, 35 | "graceful-fs": { 36 | "version": "4.2.3", 37 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 38 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" 39 | }, 40 | "js-yaml": { 41 | "version": "3.13.1", 42 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 43 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 44 | "requires": { 45 | "argparse": "^1.0.7", 46 | "esprima": "^4.0.0" 47 | } 48 | }, 49 | "jsonfile": { 50 | "version": "4.0.0", 51 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 52 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 53 | "requires": { 54 | "graceful-fs": "^4.1.6" 55 | } 56 | }, 57 | "sprintf-js": { 58 | "version": "1.0.3", 59 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 60 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 61 | }, 62 | "universalify": { 63 | "version": "0.1.2", 64 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 65 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/configure/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@halfhelix/configure", 3 | "version": "1.2.0", 4 | "description": "", 5 | "main": "configure.js", 6 | "author": "https://halfhelix.com", 7 | "license": "MIT", 8 | "scripts": { 9 | "release": "npm publish --access public", 10 | "lint": "prettier --write {,**/}*.js" 11 | }, 12 | "publishConfig": { 13 | "access": "public" 14 | }, 15 | "dependencies": { 16 | "@halfhelix/terminal-kit": "1.2.0", 17 | "dotenv": "^8.2.0", 18 | "fs-extra": "^8.1.0", 19 | "js-yaml": "^3.12.0" 20 | }, 21 | "gitHead": "436453a333a2db6e13dc024ba070920951f24e43" 22 | } 23 | -------------------------------------------------------------------------------- /packages/configure/src/constants.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | CWD: process.cwd() 3 | } 4 | -------------------------------------------------------------------------------- /packages/configure/src/defaults.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('./defaults/path'), 3 | ...require('./defaults/git'), 4 | ...require('./defaults/themeName'), 5 | ...require('./defaults/cypress'), 6 | ...require('./defaults/css'), 7 | ...require('./defaults/debug'), 8 | ...require('./defaults/browserSync'), 9 | ...require('./defaults/javascript'), 10 | ...require('./defaults/shopify'), 11 | theme: '', 12 | password: '', 13 | store: '', 14 | domain: false, 15 | ignore: ['config/settings_data.json'], 16 | webpack: {}, 17 | isCI() { 18 | return !!process.env.CI_JOB_NAME || !!process.env.GITHUB_ACTIONS 19 | }, 20 | watch: (settings) => { 21 | return `${settings['path.src']}/**/*` 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/configure/src/defaults/browserSync.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Proxies https://browsersync.io/docs/options#option-online 3 | 'bs.online': true, 4 | // Proxies https://browsersync.io/docs/options#option-host 5 | 'bs.local': 'localhost', 6 | // Sets the URL that localhost (bs.local) proxies 7 | 'bs.target': (settings) => { 8 | return `https://${settings.domain || settings.store}?preview_theme_id=${ 9 | settings['theme'] 10 | }` 11 | }, 12 | 'bs.https': true, 13 | // Sets the location that BrowserSync places the live reload snippet 14 | 'bs.snippetPlacement'(settings) { 15 | return { 16 | match: /<\/body>/i, 17 | fn: function (snippet, match) { 18 | return snippet + match 19 | } 20 | } 21 | }, 22 | // Automatically open the proxy in a new browser window 23 | 'bs.open': true, 24 | // Sets a hard delay live reload event and browser reload 25 | 'bs.reloadDelay': 1000, 26 | // A set of regular expressions that transform HTML in the Proxy 27 | // before it is downloaded by the browser. This set is consumed 28 | // when CSS is not chunked (activated via CSS setting) 29 | 'bs.proxyReplacements.normal': [ 30 | { 31 | regex: /]*><\/script>/gi, 32 | replacement() {} 33 | }, 34 | { 35 | regex: /]*>/gi, 36 | replacement(settings) { 37 | return `` 38 | } 39 | } 40 | ], 41 | // A set of regular expressions that transform HTML in the Proxy 42 | // before it is downloaded by the browser. This set is consumed 43 | // when CSS is chunked (activated via CSS setting) 44 | 'bs.proxyReplacements.chunked': [ 45 | { 46 | regex: /]*><\/script>/gi, 47 | replacement() {} 48 | }, 49 | { 50 | regex: /]* data-kit>/gi, 51 | replacement() {} 52 | }, 53 | { 54 | regex: /