feat: seperate workspaces
Description
This separates out the workspaces to help reduce the clutter created when running npm install.
The /examples directory are not intended to be workspace packages, so the dependencies declared in each example should be isolated to that example and not included when installing dependencies for the packages.
Fix Workflows
- [x] Unit Test Plugin
- [x] E2E Test Packages
- [ ] ~E2E Test Plugin (legacy)~
- [x] Experimental App Router Build & Test
- [x] Lint Packages
- [x] Test Packages
- [x] Lint Plugin
- [x] Unit Test Plugin
- [x] NextJS Bundle Analysis
Related Issue(s):
- #1786
- #1929
Testing
I symlinked my local copy of acf.wpgraphql.com to this local copy of @faustwp/blocks, then ran my site and it was able to build.
In addition to the package.json changes in this PR, we still need to symlink react from the package we're npm linking in our project.
So, in acf.wpgraphql.com I did npm link @faustwp/blocks and then within faustjs/packages/blocks I had to npm link /path/to/acf.wpgraphql.com/node_modules/react for local development to work without the multiple versions of react error
see: https://legacy.reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
Screenshots
Here you can see that in my acf.wpgraphql.com project I have used npm link @faustwp/blocks:
npm list | grep faust
Then in faustjs/packages/blocks I have react linked back to my acf.wpgraphql.com project via running: npm link /Users/jason.bahl/Sites/libs/acf.wpgraphql.com/node_modules/react
npm list | grep react
Now I can successfully run npm run dev within acf.wpgraphql.com and it builds and runs without any errors.
Before
Before this PR, we cannot npm link react back to the acf.wpgraphql.com project because of conflicts caused by the examples dependencies and the packages dependencies..
After
After this PR, following the npm link steps above, we are able to successfully link react from packages/blocks back to the project (acf.wpgraphql.com in this case) run the project locally without issue. We can also do things like add console.log statements to the components/WordPressBlockViewer.tsx component and see it output with "fast refresh"
Documentation Changes
- [ ]
@todoUpdate LOCAL_DEVELOPMENT.md
⚠️ No Changeset found
Latest commit: 24f96acada6c09f1d493cf57a1c3aee932b116a8
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "@faustjs/core" specified in the `linked` option does not match any package in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustjs/next" specified in the `linked` option does not match any package in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustjs/react" specified in the `linked` option does not match any package in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustjs/next-headless-getting-started" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustwp/getting-started-example" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustwp/app-router-example" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@faustwp/block-support-example" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
@jasonbahl a few ci/cd errors there before we can merge.
Coverage report for packages/faustwp-core
❌ An unexpected error occurred. For more details, check console
Error: The process '/opt/hostedtoolcache/node/20.17.0/x64/bin/npm' failed with exit code 1
St.:grey_question: |
Category | Percentage | Covered / Total |
|---|---|---|---|
| 🟢 | Statements | 84.98% | 1041/1225 |
| 🟡 | Branches | 66.77% (+0.07% 🔼) |
651/975 |
| 🟢 | Functions | 85.06% | 148/174 |
| 🟢 | Lines | 84.61% (-0.08% 🔻) |
1006/1189 |
Test suite run failed
Failed tests: 12/148. Failed suites: 3/26.
● renders a default list of nodes in the primary section if seedNode is not provided
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `renders a default list of nodes in the primary section if seedNode is not provided 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"WordPress",
"",
"GraphiQL IDE",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:107:3)
● renders an Edit Post Node, in the primary section if seedNode is provided
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `renders an Edit Post Node, in the primary section if seedNode is provided 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"WordPress",
"Edit Post",
"GraphiQL IDE",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:133:3)
● renders an Account Node in the secondary section
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `renders an Account Node in the secondary section 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"Howdy, Edit ProfileLog Out",
"",
"Edit Profile",
"Log Out",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:157:3)
● renders an Edit Post Node if seedNode is not provided and is preview
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `renders an Edit Post Node if seedNode is not provided and is preview 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"WordPress",
"",
"GraphiQL IDE",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:180:3)
● does not render an Edit Post Node if there is no seedNode and it is not a preview
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `does not render an Edit Post Node if there is no seedNode and it is not a preview 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"WordPress",
"",
"GraphiQL IDE",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:202:3)
● Uses `toolbarNodes` hook to add nodes
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `Uses \`toolbarNodes\` hook to add nodes 1`
- Snapshot - 1
+ Received + 1
- [
+ Array [
"WordPress",
"Edit Post",
"GraphiQL IDE",
"Test Node",
]
279 | expect(items.length).toBe(expectedLen);
280 | const toolBarNames = items.map((item) => item.textContent);
> 281 | expect(toolBarNames).toMatchInlineSnapshot(expectedContent);
| ^
282 | }
283 |
at testToolBarNode (tests/components/Toolbar/Toolbar.test.tsx:281:24)
at Object.<anonymous> (tests/components/Toolbar/Toolbar.test.tsx:234:3)
● withFaust › it applies a default redirects config
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `withFaust it applies a default redirects config 1`
- Snapshot - 7
+ Received + 7
@@ -1,22 +1,22 @@
- [
- {
+ Array [
+ Object {
"destination": "/preview",
- "has": [
- {
+ "has": Array [
+ Object {
"key": "preview",
"type": "query",
"value": "true",
},
],
"permanent": false,
"source": "/((?!preview).*)",
},
- {
+ Object {
"destination": "/preview",
- "has": [
- {
+ "has": Array [
+ Object {
"key": "preview",
"type": "query",
"value": "true",
},
],
29 | );
30 | const redirects = await finalConfig.redirects!();
> 31 | expect(redirects).toMatchInlineSnapshot(`
| ^
32 | [
33 | {
34 | "destination": "/preview",
at Object.<anonymous> (tests/config/withFaust.test.ts:31:23)
● withFaust › it allows a custom preview destination
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: `withFaust it allows a custom preview destination 1`
- Snapshot - 10
+ Received + 10
@@ -1,34 +1,34 @@
- [
- {
+ Array [
+ Object {
"destination": "/demo",
- "has": [
- {
+ "has": Array [
+ Object {
"key": "preview",
"type": "query",
"value": "true",
},
],
"permanent": false,
"source": "/((?!demo).*)",
},
- {
+ Object {
"destination": "/preview",
- "has": [
- {
+ "has": Array [
+ Object {
"key": "preview",
"type": "query",
"value": "true",
},
],
"permanent": false,
"source": "/((?!preview).*)",
},
- {
+ Object {
"destination": "/preview",
- "has": [
- {
+ "has": Array [
+ Object {
"key": "preview",
"type": "query",
"value": "true",
},
],
64 | });
65 | const redirects = await finalConfig.redirects!();
> 66 | expect(redirects).toMatchInlineSnapshot(`
| ^
67 | [
68 | {
69 | "destination": "/demo",
at Object.<anonymous> (tests/config/withFaust.test.ts:66:23)
● createSitemapIndex() › returns a sitemap index with no sitemaps
expect(received).toMatchSnapshot()
Snapshot name: `createSitemapIndex() returns a sitemap index with no sitemaps 1`
- Snapshot - 0
+ Received + 0
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
</sitemapindex>
9 |
10 | expect(res.headers.get('Content-Type')).toBe('application/xml');
> 11 | expect(xml).toMatchSnapshot();
| ^
12 | });
13 |
14 | it('returns a sitemap index with specified sitemaps', async () => {
at Object.<anonymous> (tests/server/sitemaps/sitemapUtils.test.ts:11:17)
● createSitemapIndex() › returns a sitemap index with specified sitemaps
expect(received).toMatchSnapshot()
Snapshot name: `createSitemapIndex() returns a sitemap index with specified sitemaps 1`
- Snapshot - 0
+ Received + 0
@@ -6,5 +6,5 @@
</sitemap><sitemap>
<loc>http://localhost:3000/page-sitemap.xml</loc>
</sitemap>
</sitemapindex>
28 |
29 | expect(res.headers.get('Content-Type')).toBe('application/xml');
> 30 | expect(xml).toMatchSnapshot();
| ^
31 | });
32 | });
33 |
at Object.<anonymous> (tests/server/sitemaps/sitemapUtils.test.ts:30:17)
● createSitemap() › returns a sitemap with no links
expect(received).toMatchSnapshot()
Snapshot name: `createSitemap() returns a sitemap with no links 1`
- Snapshot - 0
+ Received + 0
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
</urlset>
40 |
41 | expect(res.headers.get('Content-Type')).toBe('application/xml');
> 42 | expect(xml).toMatchSnapshot();
| ^
43 | });
44 |
45 | it('returns a sitemap with specified urls', async () => {
at Object.<anonymous> (tests/server/sitemaps/sitemapUtils.test.ts:42:17)
● createSitemap() › returns a sitemap with specified urls
expect(received).toMatchSnapshot()
Snapshot name: `createSitemap() returns a sitemap with specified urls 1`
- Snapshot - 0
+ Received + 0
@@ -25,5 +25,5 @@
</url>
</urlset>
72 |
73 | expect(res.headers.get('Content-Type')).toBe('application/xml');
> 74 | expect(xml).toMatchSnapshot();
| ^
75 | });
76 | });
77 |
at Object.<anonymous> (tests/server/sitemaps/sitemapUtils.test.ts:74:17)
Report generated by 🧪jest coverage report action from 4ec11be7777a4a129c71c1257005d914bc729575
📦 Next.js Bundle Analysis for @faustwp/getting-started-example
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
250.06 KB (🟢 -475 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
Four Pages Changed Size
The following pages changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load | % of Budget (350 KB) |
|---|---|---|---|
/ |
289 B |
250.34 KB | 71.53% (🟢 -0.01%) |
/_error |
193 B |
250.24 KB | 71.50% (+/- <0.01%) |
/example |
852 B |
250.89 KB | 71.68% (+/- <0.01%) |
/preview |
280 B |
250.33 KB | 71.52% (+/- <0.01%) |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/-