diff --git a/config/jest-jsdom.setup.js b/config/jest-jsdom.setup.js new file mode 100644 index 0000000..e8d213b --- /dev/null +++ b/config/jest-jsdom.setup.js @@ -0,0 +1,3 @@ +// remove jsdom warning for not implemented second argument for window.getComputedStyle +const cmptdStyle = window.getComputedStyle; +window.getComputedStyle = (a) => cmptdStyle(a); diff --git a/config/jest-puppeteer.env.js b/config/jest-puppeteer.env.js index ad89637..4f210c2 100644 --- a/config/jest-puppeteer.env.js +++ b/config/jest-puppeteer.env.js @@ -6,18 +6,19 @@ class PuppeteerRollupEnvironment extends PuppeteerEnvironment { constructor(envConfig, envContext) { super(envConfig, envContext); + this.watch = envConfig.displayName.name === 'puppeteer-dev'; this.ctx = envContext; this.cfg = envConfig; } async setup() { // setup - await setupRollupTest(this.cfg.rootDir, this.ctx.testPath, this.cfg.cache && this.cfg.cacheDirectory); + await setupRollupTest(this.cfg.rootDir, this.ctx.testPath, this.cfg.cache && this.cfg.cacheDirectory, this.watch); await super.setup(); // coverage - const { page } = this.global; - await Promise.all([page.coverage.startCSSCoverage(), page.coverage.startJSCoverage()]); + // const { page } = this.global; + // await Promise.all([page.coverage.startCSSCoverage(), page.coverage.startJSCoverage()]); } async teardown() { diff --git a/config/jest-puppeteer.rollup.js b/config/jest-puppeteer.rollup.js index cb6d08f..cc20c26 100644 --- a/config/jest-puppeteer.rollup.js +++ b/config/jest-puppeteer.rollup.js @@ -2,9 +2,12 @@ const fs = require('fs'); const crypto = require('crypto'); const path = require('path'); const del = require('del'); +const readline = require('readline'); const rollup = require('rollup'); const rollupPluginHtml = require('@rollup/plugin-html'); const rollupPluginStyles = require('rollup-plugin-styles'); +const rollupPluginServe = require('rollup-plugin-serve'); +const rollupPluginLivereload = require('rollup-plugin-livereload'); const deploymentConfig = require('./jest-puppeteer.rollup.config.js'); const rollupConfigName = 'rollup.config.js'; @@ -132,10 +135,12 @@ const filesChanged = (testPath, cacheDir) => { return result; }; -const setupRollupTest = async (rootDir, testPath, cacheDir) => { +const setupRollupTest = async (rootDir, testPath, cacheDir, watch) => { + const rollupWatchers = []; + const rollupServers = []; const testDir = path.dirname(testPath); const testName = path.basename(testDir); - const changed = cacheDir ? filesChanged(testPath, cacheDir) : true; + const changed = cacheDir && !watch ? filesChanged(testPath, cacheDir) : true; const buildFolderExists = fs.existsSync(path.resolve(testDir, deploymentConfig.build)); if (changed || !buildFolderExists) { @@ -148,13 +153,14 @@ const setupRollupTest = async (rootDir, testPath, cacheDir) => { try { const htmlFilePath = path.resolve(testDir, deploymentConfig.html.input); const htmlFileContent = fs.existsSync(htmlFilePath) ? fs.readFileSync(htmlFilePath, 'utf8') : null; + const dist = path.resolve(testDir, deploymentConfig.build); let rollupConfigObj = rollupConfig(undefined, { project: rootDir, overwrite: ({ defaultConfig }) => { return { + dist, input: path.resolve(testDir, deploymentConfig.js.input), - dist: path.resolve(testDir, deploymentConfig.build), file: deploymentConfig.js.output, types: null, minVersions: false, @@ -170,6 +176,23 @@ const setupRollupTest = async (rootDir, testPath, cacheDir) => { template: genHtmlTemplateFunc(htmlFileContent), meta: [{ charset: 'utf-8' }, { 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' }], }), + ...(watch + ? [ + rollupPluginServe({ + contentBase: dist, + historyApiFallback: `/${deploymentConfig.html.output}`, + port: 18080, + onListening(server) { + rollupServers.push(server); + }, + }), + rollupPluginLivereload({ + watch: dist, + verbose: true, + port: 28080, + }), + ] + : []), ], }; }, @@ -184,17 +207,82 @@ const setupRollupTest = async (rootDir, testPath, cacheDir) => { for (let i = 0; i < rollupConfigObj.length; i++) { const inputConfig = rollupConfigObj[i]; let { output } = inputConfig; - // eslint-disable-next-line no-await-in-loop - const bundle = await rollup.rollup(inputConfig); if (!Array.isArray(output)) { output = [output]; } - for (let v = 0; v < output.length; v++) { - const outputConfig = output[i]; + if (watch) { + let firstWatch = true; + const rollupWatcher = rollup.watch({ + ...inputConfig, + output, + }); + // eslint-disable-next-line no-await-in-loop - await bundle.write(outputConfig); + await new Promise((resolve) => { + rollupWatcher.on('event', ({ code, duration, error, result }) => { + if (code === 'ERROR') { + console.log('Error:', error); // eslint-disable-line + } + if (code === 'START') { + console.log(firstWatch ? 'Building...' : 'Rebuilding...'); // eslint-disable-line + } + if (code === 'BUNDLE_END') { + console.log(`Bundle finished after ${Math.round(duration / 1000)} seconds.`); // eslint-disable-line + if (result && result.close) { + result.close(); + } + } + if (code === 'END') { + console.log('Watching for changes, press ENTER to continue.'); // eslint-disable-line + console.log(''); // eslint-disable-line + if (firstWatch) { + firstWatch = false; + resolve(); + } + } + }); + }); + + rollupWatchers.push(rollupWatcher); + } else { + // eslint-disable-next-line no-await-in-loop + const bundle = await rollup.rollup(inputConfig); + + for (let v = 0; v < output.length; v++) { + const outputConfig = output[i]; + // eslint-disable-next-line no-await-in-loop + await bundle.write(outputConfig); + } + } + } + + if (watch) { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + await new Promise((resolve) => { + rl.on('line', () => { + resolve(); + }); + rl.on('close', () => { + resolve(); + }); + }); + + rl.close(); + rollupWatchers.forEach((watcher) => { + watcher.close(); + }); + rollupServers.forEach((server) => { + server.close(); + }); + if (rollupPluginLivereload && global.PLUGIN_LIVERELOAD && global.PLUGIN_LIVERELOAD.server) { + global.PLUGIN_LIVERELOAD.server.close(); + global.PLUGIN_LIVERELOAD.server = null; } } } catch (e) { diff --git a/config/jest-puppeteer.setup.js b/config/jest-puppeteer.setup.js new file mode 100644 index 0000000..91d9ef2 --- /dev/null +++ b/config/jest-puppeteer.setup.js @@ -0,0 +1,4 @@ +const setDefaultOptions = require('expect-puppeteer').setDefaultOptions; + +jest.setTimeout(60000); +setDefaultOptions({ timeout: 60000 }); diff --git a/jest.config.base.js b/jest.config.base.js index a9779da..06585ba 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -4,6 +4,8 @@ const puppeteerRollupConfig = require('./config/jest-puppeteer.rollup.config.js' const testEnvironmentPath = path.resolve(__dirname, './config/jest-puppeteer.env.js'); const testServerLoaderPath = path.resolve(__dirname, './config/jest-test-server.loader.js'); +const jsdomSetupFile = path.resolve(__dirname, './config/jest-jsdom.setup.js'); +const puppeteerSetupFile = path.resolve(__dirname, './config/jest-puppeteer.setup.js'); // For a detailed explanation regarding each configuration property, visit: // https://jestjs.io/docs/en/configuration.html @@ -20,26 +22,36 @@ const base = { }, }; +const pptrBase = { + ...base, + preset: 'jest-puppeteer', + setupFilesAfterEnv: ['expect-puppeteer', puppeteerSetupFile], + testMatch: ['**/tests/puppeteer/**/*.test.[jt]s?(x)'], + testEnvironment: testEnvironmentPath, + coveragePathIgnorePatterns: ['/node_modules/', `/${puppeteerRollupConfig.build}/`], + transform: { + '^.+\\.[jt]sx?$': 'babel-jest', + [`^.+${puppeteerRollupConfig.build}.+${puppeteerRollupConfig.html.output}?$`]: testServerLoaderPath, + }, +}; + module.exports = { ...base, projects: [ { ...base, displayName: 'jsdom', + setupFilesAfterEnv: [jsdomSetupFile], testMatch: ['**/tests/jsdom/**/*.test.[jt]s?(x)'], }, { - ...base, - preset: 'jest-puppeteer', + ...pptrBase, displayName: 'puppeteer', - setupFilesAfterEnv: ['expect-puppeteer'], - testMatch: ['**/tests/puppeteer/**/*.test.[jt]s?(x)'], - testEnvironment: testEnvironmentPath, - coveragePathIgnorePatterns: ['/node_modules/', `/${puppeteerRollupConfig.build}/`], - transform: { - '^.+\\.[jt]sx?$': 'babel-jest', - [`^.+${puppeteerRollupConfig.build}.+${puppeteerRollupConfig.html.output}?$`]: testServerLoaderPath, - }, + }, + { + ...pptrBase, + displayName: 'puppeteer-dev', + collectCoverage: false, }, ], }; diff --git a/package.json b/package.json index c62c89e..90ad517 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,10 @@ "prettier-eslint": "^11.0.0", "puppeteer": "^5.2.1", "puppeteer-to-istanbul": "^1.4.0", - "rollup": "^2.22.1", + "rollup": "^2.36.1", + "rollup-plugin-livereload": "^2.0.0", "rollup-plugin-prettier": "^2.1.0", + "rollup-plugin-serve": "^1.1.0", "rollup-plugin-styles": "^3.10.0", "rollup-plugin-terser": "^6.1.0", "rollup-plugin-typescript2": "^0.27.1", @@ -62,6 +64,7 @@ "test": "yarn workspaces run test", "test:jsdom": "yarn workspaces run test:jsdom", "test:pptr": "yarn workspaces run test:pptr", + "test:pptr-dev": "yarn workspaces run test:pptr-dev", "build": "yarn workspaces run build", "lint": "npx eslint --fix ." } diff --git a/packages/overlayscrollbars/package.json b/packages/overlayscrollbars/package.json index f64d2e1..176ecaa 100644 --- a/packages/overlayscrollbars/package.json +++ b/packages/overlayscrollbars/package.json @@ -7,6 +7,7 @@ "test": "jest --coverage --runInBand --detectOpenHandles", "test:jsdom": "jest --coverage --runInBand --detectOpenHandles --selectProjects jsdom --testPathPattern", "test:pptr": "jest --coverage --runInBand --detectOpenHandles --selectProjects puppeteer --testPathPattern", + "test:pptr-dev": "jest --coverage --runInBand --detectOpenHandles --selectProjects puppeteer-dev --testPathPattern", "build": "rollup -c" } } diff --git a/packages/overlayscrollbars/tests/puppeteer/Environment/index.test.ts b/packages/overlayscrollbars/tests/puppeteer/Environment/index.test.ts index 575793f..2891c40 100644 --- a/packages/overlayscrollbars/tests/puppeteer/Environment/index.test.ts +++ b/packages/overlayscrollbars/tests/puppeteer/Environment/index.test.ts @@ -6,7 +6,7 @@ describe('Environment', () => { await page.goto(url); }); - it('should be titled "Environment"', async () => { + test('page should be titled "Environment"', async () => { // @ts-ignore const a: Environment = await page.evaluate(() => window.environment.envInstance); console.log(a); diff --git a/packages/overlayscrollbars/tests/puppeteer/lifecycles/structureLifecycle/index.test.ts b/packages/overlayscrollbars/tests/puppeteer/lifecycles/structureLifecycle/index.test.ts index 019d7b2..a04baa5 100644 --- a/packages/overlayscrollbars/tests/puppeteer/lifecycles/structureLifecycle/index.test.ts +++ b/packages/overlayscrollbars/tests/puppeteer/lifecycles/structureLifecycle/index.test.ts @@ -6,7 +6,7 @@ describe('StructureLifecycle', () => { await page.goto(url); }); - it('should be titled "Environment"', async () => { + test('page should be titled "Environment"', async () => { // @ts-ignore const a: Environment = await page.evaluate(() => window.structureLifecycle.envInstance); console.log(a); diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.browser.ts b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.browser.ts new file mode 100644 index 0000000..46bed3e --- /dev/null +++ b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.browser.ts @@ -0,0 +1,185 @@ +import 'overlayscrollbars.scss'; +import './index.scss'; +import should from 'should'; +import { waitFor } from '@testing-library/dom'; +import { generateSelectCallback, iterateSelect } from '@/testing-browser/Select'; +import { setTestResult } from '@/testing-browser/TestResult'; +import { hasDimensions, offsetSize, WH, style } from 'support'; + +import { createSizeObserver } from 'observers/sizeObserver'; + +let sizeIterations = 0; +let directionIterations = 0; +const contentBox = (elm: HTMLElement | null): WH => { + if (elm) { + const computedStyle = window.getComputedStyle(elm); + return { + w: elm.clientWidth - (parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)), + h: elm.clientHeight - (parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)), + }; + } + + return { w: 0, h: 0 }; +}; + +const targetElm = document.querySelector('#target'); +const heightSelect: HTMLSelectElement | null = document.querySelector('#height'); +const widthSelect: HTMLSelectElement | null = document.querySelector('#width'); +const paddingSelect: HTMLSelectElement | null = document.querySelector('#padding'); +const borderSelect: HTMLSelectElement | null = document.querySelector('#border'); +const boxSizingSelect: HTMLSelectElement | null = document.querySelector('#boxSizing'); +const displaySelect: HTMLSelectElement | null = document.querySelector('#display'); +const directionSelect: HTMLSelectElement | null = document.querySelector('#direction'); +const startBtn: HTMLButtonElement | null = document.querySelector('#start'); +const resizesSlot: HTMLButtonElement | null = document.querySelector('#resizes'); + +const selectCallback = generateSelectCallback(targetElm as HTMLElement); +const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any) => { + interface IterateSelect { + currSizeIterations: number; + currDirectionIterations: number; + currOffsetSize: WH; + currContentSize: WH; + currDir: string; + } + + await iterateSelect(select, { + beforeEach() { + const currSizeIterations = sizeIterations; + const currDirectionIterations = directionIterations; + const currOffsetSize = offsetSize(targetElm as HTMLElement); + const currContentSize = contentBox(targetElm as HTMLElement); + const currDir = style(targetElm as HTMLElement, 'direction'); + + return { + currSizeIterations, + currDirectionIterations, + currOffsetSize, + currContentSize, + currDir, + }; + }, + async check({ currSizeIterations, currDirectionIterations, currOffsetSize, currContentSize, currDir }) { + const newOffsetSize = offsetSize(targetElm as HTMLElement); + const newContentSize = contentBox(targetElm as HTMLElement); + const newDir = style(targetElm as HTMLElement, 'direction'); + const offsetSizeChanged = currOffsetSize.w !== newOffsetSize.w || currOffsetSize.h !== newOffsetSize.h; + const contentSizeChanged = currContentSize.w !== newContentSize.w || currContentSize.h !== newContentSize.h; + const dirChanged = currDir !== newDir; + const dimensions = hasDimensions(targetElm as HTMLElement); + const observerElm = targetElm?.firstElementChild as HTMLElement; + + // no overflow if not needed + if (targetElm && newContentSize.w > 0) { + should.ok(observerElm.getBoundingClientRect().right <= targetElm.getBoundingClientRect().right); + } + if (targetElm && newContentSize.h > 0) { + should.ok(observerElm.getBoundingClientRect().bottom <= targetElm.getBoundingClientRect().bottom); + } + + if (dimensions && (offsetSizeChanged || contentSizeChanged || dirChanged)) { + await waitFor( + () => { + if (offsetSizeChanged || contentSizeChanged) { + should.equal(sizeIterations, currSizeIterations + 1); + } + if (dirChanged) { + should.equal(directionIterations, currDirectionIterations + 1); + } + }, + { + onTimeout(error): Error { + setTestResult(false); + return error; + }, + } + ); + } + }, + afterEach, + }); +}; + +heightSelect?.addEventListener('change', selectCallback); +widthSelect?.addEventListener('change', selectCallback); +paddingSelect?.addEventListener('change', selectCallback); +borderSelect?.addEventListener('change', selectCallback); +boxSizingSelect?.addEventListener('change', selectCallback); +displaySelect?.addEventListener('change', selectCallback); +directionSelect?.addEventListener('change', selectCallback); + +selectCallback(heightSelect); +selectCallback(widthSelect); +selectCallback(paddingSelect); +selectCallback(borderSelect); +selectCallback(boxSizingSelect); +selectCallback(displaySelect); +selectCallback(directionSelect); + +const iteratePadding = async (afterEach?: () => any) => { + await iterate(paddingSelect, afterEach); +}; +const iterateBorder = async (afterEach?: () => any) => { + await iterate(borderSelect, afterEach); +}; +const iterateHeight = async (afterEach?: () => any) => { + await iterate(heightSelect, afterEach); +}; +const iterateWidth = async (afterEach?: () => any) => { + await iterate(widthSelect, afterEach); +}; +const iterateBoxSizing = async (afterEach?: () => any) => { + await iterate(boxSizingSelect, afterEach); +}; +const iterateDisplay = async (afterEach?: () => any) => { + await iterate(displaySelect, afterEach); +}; +const iterateDirection = async (afterEach?: () => any) => { + await iterate(directionSelect, afterEach); +}; + +const start = async () => { + setTestResult(null); + + console.log('init direction changes:', directionIterations); + console.log('init size changes:', sizeIterations); + should.ok(directionIterations > 0); + should.ok(sizeIterations > 0); + + targetElm?.removeAttribute('style'); + await iterateDisplay(); + await iterateDirection(); + await iterateBoxSizing(async () => { + await iterateHeight(async () => { + await iterateWidth(async () => { + await iterateBorder(async () => { + await iterateDirection(); + await iteratePadding(); + }); + }); + }); + }); + + setTestResult(true); +}; + +startBtn?.addEventListener('click', start); + +createSizeObserver( + targetElm as HTMLElement, + (directionCache?: any) => { + if (directionCache) { + directionIterations += 1; + } else { + sizeIterations += 1; + } + requestAnimationFrame(() => { + if (resizesSlot) { + resizesSlot.textContent = (directionIterations + sizeIterations).toString(); + } + }); + }, + { _direction: true, _appear: true } +); +console.log('h1'); +export { start }; diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.html b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.html new file mode 100644 index 0000000..05167a7 --- /dev/null +++ b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.html @@ -0,0 +1,49 @@ +
+ + + + + + + + + + + + + + + + + Detected resizes: 0 +
+
+
+
+
+
diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.scss b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.scss new file mode 100644 index 0000000..8e9c890 --- /dev/null +++ b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.scss @@ -0,0 +1,99 @@ +body { + display: flex; + flex-direction: column; +} +#controls { + flex: none; +} +#stage { + flex: auto; + position: relative; + + & > div { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: lightgoldenrodyellow; + } +} + +#canvas > div { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +#target { + overflow: hidden; + resize: both; + position: relative; + // prevent container from reaching 0x0 dimensions for testing purposes + min-width: 50px; + min-height: 50px; +} + +.padding0 { + padding: 0; +} +.padding10 { + padding: 10px; +} +.padding50 { + padding: 50px; +} + +.border2 { + border: 2px solid red; +} +.border10 { + border: 10px solid red; +} +.border0 { + border: none; +} + +.heightAuto { + height: auto; +} +.height200 { + height: 200px; +} +.heightHundred { + height: 100%; +} + +.widthAuto { + width: auto; + float: left; +} +.width200 { + width: 200px; +} +.widthHundred { + width: 100%; +} + +.boxSizingBorderBox { + box-sizing: border-box; +} +.boxSizingContentBox { + box-sizing: content-box; +} + +.displayNone { + display: none; +} +.displayBlock { + display: block; +} + +.directionltr { + direction: ltr; +} +.directionRTL { + direction: rtl; +} diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.test.ts b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.test.ts new file mode 100644 index 0000000..ccb8a4f --- /dev/null +++ b/packages/overlayscrollbars/tests/puppeteer/observers/domObserver/index.test.ts @@ -0,0 +1,13 @@ +import expectPuppeteer from 'expect-puppeteer'; +import url from './.build/build.html'; + +describe('DOMObserver', () => { + beforeAll(async () => { + await page.goto(url); + }); + + test('test', async () => { + await expectPuppeteer(page).toClick('#start'); + await expectPuppeteer(page).toMatchElement('#testResult.passed'); + }); +}); diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/sizeObserver/index.test.ts b/packages/overlayscrollbars/tests/puppeteer/observers/sizeObserver/index.test.ts index 0d2ffb1..3d580d9 100644 --- a/packages/overlayscrollbars/tests/puppeteer/observers/sizeObserver/index.test.ts +++ b/packages/overlayscrollbars/tests/puppeteer/observers/sizeObserver/index.test.ts @@ -1,15 +1,13 @@ import expectPuppeteer from 'expect-puppeteer'; import url from './.build/build.html'; -describe('Environment', () => { +describe('SizeObserver', () => { beforeAll(async () => { await page.goto(url); }); - it('test', async () => { + test('test', async () => { await expectPuppeteer(page).toClick('#start'); - await expectPuppeteer(page).toMatchElement('#testResult.passed', { - timeout: 60000, - }); - }, 60000); + await expectPuppeteer(page).toMatchElement('#testResult.passed'); + }); }); diff --git a/packages/overlayscrollbars/tests/puppeteer/observers/trinsicObserver/index.test.ts b/packages/overlayscrollbars/tests/puppeteer/observers/trinsicObserver/index.test.ts index 0d2ffb1..4c67ff5 100644 --- a/packages/overlayscrollbars/tests/puppeteer/observers/trinsicObserver/index.test.ts +++ b/packages/overlayscrollbars/tests/puppeteer/observers/trinsicObserver/index.test.ts @@ -1,15 +1,13 @@ import expectPuppeteer from 'expect-puppeteer'; import url from './.build/build.html'; -describe('Environment', () => { +describe('TrinsicObserver', () => { beforeAll(async () => { await page.goto(url); }); - it('test', async () => { + test('test', async () => { await expectPuppeteer(page).toClick('#start'); - await expectPuppeteer(page).toMatchElement('#testResult.passed', { - timeout: 60000, - }); - }, 60000); + await expectPuppeteer(page).toMatchElement('#testResult.passed'); + }); }); diff --git a/rollup.config.base.js b/rollup.config.base.js index 1d85c34..6a22479 100644 --- a/rollup.config.base.js +++ b/rollup.config.base.js @@ -243,26 +243,37 @@ const rollupConfig = (config = {}, { project = process.cwd(), overwrite = {}, si const isLast = index === buildsArr.length - 1; if (isFirst) { + const deleteGeneratedDirs = () => { + const deletedDirs = del.sync([distPath, typesPath].filter((curr) => curr !== null)); + if (deletedDirs.length > 0 && !silent) { + console.log('Deleted directories:\n', deletedDirs.join('\n')); + } + }; build.plugins.unshift({ name: 'deleteGeneratedDirs', options() { - const deletedDirs = del.sync([distPath, typesPath].filter((curr) => curr !== null)); - if (deletedDirs.length > 0 && !silent) { - console.log('Deleted directories:\n', deletedDirs.join('\n')); + if (!this.meta.watchMode) { + deleteGeneratedDirs(); } }, }); } if (isLast) { + const deleteCacheDirs = () => { + const cacheDirs = cache.map((dir) => path.resolve(projectPath, dir)); + const deletedDirs = del.sync(cacheDirs); + if (deletedDirs.length > 0 && !silent) { + console.log('Deleted cache:\n', deletedDirs.join('\n')); + } + }; build.plugins.push({ name: 'deleteCacheDirs', writeBundle() { - const cacheDirs = cache.map((dir) => path.resolve(projectPath, dir)); - const deletedDirs = del.sync(cacheDirs); - if (deletedDirs.length > 0 && !silent) { - console.log('Deleted cache:\n', deletedDirs.join('\n')); + if (!this.meta.watchMode) { + deleteCacheDirs(); } }, + closeWatcher: deleteCacheDirs, }); } diff --git a/yarn.lock b/yarn.lock index 9662b2b..aa26f95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1784,7 +1784,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== @@ -1913,6 +1913,11 @@ async-foreach@^0.1.3: resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -2055,6 +2060,11 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -2123,7 +2133,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2331,6 +2341,21 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chokidar@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" + integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -3963,6 +3988,11 @@ fsevents@^2.1.2, fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" @@ -4055,7 +4085,7 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== @@ -4487,6 +4517,13 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.0.2, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -4607,7 +4644,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -5555,6 +5592,21 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +livereload-js@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-3.3.1.tgz#61f887468086762e61fb2987412cf9d1dda99202" + integrity sha512-CBu1gTEfzVhlOK1WASKAAJ9Qx1fHECTq0SUB67sfxwQssopTyvzqTlgl+c0h9pZ6V+Fzd2rc510ppuNusg9teQ== + +livereload@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/livereload/-/livereload-0.9.1.tgz#65125dabdf2db4fd3f1169e953fe56e3bcc6f477" + integrity sha512-9g7sua11kkyZNo2hLRCG3LuZZwqexoyEyecSlV8cAsfAVVCZqLzVir6XDqmH0r+Vzgnd5LrdHDMyjtFnJQLAYw== + dependencies: + chokidar "^3.3.0" + livereload-js "^3.1.0" + opts ">= 1.2.0" + ws "^6.2.1" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -5837,6 +5889,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@>=2.4.6: + version "2.4.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" + integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== + mime@^2.0.3: version "2.4.6" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" @@ -6099,7 +6156,7 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -6282,6 +6339,11 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +opener@1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -6306,6 +6368,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +"opts@>= 1.2.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1" + integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg== + os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -7206,6 +7273,13 @@ readable-stream@^3.1.1, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -7465,6 +7539,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rollup-plugin-livereload@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.0.tgz#d3928d74e8cf2ae4286c5dd46b770fd3f3b82313" + integrity sha512-oC/8NqumGYuphkqrfszOHUUIwzKsaHBICw6QRwT5uD07gvePTS+HW+GFwu6f9K8W02CUuTvtIM9AWJrbj4wE1A== + dependencies: + livereload "^0.9.1" + rollup-plugin-prettier@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/rollup-plugin-prettier/-/rollup-plugin-prettier-2.1.0.tgz#06b42169e28cb23163d4648bef412e57ff70acb4" @@ -7477,6 +7558,14 @@ rollup-plugin-prettier@^2.1.0: lodash.omitby "4.6.0" magic-string "0.25.7" +rollup-plugin-serve@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-serve/-/rollup-plugin-serve-1.1.0.tgz#0654a57021a21b903340c69940f7463706e8288d" + integrity sha512-pYkSsuA0/psKqhhictkJw1c2klya5b+LlCvipWqI9OE1aG2M97mRumZCbBlry5CMEOzYBBgSDgd1694sNbmyIw== + dependencies: + mime ">=2.4.6" + opener "1" + rollup-plugin-styles@^3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/rollup-plugin-styles/-/rollup-plugin-styles-3.10.0.tgz#8e0e6c96ae235d15bfe5f03d9d0ee5282f3f40a2" @@ -7521,10 +7610,10 @@ rollup-plugin-typescript2@^0.27.1: resolve "1.17.0" tslib "2.0.1" -rollup@^2.22.1: - version "2.26.11" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.26.11.tgz#4fc31de9c7b83d50916fc8395f8c3d24730cdaae" - integrity sha512-xyfxxhsE6hW57xhfL1I+ixH8l2bdoIMaAecdQiWF3N7IgJEMu99JG+daBiSZQjnBpzFxa0/xZm+3pbCdAQehHw== +rollup@^2.36.1: + version "2.36.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.36.1.tgz#2174f0c25c7b400d57b05628d0e732c7ae8d2178" + integrity sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ== optionalDependencies: fsevents "~2.1.2" @@ -8925,6 +9014,13 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + ws@^7.2.3: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8"