From e6ef5f3abea3ad763f10b4272184d61198b53d7e Mon Sep 17 00:00:00 2001 From: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> Date: Wed, 8 Jul 2020 16:35:55 +0200 Subject: [PATCH] feat(workflow): improve DX by triggering rebuild on changes (#937) --- .../cli/__tests__/buildPluginsMap.spec.ts | 3 + .../cli/__tests__/buildPluginsTrace.spec.ts | 3 + packages/cli/package.json | 1 + packages/cli/src/commands/build.ts | 25 +++++++ packages/cli/src/commands/dev.ts | 70 ++++++++++++++++--- packages/cli/src/commands/languages.ts | 3 + packages/cli/src/commands/plugins.ts | 8 ++- packages/cli/src/extensions/cms-extensions.ts | 12 ++++ .../src/extensions/languages-extensions.ts | 24 +++++-- packages/cli/src/extensions/nuxt-extension.ts | 2 + .../cli/src/extensions/plugins-extensions.ts | 10 +++ .../components/SwBottomNavigation.vue | 2 +- 12 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 packages/cli/src/commands/build.ts diff --git a/packages/cli/__tests__/buildPluginsMap.spec.ts b/packages/cli/__tests__/buildPluginsMap.spec.ts index f3273709f..2b78db705 100644 --- a/packages/cli/__tests__/buildPluginsMap.spec.ts +++ b/packages/cli/__tests__/buildPluginsMap.spec.ts @@ -4,6 +4,9 @@ describe("CLI extensions - plugins - buildPluginsMap", () => { template: { generate: jest.fn(), }, + runtime: { + run: jest.fn(), + }, }; beforeAll(() => { pluginsModule(toolbox); diff --git a/packages/cli/__tests__/buildPluginsTrace.spec.ts b/packages/cli/__tests__/buildPluginsTrace.spec.ts index 8ce3276cd..1db453bac 100644 --- a/packages/cli/__tests__/buildPluginsTrace.spec.ts +++ b/packages/cli/__tests__/buildPluginsTrace.spec.ts @@ -8,6 +8,9 @@ describe("CLI extensions - plugins - buildPluginsTrace", () => { print: { error: jest.fn(), }, + runtime: { + run: jest.fn(), + }, }; beforeAll(() => { pluginsModule(toolbox); diff --git a/packages/cli/package.json b/packages/cli/package.json index 1fe74f9f2..9742f79fc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -31,6 +31,7 @@ "license": "MIT", "dependencies": { "@shopware-pwa/shopware-6-client": "0.1.1", + "chokidar": "^3.4.0", "gluegun": "^4.3.1", "lodash": "^4.17.15", "request": "^2.88.2", diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts new file mode 100644 index 000000000..627585d68 --- /dev/null +++ b/packages/cli/src/commands/build.ts @@ -0,0 +1,25 @@ +import { GluegunCommand } from "gluegun"; + +const command: GluegunCommand = { + name: "build", + description: "Build your project for production", + run: async (toolbox) => { + const { + system: { spawn }, + print: { info }, + } = toolbox; + + info(`Starting Shopware PWA project building...`); + + // initial config invoke + await toolbox.plugins.invokeRefreshPlugins(true); + await toolbox.cms.invokeRefreshCMS(); + await toolbox.languages.invokeRefreshLanguages(); + + await spawn("yarn nuxt build", { + stdio: "inherit", + }); + }, +}; + +module.exports = command; diff --git a/packages/cli/src/commands/dev.ts b/packages/cli/src/commands/dev.ts index bf9acfe4a..1acd51ff5 100644 --- a/packages/cli/src/commands/dev.ts +++ b/packages/cli/src/commands/dev.ts @@ -9,22 +9,74 @@ const command: GluegunCommand = { print: { info }, } = toolbox; + const path = require("path"); + const chokidar = require("chokidar"); const jetpack = require("fs-jetpack"); info(`Starting Shopware PWA development project...`); - // toolbox.themeFolders.forEach((themeFolder) => - // toolbox.watchThemeFolder(themeFolder) - // ); + // Watch locales + await jetpack.dirAsync("locales") // create folder if not exist + const localesWatchEvents = ["add", "change", "unlink"]; + const locales = path.join("locales/*.json"); + const localPLuginsLocales = path.join("sw-plugins/**/locales/*"); + chokidar + .watch([locales, localPLuginsLocales], { + ignoreInitial: true, + }) + .on("all", async (event) => { + if (localesWatchEvents.includes(event)) { + await toolbox.languages.invokeRefreshLanguages(true); + } + }); + + // Watch plugins + const pluginsWatchEvents = ["add", "change", "unlink"]; + const localPluginsPath = path.join("sw-plugins"); + chokidar + .watch([localPluginsPath], { + ignoreInitial: true, + ignored: "**/locales/*.json", + }) + .on("all", async (event) => { + if (pluginsWatchEvents.includes(event)) { + await toolbox.plugins.invokeRefreshPlugins(true); + await toolbox.cms.invokeRefreshCMS(); + } + }); - // Refresh languages during local development - if (jetpack.exists("locales")) { - jetpack.watch("locales", { recursive: true }, async () => { - await toolbox.runtime.run(`languages`, { local: true }); + // Watch CMS + const cmsWatchEvents = ["add", "change", "unlink"]; + const cmsPath = path.join("cms"); + chokidar + .watch([cmsPath], { + ignoreInitial: true, + }) + .on("all", async (event) => { + if (cmsWatchEvents.includes(event)) { + toolbox.cms.invokeRefreshCMS(); + } }); - } - await spawn("yarn dev", { + // Watch Cmponents + const componentsWatchEvents = ["add", "unlink"]; + const componentsPath = path.join("components"); + chokidar + .watch([componentsPath], { + ignoreInitial: true, + }) + .on("all", async (event) => { + if (componentsWatchEvents.includes(event)) { + jetpack.copy(`nuxt.config.js`, `nuxt.config.js`, { overwrite: true }); + } + }); + + // initial config invoke + await toolbox.plugins.invokeRefreshPlugins(true); + await toolbox.cms.invokeRefreshCMS(); + await toolbox.languages.invokeRefreshLanguages(); + + await spawn("yarn nuxt", { stdio: "inherit", }); }, diff --git a/packages/cli/src/commands/languages.ts b/packages/cli/src/commands/languages.ts index ef60f7ce0..26e83fc9c 100644 --- a/packages/cli/src/commands/languages.ts +++ b/packages/cli/src/commands/languages.ts @@ -108,6 +108,9 @@ module.exports = { endpoint: inputParameters.shopwareEndpoint, accessToken: inputParameters.shopwareAccessToken, }); + apiClient.onConfigChange(() => { + // nothing to do for now + }); const langs: any = await apiClient.getAvailableLanguages(); langs.forEach((lang) => { diff --git a/packages/cli/src/commands/plugins.ts b/packages/cli/src/commands/plugins.ts index cf0aa81ef..a51665330 100644 --- a/packages/cli/src/commands/plugins.ts +++ b/packages/cli/src/commands/plugins.ts @@ -49,7 +49,7 @@ module.exports = { const generateFilesSpinner = spin("Generating plugins files"); // remove plugin files - await toolbox.filesystem.removeAsync(`.shopware-pwa/sw-plugins`); + // await toolbox.filesystem.removeAsync(`.shopware-pwa/sw-plugins`); await generate({ template: "/plugins/usePlugins.js", @@ -104,7 +104,11 @@ module.exports = { }, }); - await toolbox.runtime.run(`languages`, inputParameters); + const langParams = { + local: true, + ...inputParameters + } + await toolbox?.runtime?.run(`languages`, langParams); success(`Plugins generated`); }, diff --git a/packages/cli/src/extensions/cms-extensions.ts b/packages/cli/src/extensions/cms-extensions.ts index dad2b74a8..b2019c15b 100644 --- a/packages/cli/src/extensions/cms-extensions.ts +++ b/packages/cli/src/extensions/cms-extensions.ts @@ -3,6 +3,18 @@ import { join, resolve } from "path"; import { merge } from "lodash"; module.exports = (toolbox: GluegunToolbox) => { + toolbox.cms = {}; + + let runningRefreshCms: boolean = false; + toolbox.cms.invokeRefreshCMS = async () => { + if (runningRefreshCms) { + return; + } + runningRefreshCms = true; + await toolbox?.runtime?.run(`cms`, {}); + runningRefreshCms = false; + }; + toolbox.resolveCms = async (directoryPath, aliases, cmsComponentsMap) => { // Read cmsMap.json file in cms folder, every cms folder should contain one const readedMap = await toolbox.filesystem.readAsync( diff --git a/packages/cli/src/extensions/languages-extensions.ts b/packages/cli/src/extensions/languages-extensions.ts index a38b29ee3..c24fca74b 100644 --- a/packages/cli/src/extensions/languages-extensions.ts +++ b/packages/cli/src/extensions/languages-extensions.ts @@ -20,10 +20,14 @@ module.exports = (toolbox: GluegunToolbox) => { ); const resultMap = {}; languageKeys.forEach((languageKey) => { - resultMap[languageKey] = toolbox.filesystem.read( - path.join(directoryPath, languageKey), - "json" - ); + try { + resultMap[languageKey] = toolbox.filesystem.read( + path.join(directoryPath, languageKey), + "json" + ); + } catch (e) { + console.warn("Language file " + languageKey + " is not a proper JSON"); + } }); return resultMap; }; @@ -58,4 +62,16 @@ module.exports = (toolbox: GluegunToolbox) => { } return localesPaths; }; + + let runningRefreshLanguages: boolean = false; + toolbox.languages.invokeRefreshLanguages = async ( + isLocal: boolean = false + ) => { + if (runningRefreshLanguages) { + return; + } + runningRefreshLanguages = true; + await toolbox?.runtime?.run(`languages`, { local: isLocal }); + runningRefreshLanguages = false; + }; }; diff --git a/packages/cli/src/extensions/nuxt-extension.ts b/packages/cli/src/extensions/nuxt-extension.ts index 1eb7c19ed..305a20150 100644 --- a/packages/cli/src/extensions/nuxt-extension.ts +++ b/packages/cli/src/extensions/nuxt-extension.ts @@ -71,6 +71,8 @@ module.exports = (toolbox: GluegunToolbox) => { await toolbox.patching.update("package.json", (config) => { config.scripts.lint = "prettier --write '*.{js,vue}'"; + config.scripts.dev = "shopware-pwa dev"; + config.scripts.build = "shopware-pwa build"; // update versions to canary if (canary) { diff --git a/packages/cli/src/extensions/plugins-extensions.ts b/packages/cli/src/extensions/plugins-extensions.ts index 93488af9e..052a8064e 100644 --- a/packages/cli/src/extensions/plugins-extensions.ts +++ b/packages/cli/src/extensions/plugins-extensions.ts @@ -5,6 +5,16 @@ import { join } from "path"; module.exports = (toolbox: GluegunToolbox) => { toolbox.plugins = {}; + let runningRefreshPlugins: boolean = false; + toolbox.plugins.invokeRefreshPlugins = async (devMode: boolean = false) => { + if (runningRefreshPlugins) { + return; + } + runningRefreshPlugins = true; + await toolbox?.runtime?.run(`plugins`, { ci: true, devMode }); + runningRefreshPlugins = false; + }; + toolbox.plugins.getPluginsConfig = async ( options: { localPlugins?: boolean; diff --git a/packages/default-theme/components/SwBottomNavigation.vue b/packages/default-theme/components/SwBottomNavigation.vue index 23d704672..2a3585d37 100644 --- a/packages/default-theme/components/SwBottomNavigation.vue +++ b/packages/default-theme/components/SwBottomNavigation.vue @@ -118,7 +118,7 @@ import { import SwCurrencySwitcher from "@shopware-pwa/default-theme/components/SwCurrencySwitcher" import { onMounted } from "@vue/composition-api" import SwButton from "@shopware-pwa/default-theme/components/atoms/SwButton" -import { PAGE_ACCOUNT } from "../helpers/pages" +import { PAGE_ACCOUNT } from "@shopware-pwa/default-theme/helpers/pages" export default { name: "SwBottomNavigation",