<[a-zA-Z]*-[a-zA-Z](.*)>(.*)<\/[a-zA-Z]*-[a-zA-Z](.*)><\/p>/g;
diff --git a/packages/cli/test/cases/serve.config.static-router/serve.config.static-router.spec.js b/packages/cli/test/cases/serve.config.static-router/serve.config.static-router.spec.js
index 6fab318ea..0aa04c416 100644
--- a/packages/cli/test/cases/serve.config.static-router/serve.config.static-router.spec.js
+++ b/packages/cli/test/cases/serve.config.static-router/serve.config.static-router.spec.js
@@ -22,8 +22,10 @@
* index.md
*/
import chai from 'chai';
+import fs from 'fs/promises';
import path from 'path';
import { getSetupFiles, getDependencyFiles, getOutputTeardownFiles } from '../../../../../test/utils.js';
+import { normalizePathnameForWindows } from '../../../src/lib/resource-utils.js';
import request from 'request';
import { runSmokeTest } from '../../../../../test/smoke-test.js';
import { Runner } from 'gallinago';
@@ -46,20 +48,79 @@ describe('Serve Greenwood With: ', function() {
});
describe(LABEL, function() {
+ const workaroundFiles = [
+ 'hashing-utils',
+ 'node-modules-utils',
+ 'resource-utils',
+ 'templating-utils'
+ ];
before(async function() {
const greenwoodRouterLibs = await getDependencyFiles(
`${process.cwd()}/packages/cli/src/lib/router.js`,
`${outputPath}/node_modules/@greenwood/cli/src/lib`
);
+ /*
+ * there is an odd issue seemingly due to needed lib/router.js tha causes tests to think files are CommonJS
+ * ```
+ * file:///Users/owenbuckley/Workspace/project-evergreen/repos/greenwood/packages/cli/test/cases/serve.config.static-router/public/artists.js:3
+ * import { getAppTemplate, getPageTemplate, getUserScripts } from '@greenwood/cli/src/lib/templating-utils.js';
+ * ^^^^^^^^^^^^^^
+ * SyntaxError: Named export 'getAppTemplate' not found. The requested module '@greenwood/cli/src/lib/templating-utils.js'
+ * is a CommonJS module, which may not support all module.exports as named exports.
+ * CommonJS modules can always be imported via the default export, for example using:
+ * import pkg from '@greenwood/cli/src/lib/templating-utils.js';
+ * const { getAppTemplate, getPageTemplate, getUserScripts } = pkg;
+ * ```
+ *
+ * however no other tests have this issue. so as terrible hack we need to
+ * - copy all lib files
+ * - rename them to end in .mjs
+ * - update references to these files in other imports
+ *
+ * (unfortunately, trying to just add a package.json with type="module" did not seem to work :/)
+ */
+ const greenwoodTemplatingLibs = await getDependencyFiles(
+ `${process.cwd()}/packages/cli/src/lib/*`,
+ `${outputPath}/node_modules/@greenwood/cli/src/lib`
+ );
+ const greenwoodTemplates = await getDependencyFiles(
+ `${process.cwd()}/packages/cli/src/templates/*`,
+ `${outputPath}/node_modules/@greenwood/cli/src/templates`
+ );
await runner.setup(outputPath, [
...getSetupFiles(outputPath),
- ...greenwoodRouterLibs
+ ...greenwoodRouterLibs,
+ ...greenwoodTemplatingLibs,
+ ...greenwoodTemplates
]);
+
+ for (const f of workaroundFiles) {
+ const pathname = normalizePathnameForWindows(new URL(`./node_modules/@greenwood/cli/src/lib/${f}.js`, import.meta.url));
+ let contents = await fs.readFile(pathname, 'utf-8');
+
+ workaroundFiles.forEach((wf) => {
+ contents = contents.replace(`${wf}.js`, `${wf}.mjs`);
+ });
+
+ await fs.writeFile(pathname.replace('.js', '.mjs'), contents);
+ }
+
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
- setTimeout(() => {
+ setTimeout(async () => {
+ // template out artists.js to use .mjs too
+ const pathname = normalizePathnameForWindows(new URL('./public/artists.js', import.meta.url));
+ let ssrPageContents = await fs.readFile(pathname, 'utf-8');
+
+ for (const f of workaroundFiles) {
+ ssrPageContents = ssrPageContents.replace(`${f}.js`, `${f}.mjs`);
+ }
+
+ await fs.writeFile(pathname, ssrPageContents);
+
resolve();
}, 10000);
diff --git a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js
index da11977ed..23cd8b303 100644
--- a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js
+++ b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js
@@ -26,7 +26,6 @@ import { fileURLToPath, URL } from 'url';
const expect = chai.expect;
-// TODO why does this test keep stalling out and not closing the command?
describe('Serve Greenwood With: ', function() {
const LABEL = 'API Routes';
const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
@@ -45,6 +44,7 @@ describe('Serve Greenwood With: ', function() {
before(async function() {
await runner.setup(outputPath, getSetupFiles(outputPath));
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js b/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js
new file mode 100644
index 000000000..a7d8a9cb1
--- /dev/null
+++ b/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js
@@ -0,0 +1,52 @@
+/*
+ * Use Case
+ * Run Greenwood serve command without having already run greenwood build.
+ *
+ * User Result
+ * Should throw an error.
+ *
+ * User Command
+ * greenwood serve
+ *
+ * User Config
+ * N / A
+ *
+ * User Workspace
+ * Greenwood default
+ */
+import chai from 'chai';
+import path from 'path';
+import { getOutputTeardownFiles } from '../../../../../test/utils.js';
+import { Runner } from 'gallinago';
+import { fileURLToPath } from 'url';
+
+const expect = chai.expect;
+
+describe('Serve Greenwood With: ', function() {
+ const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
+ const outputPath = fileURLToPath(new URL('.', import.meta.url));
+ let runner;
+
+ before(async function() {
+ this.context = {
+ publicDir: path.join(outputPath, 'public')
+ };
+ runner = new Runner();
+ });
+
+ describe('Running the serve command without running the build command first', function() {
+ it('should throw an error that no build output was detected', async function() {
+ try {
+ await runner.setup(outputPath);
+ await runner.runCommand(cliPath, 'serve');
+ } catch (err) {
+ expect(err).to.contain('No build output detected. Make sure you have run greenwood build');
+ }
+ });
+ });
+
+ after(function() {
+ runner.teardown(getOutputTeardownFiles(outputPath));
+ });
+
+});
\ No newline at end of file
diff --git a/packages/cli/test/cases/serve.default.ssr-prerender/serve.default.ssr-prerender.spec.js b/packages/cli/test/cases/serve.default.ssr-prerender/serve.default.ssr-prerender.spec.js
index b589784cc..bc9e55c3b 100644
--- a/packages/cli/test/cases/serve.default.ssr-prerender/serve.default.ssr-prerender.spec.js
+++ b/packages/cli/test/cases/serve.default.ssr-prerender/serve.default.ssr-prerender.spec.js
@@ -52,6 +52,7 @@ describe('Serve Greenwood With: ', function() {
before(async function() {
await runner.setup(outputPath, getSetupFiles(outputPath));
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/cli/test/cases/serve.default.ssr-static-export/serve.default.ssr-static-export.spec.js b/packages/cli/test/cases/serve.default.ssr-static-export/serve.default.ssr-static-export.spec.js
index a05b8400f..72f1003dc 100644
--- a/packages/cli/test/cases/serve.default.ssr-static-export/serve.default.ssr-static-export.spec.js
+++ b/packages/cli/test/cases/serve.default.ssr-static-export/serve.default.ssr-static-export.spec.js
@@ -126,11 +126,11 @@ describe('Serve Greenwood With: ', function() {
...litReactiveElementDecorators,
...litReactiveElementPackageJson
]);
- await runner.runCommand(cliPath, 'build');
});
before(async function() {
await runner.setup(outputPath, getSetupFiles(outputPath));
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/cli/test/cases/serve.default.ssr/serve.default.ssr.spec.js b/packages/cli/test/cases/serve.default.ssr/serve.default.ssr.spec.js
index 2863f7935..feb66af61 100644
--- a/packages/cli/test/cases/serve.default.ssr/serve.default.ssr.spec.js
+++ b/packages/cli/test/cases/serve.default.ssr/serve.default.ssr.spec.js
@@ -32,7 +32,7 @@ import { getSetupFiles, getOutputTeardownFiles } from '../../../../../test/utils
import request from 'request';
import { runSmokeTest } from '../../../../../test/smoke-test.js';
import { Runner } from 'gallinago';
-import { fileURLToPath, URL } from 'url';
+import { fileURLToPath } from 'url';
const expect = chai.expect;
@@ -55,6 +55,7 @@ describe('Serve Greenwood With: ', function() {
before(async function() {
await runner.setup(outputPath, getSetupFiles(outputPath));
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/cli/test/cases/serve.default/serve.default.spec.js b/packages/cli/test/cases/serve.default/serve.default.spec.js
index c973ea5ce..f2a15e555 100644
--- a/packages/cli/test/cases/serve.default/serve.default.spec.js
+++ b/packages/cli/test/cases/serve.default/serve.default.spec.js
@@ -60,6 +60,7 @@ describe('Serve Greenwood With: ', function() {
before(async function() {
await runner.setup(outputPath, getSetupFiles(outputPath));
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/cli/test/cases/serve.spa/serve.spa.spec.js b/packages/cli/test/cases/serve.spa/serve.spa.spec.js
index 64db569c0..c472bda2f 100644
--- a/packages/cli/test/cases/serve.spa/serve.spa.spec.js
+++ b/packages/cli/test/cases/serve.spa/serve.spa.spec.js
@@ -56,6 +56,7 @@ describe('Serve Greenwood With: ', function() {
before(async function() {
await runner.setup(outputPath);
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/plugin-import-jsx/package.json b/packages/plugin-import-jsx/package.json
index d77a81e4b..a6129c4ce 100644
--- a/packages/plugin-import-jsx/package.json
+++ b/packages/plugin-import-jsx/package.json
@@ -25,7 +25,7 @@
"@greenwood/cli": "^0.28.0-alpha.4"
},
"dependencies": {
- "wc-compiler": "~0.7.0"
+ "wc-compiler": "~0.8.0"
},
"devDependencies": {
"@greenwood/cli": "^0.28.0-alpha.4"
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/artists.json b/packages/plugin-renderer-lit/test/cases/serve.default/artists.json
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/artists.json
rename to packages/plugin-renderer-lit/test/cases/serve.default/artists.json
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/greenwood.config.js b/packages/plugin-renderer-lit/test/cases/serve.default/greenwood.config.js
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/greenwood.config.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/greenwood.config.js
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/package.json b/packages/plugin-renderer-lit/test/cases/serve.default/package.json
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/package.json
rename to packages/plugin-renderer-lit/test/cases/serve.default/package.json
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/build.default.spec.js b/packages/plugin-renderer-lit/test/cases/serve.default/serve.default.spec.js
similarity index 98%
rename from packages/plugin-renderer-lit/test/cases/build.default/build.default.spec.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/serve.default.spec.js
index a31503280..95b7576a2 100644
--- a/packages/plugin-renderer-lit/test/cases/build.default/build.default.spec.js
+++ b/packages/plugin-renderer-lit/test/cases/serve.default/serve.default.spec.js
@@ -1,6 +1,6 @@
/*
* Use Case
- * Run Greenwood with an SSR route.
+ * Run Greenwood server with an SSR route built using Lit SSR.
*
* User Result
* Should generate a Greenwood build for hosting a server rendered application.
@@ -34,7 +34,7 @@ import { fileURLToPath, URL } from 'url';
const expect = chai.expect;
-describe('Build Greenwood With: ', function() {
+describe('Serve Greenwood With: ', function() {
const LABEL = 'Custom Lit Renderer for SSR';
const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
const outputPath = fileURLToPath(new URL('.', import.meta.url));
@@ -127,6 +127,7 @@ describe('Build Greenwood With: ', function() {
...litReactiveElementDecorators,
...litReactiveElementPackageJson
]);
+ await runner.runCommand(cliPath, 'build');
return new Promise(async (resolve) => {
setTimeout(() => {
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/src/components/footer.js b/packages/plugin-renderer-lit/test/cases/serve.default/src/components/footer.js
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/src/components/footer.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/src/components/footer.js
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/src/components/greeting.js b/packages/plugin-renderer-lit/test/cases/serve.default/src/components/greeting.js
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/src/components/greeting.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/src/components/greeting.js
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/src/pages/artists.js b/packages/plugin-renderer-lit/test/cases/serve.default/src/pages/artists.js
similarity index 92%
rename from packages/plugin-renderer-lit/test/cases/build.default/src/pages/artists.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/src/pages/artists.js
index 5e2e8ab04..2bdf8c57f 100644
--- a/packages/plugin-renderer-lit/test/cases/build.default/src/pages/artists.js
+++ b/packages/plugin-renderer-lit/test/cases/serve.default/src/pages/artists.js
@@ -1,4 +1,4 @@
-import fs from 'fs/promises';
+import fs from 'fs';
import { html } from 'lit';
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
import '../components/greeting.js';
@@ -30,7 +30,7 @@ async function getTemplate(compilation, route) {
}
async function getBody() {
- const artists = JSON.parse(await fs.readFile(new URL('../../artists.json', import.meta.url), 'utf-8'));
+ const artists = JSON.parse(await fs.promises.readFile(new URL('../../artists.json', import.meta.url), 'utf-8'));
return html`
Lit SSR response
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/src/pages/users.js b/packages/plugin-renderer-lit/test/cases/serve.default/src/pages/users.js
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/src/pages/users.js
rename to packages/plugin-renderer-lit/test/cases/serve.default/src/pages/users.js
diff --git a/packages/plugin-renderer-lit/test/cases/build.default/src/templates/app.html b/packages/plugin-renderer-lit/test/cases/serve.default/src/templates/app.html
similarity index 100%
rename from packages/plugin-renderer-lit/test/cases/build.default/src/templates/app.html
rename to packages/plugin-renderer-lit/test/cases/serve.default/src/templates/app.html
diff --git a/www/pages/docs/index.md b/www/pages/docs/index.md
index 24101b361..9967f730a 100644
--- a/www/pages/docs/index.md
+++ b/www/pages/docs/index.md
@@ -30,7 +30,9 @@ $ npx @greenwood/cli@latest
With Greenwood installed, you can run its CLI to generate your site. The principal commands available are:
- `greenwood develop`: Starts a local development server for your project.
- `greenwood build`: Generates a production build of your project for just static assets.
-- `greenwood serve`: Generates a production build of your project and runs it on a NodeJS based web server, for both static and server renderer pages.
+- `greenwood serve`: Starts a server to host the output of the Greenwood build command with NodeJS. For convenience on your host, this can be achieved with `npx @greenwood/cli serve`.
+ - For SSG, you only need the _public/_ output directory.
+ - For SSR, you need the _public/_ output directory and the project's _greenwood.config.js_ file (if applicable).
- `greenwood eject`: Ejects CLI configurations (Just Rollup right now) to your working directory for more advanced customization. [YMMV](https://www.howtogeek.com/693183/what-does-ymmv-mean-and-how-do-you-use-it/).
You can define npm scripts in _package.json_ like so to automate your workflows. You also need to define a `type` field with the value of `module`:
@@ -42,7 +44,6 @@ You can define npm scripts in _package.json_ like so to automate your workflows.
"start": "greenwood develop",
"serve": "greenwood serve"
}
-
}
```
@@ -57,11 +58,13 @@ $ yarn start
$ npm run build
$ yarn build
-# generate a static build and preview it locally
+# serve a static build
$ npm run serve
$ yarn serve
```
+> _Note: You must have run `greenwood build` before running `greenwood serve`. Except for Context plugins, plugins are generally not available with `greenwood serve` as your application is built ahead of time._
+
### Sections
To continue learning more about Greenwood, please feel free to browse the other sections of our documentation.
diff --git a/yarn.lock b/yarn.lock
index f23a3e356..2954f634f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2508,6 +2508,14 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
+"@rollup/pluginutils@^4.1.0":
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
+ integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==
+ dependencies:
+ estree-walker "^2.0.1"
+ picomatch "^2.2.2"
+
"@rollup/stream@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@rollup/stream/-/stream-2.0.0.tgz#2ada818c2d042e37f63119d7bf8bbfc71792f641"
@@ -2886,6 +2894,15 @@
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
+"@web/rollup-plugin-import-meta-assets@^1.0.0":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@web/rollup-plugin-import-meta-assets/-/rollup-plugin-import-meta-assets-1.0.7.tgz#7048f717e2218a22af547371ffafdc4f534a2eea"
+ integrity sha512-ft44CqITUkNd8stwNb4ZOvrZ8DlPifM821jplksmxRGetg5Lx684oFrpfQJ7mfkU/Sa7B3dI1mHTX0DE52eBwg==
+ dependencies:
+ "@rollup/pluginutils" "^4.1.0"
+ estree-walker "^2.0.2"
+ magic-string "^0.25.7"
+
"@webcomponents/scoped-custom-element-registry@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@webcomponents/scoped-custom-element-registry/-/scoped-custom-element-registry-0.0.3.tgz#774591a886b0b0e4914717273ba53fd8d5657522"
@@ -5230,7 +5247,7 @@ estree-walker@^1.0.1:
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
-estree-walker@^2.0.1:
+estree-walker@^2.0.1, estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
@@ -10094,9 +10111,9 @@ rollup-plugin-analyzer@^4.0.0:
integrity sha512-LL9GEt3bkXp6Wa19SNR5MWcvHNMvuTFYg+eYBZN2OIFhSWN+pEJUQXEKu5BsOeABob3x9PDaLKW7w5iOJnsESQ==
rollup@^2.58.0:
- version "2.58.0"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.58.0.tgz#a643983365e7bf7f5b7c62a8331b983b7c4c67fb"
- integrity sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw==
+ version "2.79.1"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
+ integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==
optionalDependencies:
fsevents "~2.3.2"
@@ -11679,10 +11696,10 @@ w3c-xmlserializer@^2.0.0:
dependencies:
xml-name-validator "^3.0.0"
-wc-compiler@~0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/wc-compiler/-/wc-compiler-0.7.0.tgz#0ceac8af462502ff69a80eb3861f75eaa39c37f1"
- integrity sha512-jWORep0UIvnZi8+4ek2ZfX1TJik3B5QW/38MZ6UZN/st3TORt13vk50Arr2Rc3zlpam5AGE3Oxi7no8WmEBBXQ==
+wc-compiler@~0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/wc-compiler/-/wc-compiler-0.8.0.tgz#1baadbdc3aff91ff1eba601e56effcb3d6dc5ea8"
+ integrity sha512-vkq9wcpMOTsIDgPvQYso01fQZTD2iGzKTVhO6AbbAz5bE8WUOvNAN9sPy56An26sVmMl/KNL2St5rVmFQ/lw9w==
dependencies:
acorn "^8.7.0"
acorn-jsx "^5.3.2"