shopic 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +160 -0
- package/dist/index.js +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# shopic
|
|
2
|
+
|
|
3
|
+
Custom code bundle for the Shopic Webflow site. TypeScript, bundled with esbuild,
|
|
4
|
+
published to npm and served to Webflow over the jsDelivr CDN.
|
|
5
|
+
|
|
6
|
+
## How the code reaches the site
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
src/*.ts → esbuild → dist/*.js → npm publish → cdn.jsdelivr.net/npm/shopic@<version>/dist/index.js
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
npm stores the versions; jsDelivr is the CDN that serves them. The published package
|
|
13
|
+
is public even though this repository is not — that is the price of a free CDN.
|
|
14
|
+
|
|
15
|
+
## Local development
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm install
|
|
19
|
+
pnpm dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`pnpm dev` serves the bundle at `http://localhost:3000` with live reload.
|
|
23
|
+
|
|
24
|
+
Put this in **Site Settings → Custom Code → Footer** once, and leave it there. It
|
|
25
|
+
loads the CDN build for everyone, and the local build only for a browser you have
|
|
26
|
+
flipped into dev mode:
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<script>
|
|
30
|
+
(() => {
|
|
31
|
+
const PROD = 'https://cdn.jsdelivr.net/npm/shopic@0.0.1/dist/index.js';
|
|
32
|
+
const DEV = 'http://localhost:3000/index.js';
|
|
33
|
+
|
|
34
|
+
const load = (src, fallback) => {
|
|
35
|
+
const s = document.createElement('script');
|
|
36
|
+
s.src = src;
|
|
37
|
+
if (fallback) s.onerror = fallback;
|
|
38
|
+
document.head.appendChild(s);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
if (localStorage.getItem('shopic-dev') === 'on') load(DEV, () => load(PROD));
|
|
42
|
+
else load(PROD);
|
|
43
|
+
})();
|
|
44
|
+
</script>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Flip it on in the console on the staging domain, once:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
localStorage.setItem('shopic-dev', 'on'); // off: localStorage.removeItem('shopic-dev')
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Without that gate every visitor's browser would probe your localhost. With it,
|
|
54
|
+
only yours does, and it falls back to the CDN the moment `pnpm dev` is not running.
|
|
55
|
+
|
|
56
|
+
Two things to know: Chrome and Firefox allow `http://localhost` from an HTTPS page,
|
|
57
|
+
**Safari blocks it** — work in Chrome. And the dev URL has no `/dist` in it, because
|
|
58
|
+
esbuild serves that directory as the root (`src/pages/home.ts` → `/pages/home.js`).
|
|
59
|
+
|
|
60
|
+
## Releasing
|
|
61
|
+
|
|
62
|
+
Every release is run by hand from this folder. There is no CI — the GitHub
|
|
63
|
+
repository is history and backup, nothing publishes from it.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pnpm changeset # describe the change, pick patch/minor/major
|
|
67
|
+
pnpm changeset version # bumps the version, writes CHANGELOG.md
|
|
68
|
+
git commit -am "release: 0.0.1"
|
|
69
|
+
|
|
70
|
+
npm publish --access public # browser opens, confirm with the passkey
|
|
71
|
+
git tag v0.0.1
|
|
72
|
+
git push --follow-tags
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Publish with `npm`, not `pnpm changeset publish`.** Changesets detects the pnpm
|
|
76
|
+
lockfile and hands the publish to `pnpm publish`, and its only 2FA path is a typed
|
|
77
|
+
six-digit code (`Enter one-time password:`). This account uses a passkey, where no
|
|
78
|
+
such code exists — the prompt is a dead end. `changeset version` still does the real
|
|
79
|
+
work; `changeset publish` would only have added the git tag, which the command above
|
|
80
|
+
does directly.
|
|
81
|
+
|
|
82
|
+
This needs **npm CLI 11.9 or newer**; older versions cannot drive the WebAuthn
|
|
83
|
+
browser hand-off and fall back to asking for a code that does not exist.
|
|
84
|
+
|
|
85
|
+
`prepublishOnly` runs `check`, `lint` and `build` before npm packs anything, so a
|
|
86
|
+
published tarball can never contain a stale `dist`. If any of the three fails, the
|
|
87
|
+
publish stops.
|
|
88
|
+
|
|
89
|
+
That guard matters because **npm versions are immutable**. You cannot replace a
|
|
90
|
+
published version — a mistake costs you a new one.
|
|
91
|
+
|
|
92
|
+
Provenance is off. npm only signs builds from public source repositories, and this
|
|
93
|
+
one is private.
|
|
94
|
+
|
|
95
|
+
**Always pin the version in the script tag.** jsDelivr caches unversioned and
|
|
96
|
+
branch URLs for hours; `@latest` will serve stale code and cost you an afternoon.
|
|
97
|
+
|
|
98
|
+
## Animations
|
|
99
|
+
|
|
100
|
+
GSAP is **not bundled**. It loads from Webflow's native Site Settings toggle, and this
|
|
101
|
+
bundle reads the global. `src/lib/gsap.ts` throws a named error if the toggle is off —
|
|
102
|
+
a site transfer wipes Site Settings, and a silent failure would ship a site with no motion.
|
|
103
|
+
|
|
104
|
+
Animations are driven by the `data-anim` attribute so the client can move markup around
|
|
105
|
+
in the Designer without breaking motion:
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<div data-anim="hero-reveal">…</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Register the handler under the same name:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// src/anim/hero-reveal.ts
|
|
115
|
+
import { registerAnimation } from '$anim/registry';
|
|
116
|
+
|
|
117
|
+
registerAnimation('hero-reveal', (element, { gsap, reducedMotion }) => {
|
|
118
|
+
if (reducedMotion) return;
|
|
119
|
+
gsap.from(element, { autoAlpha: 0, y: 24, duration: 0.6 });
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Import the file in `src/anim/index.ts`. An unregistered `data-anim` value warns in the
|
|
124
|
+
console instead of throwing.
|
|
125
|
+
|
|
126
|
+
## Entry points
|
|
127
|
+
|
|
128
|
+
- `src/index.ts` — ships on every page.
|
|
129
|
+
- `src/pages/*.ts` — one file per page, picked up automatically, ships only where you
|
|
130
|
+
add its script tag.
|
|
131
|
+
|
|
132
|
+
## Layout
|
|
133
|
+
|
|
134
|
+
| Path | Contents |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| `src/lib` | Shared helpers — GSAP access, environment checks |
|
|
137
|
+
| `src/anim` | `data-anim` registry and one file per animation |
|
|
138
|
+
| `src/pages` | Per-page entry points |
|
|
139
|
+
| `tests` | Playwright measurement specs (Chromium, one viewport) |
|
|
140
|
+
|
|
141
|
+
## Commands
|
|
142
|
+
|
|
143
|
+
| Command | Does |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `pnpm dev` | Watch, rebuild, serve on :3000 with live reload |
|
|
146
|
+
| `pnpm build` | Minified production build into `dist` |
|
|
147
|
+
| `pnpm check` | TypeScript, no emit |
|
|
148
|
+
| `pnpm lint` | ESLint + Prettier, read-only |
|
|
149
|
+
| `pnpm lint:fix` | ESLint with `--fix` |
|
|
150
|
+
| `pnpm format` | Prettier, writes |
|
|
151
|
+
| `pnpm test` | Playwright measurement specs against `STAGING_URL` |
|
|
152
|
+
| `pnpm test:ui` | The same specs in Playwright's UI runner |
|
|
153
|
+
| `pnpm changeset` | Record a pending change and its version bump |
|
|
154
|
+
| `pnpm changeset version` | Apply pending changesets, write `CHANGELOG.md` |
|
|
155
|
+
| `npm publish` | Upload to npm (passkey in the browser) — see Releasing |
|
|
156
|
+
|
|
157
|
+
`prepublishOnly` chains `check`, `lint` and `build`; it runs on publish, not by hand.
|
|
158
|
+
|
|
159
|
+
The Playwright specs measure the published site, not the local dev server — set
|
|
160
|
+
`STAGING_URL` or they fall back to `https://shopic.webflow.io`.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(()=>{var c=new Map;var i=(e,t=document)=>{let p=t.querySelectorAll("[data-anim]");for(let o of p){let r=o.dataset.anim;if(!r)continue;let n=c.get(r);if(!n){console.warn(`[shopic] No animation registered for data-anim="${r}".`,o);continue}n(o,e)}};var a=()=>{let{gsap:e,ScrollTrigger:t}=window;if(!e)throw new Error("[shopic] GSAP is not on the page. Enable it in Webflow \u2192 Site Settings \u2192 Custom Code \u2192 GSAP.");return t&&e.registerPlugin(t),{gsap:e,ScrollTrigger:t}},s=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.Webflow||(window.Webflow=[]);window.Webflow.push(()=>{let{gsap:e,ScrollTrigger:t}=a();i({gsap:e,ScrollTrigger:t,reducedMotion:s()})});})();
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shopic",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Custom code bundle for the Shopic Webflow site.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"private": false,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "cross-env NODE_ENV=development node ./bin/build.js",
|
|
14
|
+
"build": "cross-env NODE_ENV=production node ./bin/build.js",
|
|
15
|
+
"prepublishOnly": "npm run check && npm run lint && npm run build",
|
|
16
|
+
"lint": "eslint ./src && prettier --check ./src",
|
|
17
|
+
"lint:fix": "eslint ./src --fix",
|
|
18
|
+
"check": "tsc --noEmit",
|
|
19
|
+
"format": "prettier --write ./src",
|
|
20
|
+
"test": "playwright test",
|
|
21
|
+
"test:ui": "playwright test --ui",
|
|
22
|
+
"update": "pnpm update -i -L -r"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@changesets/changelog-git": "^0.2.0",
|
|
26
|
+
"@changesets/cli": "^2.27.12",
|
|
27
|
+
"@eslint/js": "^9.19.0",
|
|
28
|
+
"@finsweet/eslint-config": "^3.0.3",
|
|
29
|
+
"@finsweet/ts-utils": "^0.40.0",
|
|
30
|
+
"@finsweet/tsconfig": "^1.4.2",
|
|
31
|
+
"@playwright/test": "^1.50.1",
|
|
32
|
+
"cross-env": "^7.0.3",
|
|
33
|
+
"esbuild": "^0.24.2",
|
|
34
|
+
"eslint": "^9.19.0",
|
|
35
|
+
"eslint-config-prettier": "^10.0.1",
|
|
36
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
37
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
38
|
+
"gsap": "^3.13.0",
|
|
39
|
+
"prettier": "^3.4.2",
|
|
40
|
+
"typescript": "^5.7.3",
|
|
41
|
+
"typescript-eslint": "^8.23.0"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"pnpm": ">=10"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/wlrx/shopic.git"
|
|
49
|
+
},
|
|
50
|
+
"packageManager": "pnpm@11.5.3+sha512.7ac1c919341c213a34dc0d02afb7143c5c26ac26ee8c4782deea821b8ac64d2134a081fd8941dae6e29bbb48f58dfc2b7fbceeccc07cb2f09d219d342a4969ed"
|
|
51
|
+
}
|