Skip to content

Commit

Permalink
Merge branch 'main' into fd-fix-public-assets
Browse files Browse the repository at this point in the history
  • Loading branch information
frandiox authored Nov 11, 2021
2 parents 996b71f + ffb98a6 commit 474a63a
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 18 deletions.
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ assignees: ''
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behaviour:

- Provide a link to a [StackBlitz sandbox](https://hydrogen.new) which reproduces the issue
- OR: provide a link to a repository that reproduces the issue

If you cannot do one of the above, list steps to reproduce the behaviour below:

1. Go to '...'
2. Click on '....'
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/publish_stackblitz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Publish to Stackblitz

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
name: Publish latest release to Stackblitz
steps:
- name: Checkout the code
uses: actions/checkout@v2
- name: Rename gitignore
run: |
mv packages/dev/_gitignore packages/dev/.gitignore
- name: Push to stackblitz branch
uses: EndBug/[email protected]
with:
push: 'origin stackblitz --force'

10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
![Hydrogen logo](/docs/images/HydrogenLogo.png)
<p align="center">
<a href="https://hydrogen.shopify.dev">
<img src="./docs/images/HydrogenLogo.png"/>
</a>
</p>

<div align="center">

📚 [Docs](https://shopify.dev/custom-storefronts/hydrogen) | 🗣 [Discord](https://discord.gg/Hefq6w5c5d) | 💬 [Discussions](https://github.com/Shopify/hydrogen/discussions) | 📝 [Changelog](./packages/hydrogen/CHANGELOG.md)

</div>

Hydrogen is a **React-based framework** for building dynamic, **Shopify-powered** custom storefronts.

Spin up a Hydrogen app in your browser with our [playground](https://hydrogen.new/) or set up your local environment with the instructions below ⬇️
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"scripts": {
"dev-lib": "yarn workspace @shopify/hydrogen dev",
"dev-server": "VITE_INSPECT=1 yarn workspace dev dev",
"dev-server": "LOCAL_DEV=true VITE_INSPECT=1 yarn workspace dev dev",
"build": "run-s build-lib build-dev build-cli",
"build-lib": "yarn workspace @shopify/hydrogen build",
"build-cli": "yarn workspace @shopify/hydrogen-cli build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const {copy} = require('./utils');

const devPath = path.resolve(__dirname, '..', '..', 'dev');
const templatePath = path.resolve(__dirname, '..', './template-hydrogen');
const skipFiles = ['node_modules', 'dist'];
const skipFiles = ['node_modules', 'dist', '.stackblitzrc'];

// Remove the symlink and replace it with a folder
fs.unlinkSync(templatePath);
Expand Down
4 changes: 4 additions & 0 deletions packages/dev/.stackblitzrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"installDependencies": true,
"startCommand": "npm run dev"
}
2 changes: 1 addition & 1 deletion packages/dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"private": true,
"scripts": {
"dev": "LOCAL_DEV=true vite",
"dev": "vite",
"lint": "npm-run-all lint:*",
"lint:js": "eslint --no-error-on-unmatched-pattern --ext .js,.ts,.jsx,.tsx src",
"lint:css": "stylelint ./src/**/*.{css,sass,scss}",
Expand Down
3 changes: 3 additions & 0 deletions packages/hydrogen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## Unreleased

- fix: let Vite handle public assets in development
- fix: new lines in hydration request break JSON.parse
- fix(#201): normalize POSIX separators to support windows
- fix: scroll to top on app first load

## 0.6.3 - 2021-11-10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import {useServerState} from '../useServerState';
* server state, which in turn fetches the correct server component.
*/
export function ServerStateRouter() {
const {setServerState, pending} = useServerState() as ServerStateContextValue;
const {setServerState, pending, serverState} =
useServerState() as ServerStateContextValue;
const [isNavigating, setIsNavigating] = useState(false);
const location = useLocation();

useEffect(() => {
setIsNavigating(true);
setServerState('pathname', location.pathname);
if (serverState.pathname !== location.pathname) {
setIsNavigating(true);
setServerState('pathname', location.pathname);
}
}, [location.pathname, setServerState]);

useEffect(() => {
Expand Down
5 changes: 4 additions & 1 deletion packages/hydrogen/src/framework/Hydration/Cache.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ function createManifestFromWirePayload(payload: string): WireManifest {
return payload.split('\n').reduce((memo, row) => {
const [key, ...values] = row.split(':');

memo[key] = JSON.parse(values.join(':'));
if (key) {
memo[key] = JSON.parse(values.join(':'));
}

return memo;
}, {} as Record<string, any>) as WireManifest;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ it('handles DOM elements', async () => {
expect(screen.getByText('hello')).toBeInTheDocument();
});

it('ignores new lines', async () => {
const tuples = [['$', 'div', null, {children: 'hello'}]];
const payload = `\nJ0:${JSON.stringify(tuples)}\n`;

render(await convertHydrationResponseToReactComponents(payload));

expect(screen.getByText('hello')).toBeInTheDocument();
});

it('handles DOM elements with arrays of children', async () => {
const tuples = [
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {generateWireSyntaxFromRenderedHtml} from '../wire.server';

it('renders normal html elements', () => {
const input = `<div class="foo"><p id="bar">Hello!</p></div>`;
const output = `\nJ0:["$","div",null,{"className":"foo","children":["$","p",null,{"id":"bar","children":"Hello!"}]}]`;
const output = `J0:["$","div",null,{"className":"foo","children":["$","p",null,{"id":"bar","children":"Hello!"}]}]`;

expect(generateWireSyntaxFromRenderedHtml(input)).toBe(output);
});
Expand Down Expand Up @@ -98,7 +98,7 @@ J0:["$","div",null,{"className":"foo","children":["\\n ",["$","@1",null,{"sid
it('renders Client Components with nested props that have multiple children', () => {
const input = `<div class="foo"><p>Bar</p><div>Baz</div></div>`;

const output = `\nJ0:["$","div",null,{"className":"foo","children":[["$","p",null,{"key":0,"children":"Bar"}],["$","div",null,{"key":1,"children":"Baz"}]]}]`;
const output = `J0:["$","div",null,{"className":"foo","children":[["$","p",null,{"key":0,"children":"Bar"}],["$","div",null,{"key":1,"children":"Baz"}]]}]`;

expect(generateWireSyntaxFromRenderedHtml(input)).toBe(output);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/hydrogen/src/framework/Hydration/wire.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function generateWireSyntaxFromRenderedHtml(html: string) {
return `M${idx + 1}:${JSON.stringify(component)}`;
})
.join('\n') + `\nJ0:${JSON.stringify(wireModel)}`
);
).trim();
}

function isDomNode(item: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`transforms client-imports 1`] = `
"// Transform relative paths to absolute in order
// to match component IDs from ClientMarker.
function normalizeComponentPaths(
componentObject: Record<string, undefined | (() => any)>,
prefix: string
) {
return Object.entries(componentObject).reduce((acc, [key, value]) => {
acc[prefix + key.replace(/\\\\.\\\\.\\\\//gm, '')] = value;
return acc;
}, {} as typeof componentObject);
}
// These strings are replaced in a plugin with real globs
// and paths that depend on the user project structure.
const allClientComponents = {
...normalizeComponentPaths(
// @ts-ignore
import.meta.glob('../../components/**/*.client.js'),
\`@shopify/\`
),
...normalizeComponentPaths(
// @ts-ignore
import.meta.glob('../../../src/**/*.client.[jt]sx'),
\`./\`
),
};
export default function importClientComponent(moduleId: string) {
const modImport = allClientComponents[moduleId];
if (!modImport) {
throw new Error(\`Could not find client component \${moduleId}\`);
}
return modImport();
}
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import middleware from '../vite-plugin-react-server-components-shim';
import fs from 'fs';
import path from 'path';
import {resolve} from '../resolver';

jest.mock('../resolver');

(resolve as any).mockImplementation(() => '@shopify/hydrogen');

let m: any;

beforeEach(() => {
m = middleware();
m.configResolved({
root: '.',
});
});

it('only transforms client-imports', function () {
expect(m.transform('', '')).toBe(undefined);
});

it('transforms client-imports', function () {
const code = fs.readFileSync(
path.resolve(__dirname, '../../Hydration/client-imports.ts'),
'utf8'
);
const result = m.transform(code, '/Hydration/client-imports');

expect(result).toMatchSnapshot();
});

it('throws an error when non-Server components load Server components', async function () {
await expect(m.resolveId('.server.tsx', '.client.tsx')).rejects.toThrow();

await expect(m.resolveId('.server.jsx', '.client.jsx')).rejects.toThrow();
});

it('passes when server components import client components', async function () {
m.resolveId('.client.tsx', '.server.tsx');
m.resolveId('.client.jsx', '.server.jsx');
});

it('throws an error when client components load hydrogen from the server-only entrypoint', async function () {
await expect(
m.resolveId('@shopify/hydrogen', '.client.tsx')
).rejects.toThrow();

await expect(
m.resolveId('@shopify/hydrogen', '.client.jsx')
).rejects.toThrow();
});
3 changes: 3 additions & 0 deletions packages/hydrogen/src/framework/plugins/resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function resolve(path: string) {
return require.resolve(path);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type {Plugin, ResolvedConfig} from 'vite';
import {normalizePath} from 'vite';
import path from 'path';
import {proxyClientComponent} from '../server-components';
import {resolve} from './resolver';

export default () => {
let config: ResolvedConfig;
Expand Down Expand Up @@ -74,10 +76,12 @@ export default () => {
*/
if (id.includes('/Hydration/client-imports')) {
// eslint-disable-next-line node/no-missing-require
const hydrogenPath = path.dirname(require.resolve('@shopify/hydrogen'));
const hydrogenPath = path.dirname(resolve('@shopify/hydrogen'));
const importerPath = path.join(hydrogenPath, 'framework', 'Hydration');

const importerToRootPath = path.relative(importerPath, config.root);
const importerToRootPath = normalizePath(
path.relative(importerPath, config.root)
);
const [importerToRootNested] =
importerToRootPath.match(/(\.\.\/)+(\.\.)?/) || [];
const userPrefix = path.normalize(
Expand All @@ -100,10 +104,10 @@ export default () => {
);

return code
.replace('__USER_COMPONENTS_PREFIX__', userPrefix)
.replace('__USER_COMPONENTS_GLOB__', userGlob)
.replace('__LIB_COMPONENTS_PREFIX__', libPrefix)
.replace('__LIB_COMPONENTS_GLOB__', libGlob);
.replace('__USER_COMPONENTS_PREFIX__', normalizePath(userPrefix))
.replace('__USER_COMPONENTS_GLOB__', normalizePath(userGlob))
.replace('__LIB_COMPONENTS_PREFIX__', normalizePath(libPrefix))
.replace('__LIB_COMPONENTS_GLOB__', normalizePath(libGlob));
}
},
} as Plugin;
Expand Down

0 comments on commit 474a63a

Please sign in to comment.