Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BYOC] Productize move of FEAASWrapper and BYOCWrapper to base packages #1605

Merged
merged 19 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8bcc480
don't require D/default export for components in component factory
ambrauer Aug 10, 2023
da4964d
move FEaaSWrapper and BYOCWrapper from nextjs-sxa add-on to base pack…
ambrauer Aug 10, 2023
84c66bc
move @sitecore-feaas/clientside to a peerDependency
ambrauer Aug 10, 2023
0f2bb7e
fix typo
ambrauer Aug 10, 2023
19e1654
add monorepo support for @sitecore-feaas/clientside/react (best we ha…
ambrauer Aug 24, 2023
12c02ac
proper fix for dual package hazard (feaas plugin for webpack config)
ambrauer Aug 29, 2023
4378f06
Update feaas/clientside package usage
illiakovalenko Aug 31, 2023
5813c9a
Applied changes
illiakovalenko Sep 4, 2023
853b9b0
Added unit tests
illiakovalenko Sep 5, 2023
c1266a2
Added unit tests
illiakovalenko Sep 5, 2023
607c62d
Update
illiakovalenko Sep 5, 2023
1d6cb56
Updated @sitecore-feaas/clientside to latest version
illiakovalenko Sep 5, 2023
06bb4b0
Updated yarn lock
illiakovalenko Sep 5, 2023
885d8d8
Updated CHANGELOG
illiakovalenko Sep 5, 2023
a690baa
Merge branch 'dev' of https://github.com/Sitecore/jss into feature/JS…
illiakovalenko Sep 6, 2023
71b5bf8
Updated unit test, skip fallback components when component is implmen…
illiakovalenko Sep 7, 2023
cd3f7af
Merge branch 'dev' of https://github.com/Sitecore/jss into feature/JS…
illiakovalenko Sep 7, 2023
eddafac
Merge branch 'dev' of https://github.com/Sitecore/jss into feature/JS…
illiakovalenko Sep 7, 2023
2db2df9
Merge branch 'dev' of https://github.com/Sitecore/jss into feature/JS…
illiakovalenko Sep 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ Our versioning strategy is as follows:

### 🎉 New Features & Improvements

* `[templates/nextjs-sxa]` `[sitecore-jss-react]` "Bring Your Own Code" (BYOC) feature is introduced. This allows developers and editors more flexibility when developing and working with new components, i.e.:
* `[templates/nextjs-sxa]` `[sitecore-jss-react]` `[sitecore-jss-nextjs]` "Bring Your Own Code" (BYOC) feature is introduced. This allows developers and editors more flexibility when developing and working with new components, i.e.:
* Avoid the jss deploy process for components, and use FEAAS registration instead
* Put components anywhere in the project,
* Use any prop type, without dependence on Layout Service data

Check the BYOC documentation for more info. ([#1568](https://github.com/Sitecore/jss/pull/1568)) ([#1603](https://github.com/Sitecore/jss/pull/1603))
Check the BYOC documentation for more info. ([#1568](https://github.com/Sitecore/jss/pull/1568)) ([#1603](https://github.com/Sitecore/jss/pull/1603))([#1605](https://github.com/Sitecore/jss/pull/1605))
* `[templates/nextjs-sxa]` Scaffolding components for BYOC is added. Use '--byoc' flag at the end of `jss scaffold` command to create a boilerplate component for BYOC ([#1572](https://github.com/Sitecore/jss/pull/1572))
* `[sitecore-jss-nextjs]` Stylesheet loading via page head links for FEAAS and BYOC is implemented. This allows stylesheets to be loaded during SSR and avoid extra calls on client. ([#1587](https://github.com/Sitecore/jss/pull/1587))
* `[templates/nextjs]` Scaffold new components outside of 'src/components' folder by specifying a path with src in it, i.e. `jss scaffold src/new-folder/NewComponent` ([#1572](https://github.com/Sitecore/jss/pull/1572))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"dependencies": {
"@sitecore-feaas/clientside": "^0.3.12",
"bootstrap": "^5.1.3",
"font-awesome": "^4.7.0",
"sass": "^1.52.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@sitecore-feaas/clientside": "^0.3.14",
"@sitecore-jss/sitecore-jss-nextjs": "~21.3.0-canary",
"graphql": "~15.8.0",
"graphql-tag": "^2.12.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { PackageDefinition, ComponentFile } from '@sitecore-jss/sitecore-jss-dev

export interface ComponentBuilderPluginConfig {
watch?: boolean;
packages?: PackageDefinition[];
components?: ComponentFile[];
packages: PackageDefinition[];
components: ComponentFile[];
}

export interface ComponentBuilderPlugin {
Expand Down Expand Up @@ -38,6 +38,8 @@ export interface ComponentBuilderPlugin {

const defaultConfig: ComponentBuilderPluginConfig = {
watch: process.argv.some(arg => arg === '--watch'),
packages: [],
components: [],
};

(Object.values(plugins) as ComponentBuilderPlugin[])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ComponentBuilderPlugin, ComponentBuilderPluginConfig } from '..';

/**
* Provides Sitecore Components (FEaaS) packages configuration
*/
class FEaaSPlugin implements ComponentBuilderPlugin {
order = 1;

exec(config: ComponentBuilderPluginConfig) {
config.packages.push({
name: '@sitecore-jss/sitecore-jss-nextjs',
components: [
{
componentName: 'BYOCWrapper',
art-alexeyenko marked this conversation as resolved.
Show resolved Hide resolved
moduleName: 'BYOCWrapper',
},
{
componentName: 'FEaaSWrapper',
moduleName: 'FEaaSWrapper',
},
],
});

return config;
}
}

export const feaasPlugin = new FEaaSPlugin();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @param {import('next').NextConfig} nextConfig
*/
const feaasPlugin = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
webpack: (config, options) => {
if (options.isServer) {
// Force use of CommonJS on the server for FEAAS SDK since JSS also uses CommonJS entrypoint to FEAAS SDK.
// This prevents issues arising due to FEAAS SDK's dual CommonJS/ES module support on the server (via conditional exports).
// See https://nodejs.org/api/packages.html#dual-package-hazard.
config.externals = [{ '@sitecore-feaas/clientside/react': 'commonjs @sitecore-feaas/clientside/react' }, ...config.externals];
}

// Overload the Webpack config if it was already overloaded
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options);
}

return config;
}
});
};

module.exports = feaasPlugin;
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const path = require('path');
const CWD = process.cwd();

/**
* @param {import('next').NextConfig} nextConfig
*/
Expand All @@ -7,6 +10,12 @@ const monorepoPlugin = (nextConfig = {}) => {
if (options.isServer) {
config.externals = ['react', 'vertx', ...config.externals];
}
// Monorepo support for @sitecore-feaas/clientside/react
config.resolve.alias['@sitecore-feaas/clientside/react'] = path.resolve(
CWD, options.isServer ?
'./node_modules/@sitecore-feaas/clientside/dist/node/react.cjs' :
'./node_modules/@sitecore-feaas/clientside/dist/browser/react.esm.js'
);

// Overload the Webpack config if it was already overloaded
if (typeof nextConfig.webpack === 'function') {
Expand Down
8 changes: 6 additions & 2 deletions packages/sitecore-jss-nextjs/src/ComponentBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type LazyModule = {
/**
* Component is a module or a lazy module
*/
type Component = Module | LazyModule;
type Component = Module | LazyModule | ComponentType;

/**
* Configuration for ComponentBuilder
Expand Down Expand Up @@ -97,7 +97,11 @@ export class ComponentBuilder {
return (component as Module)[exportName];
}

return (component as Module).Default || (component as Module).default || null;
return (
(component as Module).Default ||
(component as Module).default ||
(component as ComponentType)
);
};
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
import {
GetServerSideComponentProps,
GetStaticComponentProps,
FEaaSComponent,
FEaaSComponentProps,
FEaaSWrapper,
FEaaSComponentParams,
fetchFEaaSComponentServerProps,
constants,
} from '@sitecore-jss/sitecore-jss-nextjs';
import React from 'react';
} from '@sitecore-jss/sitecore-jss-react';
import {
GetStaticComponentProps,
GetServerSideComponentProps,
} from '../sharedTypes/component-props';
import { constants } from '@sitecore-jss/sitecore-jss';

export const Default = (props: FEaaSComponentProps): JSX.Element => {
const styles = `component feaas ${props.params?.styles}`.trimEnd();
const id = props.params?.RenderingIdentifier;
return (
<div className={styles} id={id ? id : undefined}>
<div className="component-content">
<FEaaSComponent {...props} />
</div>
</div>
);
};
/**
* This is a repackaged version of the React FEaaSWrapper component with support for
* server rendering in Next.js (using component-level data-fetching feature of JSS).
*/

/**
* Will be called during SSG
* @param {ComponentRendering} rendering
* @param {LayoutServiceData} layoutData
* @param {GetStaticPropsContext} context
* @returns {GetStaticPropsContext} context
*/
export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => {
if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
return null;
}
const params: FEaaSComponentParams = rendering.params || {};
const result = await fetchFEaaSComponentServerProps(params, layoutData.sitecore.context.pageState);
const result = await fetchFEaaSComponentServerProps(
params,
layoutData.sitecore.context.pageState
);
return result;
};

/**
* Will be called during SSR
* @param {ComponentRendering} rendering
* @param {LayoutServiceData} layoutData
* @param {GetStaticPropsContext} context
* @returns {GetStaticPropsContext} context
*/
export const getServerSideProps: GetServerSideComponentProps = async (rendering, layoutData) => {
if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
return null;
}
const params: FEaaSComponentParams = rendering.params || {};
const result = await fetchFEaaSComponentServerProps(params, layoutData.sitecore.context.pageState);
const result = await fetchFEaaSComponentServerProps(
params,
layoutData.sitecore.context.pageState
);
return result;
};

export default FEaaSWrapper;
3 changes: 3 additions & 0 deletions packages/sitecore-jss-nextjs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ export { RichText, RichTextProps } from './components/RichText';
export { Placeholder } from './components/Placeholder';
export { EditingComponentPlaceholder } from './components/EditingComponentPlaceholder';
export { NextImage } from './components/NextImage';
import * as FEaaSWrapper from './components/FEaaSWrapper';
export { FEaaSWrapper };

export { ComponentBuilder, ComponentBuilderConfig } from './ComponentBuilder';

Expand All @@ -175,6 +177,7 @@ export {
BYOCComponent,
BYOCComponentProps,
getFEAASLibraryStylesheetLinks,
BYOCWrapper,
File,
FileField,
RichTextField,
Expand Down
3 changes: 2 additions & 1 deletion packages/sitecore-jss-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"url": "https://github.com/sitecore/jss/issues"
},
"devDependencies": {
"@sitecore-feaas/clientside": "^0.3.14",
"@types/chai": "^4.3.4",
"@types/chai-string": "^1.4.2",
"@types/deep-equal": "^1.0.1",
Expand Down Expand Up @@ -57,11 +58,11 @@
"typescript": "~4.9.3"
},
"peerDependencies": {
"@sitecore-feaas/clientside": "^0.3.14",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"dependencies": {
"@sitecore-feaas/clientside": "^0.3.12",
"@sitecore-jss/sitecore-jss": "21.3.0-canary.51",
"deep-equal": "^2.1.0",
"prop-types": "^15.8.1",
Expand Down
21 changes: 16 additions & 5 deletions packages/sitecore-jss-react/src/components/BYOCComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import * as FEAAS from '@sitecore-feaas/clientside/react';
import { BYOCComponent } from './BYOCComponent';
import { MissingComponent, MissingComponentProps } from './MissingComponent';

describe('BYOCComponent', () => {
it('should render with props when ComponentProps is provided', () => {
const mockProps = {
params: {
ComponentName: 'ExternalComponent',
ComponentName: 'Foo',
ComponentProps: JSON.stringify({ prop1: 'value1' }),
},
};
const Foo = () => <p id="foo-content">Test</p>;
FEAAS.External.registerComponent(Foo, {
name: 'Foo',
properties: {
prop1: {
type: 'string',
},
},
});
const wrapper = mount(<BYOCComponent {...mockProps} />);
const externalComponent = wrapper.find('Se');
expect(externalComponent).to.have.lengthOf(1);
expect(externalComponent.prop('componentName')).to.equal('ExternalComponent');
expect(externalComponent.prop('prop1')).to.equal('value1');
const fooComponent = wrapper.find('feaas-external');
expect(fooComponent).to.have.lengthOf(1);
expect(fooComponent.prop('prop1')).to.equal('value1');
expect(fooComponent.prop('data-external-id')).to.equal('Foo');
expect(fooComponent.find('#foo-content')).to.have.length(1);
});
});

Expand Down
2 changes: 2 additions & 0 deletions packages/sitecore-jss-react/src/components/BYOCComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getDataFromFields } from '../utils';
import { MissingComponent, MissingComponentProps } from './MissingComponent';
import * as FEAAS from '@sitecore-feaas/clientside/react';

export const BYOC_COMPONENT_RENDERING_NAME = 'BYOCComponent';

/**
* Data from rendering params on Sitecore's BYOC rendering
*/
Expand Down
38 changes: 38 additions & 0 deletions packages/sitecore-jss-react/src/components/BYOCWrapper.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { stub } from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { BYOCWrapper } from './BYOCWrapper';
import * as BYOCComponent from './BYOCComponent';

describe('<BYOCWrapper />', () => {
it('should render', () => {
const byocComponentStub = stub(BYOCComponent, 'BYOCComponent').callsFake(() => <p>Foo</p>);
const mockProps = {
params: {
ComponentName: 'xxx',
ComponentProps: JSON.stringify({ prop1: 'value1' }),
RenderingIdentifier: 'foo-id',
styles: 'bar car ',
},
};
const wrapper = mount(<BYOCWrapper {...mockProps} />);

const byocComponent = wrapper.find('BYOCComponent');
expect(byocComponent).to.have.lengthOf(1);
const props = byocComponent.props() as BYOCComponent.BYOCComponentProps;
expect(props.params).to.deep.equal({
ComponentName: 'xxx',
ComponentProps: JSON.stringify({ prop1: 'value1' }),
RenderingIdentifier: 'foo-id',
styles: 'bar car ',
});

const root = wrapper.find('.bar');
expect(root).to.have.lengthOf(1);
expect(root.props().className).to.equal('bar car');
expect(root.props().id).to.equal('foo-id');

byocComponentStub.restore();
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { BYOCComponentProps, BYOCComponent } from '@sitecore-jss/sitecore-jss-nextjs';
import { BYOCComponentProps, BYOCComponent } from './BYOCComponent';
import React from 'react';

export const Default = (props: BYOCComponentProps): JSX.Element => {
export const BYOC_WRAPPER_RENDERING_NAME = 'BYOCWrapper';

export const BYOCWrapper = (props: BYOCComponentProps): JSX.Element => {
const styles = props.params?.styles?.trimEnd();
const id = props.params?.RenderingIdentifier;

Expand Down
Loading