From d41a6979f13e3576aa216534365e35c7dfd0523a Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Wed, 12 Aug 2020 12:38:26 -0400 Subject: [PATCH 1/3] refactor compilation spec --- test/e2e/compilation.spec.js | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/test/e2e/compilation.spec.js b/test/e2e/compilation.spec.js index b768941..0aa1a39 100644 --- a/test/e2e/compilation.spec.js +++ b/test/e2e/compilation.spec.js @@ -19,25 +19,20 @@ const normalizeErrMessage = (message) => { const fixturesDir = path.join(__dirname, '..', 'fixtures') const outputDir = path.join(__dirname, '..', '_test-output') +const createFile = ({ name = 'example_spec.js', shouldWatch = false } = {}) => { + return Object.assign(new EventEmitter(), { + filePath: path.join(outputDir, name), + outputPath: path.join(outputDir, name.replace('.', '_output.')), + shouldWatch, + }) +} + describe('webpack preprocessor - e2e', () => { - let run let file beforeEach(async () => { preprocessor.__reset() - run = ({ options, keepFile, shouldWatch = false, fileName = 'example_spec.js' } = {}) => { - if (!keepFile) { - file = Object.assign(new EventEmitter(), { - filePath: path.join(outputDir, fileName), - outputPath: path.join(outputDir, fileName.replace('.', '_output.')), - shouldWatch, - }) - } - - return preprocessor(options)(file) - } - await fs.remove(outputDir) await fs.copy(fixturesDir, outputDir) }) @@ -54,14 +49,17 @@ describe('webpack preprocessor - e2e', () => { const options = preprocessor.defaultOptions options.webpackOptions.mode = 'production' // snapshot will be minified + file = createFile() - return run({ options }).then((outputPath) => { + return preprocessor(options)(file).then((outputPath) => { snapshot(fs.readFileSync(outputPath).toString()) }) }) it('has less verbose "Module not found" error', () => { - return run({ fileName: 'imports_nonexistent_file_spec.js' }) + file = createFile({ name: 'imports_nonexistent_file_spec.js' }) + + return preprocessor()(file) .then(() => { throw new Error('Should not resolve') }) @@ -71,7 +69,9 @@ describe('webpack preprocessor - e2e', () => { }) it('has less verbose syntax error', () => { - return run({ fileName: 'syntax_error_spec.js' }) + file = createFile({ name: 'syntax_error_spec.js' }) + + return preprocessor()(file) .then(() => { throw new Error('Should not resolve') }) @@ -87,12 +87,14 @@ describe('webpack preprocessor - e2e', () => { throw new Error('Should not have trigger unhandled rejection') }) - await run({ shouldWatch: true }) + file = createFile({ shouldWatch: true }) + + await preprocessor()(file) await fs.outputFile(file.filePath, '{') await new Promise((resolve) => { setTimeout(() => { - run({ keepFile: true, shouldWatch: true }) + preprocessor()(file) .catch((err) => { expect(err.stack).to.include('Unexpected token') resolve() @@ -102,7 +104,9 @@ describe('webpack preprocessor - e2e', () => { }) it('triggers rerun on syntax error', async () => { - await run({ shouldWatch: true }) + const file = createFile({ shouldWatch: true }) + + await preprocessor()(file) const _emit = sinon.spy(file, 'emit') From 8b52f3270dc2a12564fdf3168f38ece8d4898030 Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Wed, 12 Aug 2020 13:34:38 -0400 Subject: [PATCH 2/3] fix eslint, improve scripts --- .eslintignore | 1 + package.json | 5 +- yarn.lock | 134 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 130 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index 627de35..68f7973 100644 --- a/.eslintignore +++ b/.eslintignore @@ -13,3 +13,4 @@ examples/use-babelrc/cypress/integration/spec.js dist tsconfig.json .vscode/ +.history diff --git a/package.json b/package.json index 2470246..d44fd1b 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,13 @@ "secure": "nsp check", "semantic-release": "semantic-release", "size": "npm pack --dry", - "pretest": "yarn lint && yarn build", "test": "yarn test-unit && yarn test-e2e", "test-debug": "node --inspect --debug-brk ./node_modules/.bin/_mocha", "test-e2e": "mocha test/e2e/*.spec.*", "test-unit": "mocha test/unit/*.spec.*", "test-watch": "yarn test-unit & chokidar '**/*.(js|ts)' 'test/unit/*.(js|ts)' -c 'yarn test-unit'", - "types": "tsc --noEmit" + "types": "tsc --noEmit", + "watch": "yarn build --watch" }, "husky": { "hooks": { @@ -37,6 +37,7 @@ "@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3", "@babel/preset-env": "^7.0.0", "@cypress/eslint-plugin-dev": "5.0.0", + "@fellow/eslint-plugin-coffee": "0.4.13", "@types/webpack": "4.41.12", "@typescript-eslint/eslint-plugin": "2.31.0", "@typescript-eslint/parser": "2.31.0", diff --git a/yarn.lock b/yarn.lock index 3c62ab3..599258f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1754,6 +1754,32 @@ debug "^3.1.0" lodash.once "^4.1.1" +"@fellow/coffeelint2@^2.2.3": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@fellow/coffeelint2/-/coffeelint2-2.2.6.tgz#df7ff93baed710931a0d6b8e7adb25ec089a5011" + integrity sha512-iLS/iYje87iM5atbW/op6tp45h0ruEGqMqHZVbE2q4qDx6XO8+8XOX03ppGPxkOWfxlbJqIDVnyie8GG/3MCnA== + dependencies: + coffeescript "^2.1.2" + glob "^7.0.6" + ignore "^3.0.9" + lodash-es "^4.17.5" + optimist "^0.6.1" + resolve "^0.6.3" + strip-json-comments "^1.0.4" + +"@fellow/eslint-plugin-coffee@0.4.13": + version "0.4.13" + resolved "https://registry.yarnpkg.com/@fellow/eslint-plugin-coffee/-/eslint-plugin-coffee-0.4.13.tgz#28946316e92bca00920e11efefb084c0f4cd76b0" + integrity sha512-7/dBoPmLXWPMq2Tk3AX/yeIA35c0YyNkVF92h1RIsTgGiv9O6IjWFQ39LdywUdoBH6HXFPBGUjlo+zenKFBOlw== + dependencies: + "@fellow/coffeelint2" "^2.2.3" + babel-eslint "^7.2.3" + coffeescript "^2.1.2" + eslint-module-utils "^2.1.1" + find-remove "^1.2.0" + lodash "^4.17.5" + source-map "^0.6.1" + "@hapi/address@2.x.x", "@hapi/address@^2.1.2": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -3442,7 +3468,7 @@ axobject-query@^2.0.2: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" integrity sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ== -babel-code-frame@^6.22.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -3463,6 +3489,16 @@ babel-eslint@10.0.3: eslint-visitor-keys "^1.0.0" resolve "^1.12.0" +babel-eslint@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827" + integrity sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc= + dependencies: + babel-code-frame "^6.22.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.17.0" + babel-extract-comments@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" @@ -3493,6 +3529,13 @@ babel-loader@8.0.6, babel-loader@^8.0.2: mkdirp "^0.5.1" pify "^4.0.1" +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + babel-plugin-dynamic-import-node@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" @@ -3578,7 +3621,7 @@ babel-preset-react-app@^9.0.2: babel-plugin-macros "2.8.0" babel-plugin-transform-react-remove-prop-types "0.4.24" -babel-runtime@^6.23.0, babel-runtime@^6.26.0: +babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -3586,7 +3629,32 @@ babel-runtime@^6.23.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babylon@^6.18.0: +babel-traverse@^6.23.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.23.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.17.0, babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== @@ -4583,6 +4651,11 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +coffeescript@^2.1.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.5.1.tgz#b2442a1f2c806139669534a54adc35010559d16a" + integrity sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -5407,7 +5480,7 @@ debug@2.6.0: dependencies: ms "0.7.2" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -6179,7 +6252,7 @@ eslint-loader@3.0.2: object-hash "^1.3.1" schema-utils "^2.2.0" -eslint-module-utils@^2.4.0: +eslint-module-utils@^2.1.1, eslint-module-utils@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== @@ -6999,6 +7072,14 @@ find-npm-prefix@^1.0.2: resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== +find-remove@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/find-remove/-/find-remove-1.2.2.tgz#b479d3b7c2b62ddc3f91f0001b7836f121ac9395" + integrity sha512-P94ar9U0b7AifpOu7MR1iA3cMN4J4kqIJkW15Ol8H0Lp3MI+U32ugunpDXCKOpFgFRRCMBracWWuyT0m3sIU+g== + dependencies: + fmerge "1.2.0" + rimraf "2.6.2" + find-up@3.0.0, find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -7097,6 +7178,11 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +fmerge@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fmerge/-/fmerge-1.2.0.tgz#36e99d2ae255e3ee1af666b4df780553671cf692" + integrity sha1-NumdKuJV4+4a9ma033gFU2cc9pI= + folktale@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/folktale/-/folktale-2.3.2.tgz#38231b039e5ef36989920cbf805bf6b227bf4fd4" @@ -7490,7 +7576,7 @@ glob@7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -7549,6 +7635,11 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + globby@10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22" @@ -8112,7 +8203,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.2.7, ignore@^3.3.3, ignore@^3.3.5: +ignore@^3.0.9, ignore@^3.2.7, ignore@^3.3.3, ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== @@ -9965,6 +10056,11 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" +lodash-es@^4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -11527,7 +11623,7 @@ opn@^5.1.0: dependencies: is-wsl "^1.1.0" -optimist@0.6.1: +optimist@0.6.1, optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= @@ -13944,6 +14040,11 @@ resolve@1.12.0, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2: dependencies: path-parse "^1.0.6" +resolve@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + integrity sha1-3ZV5gufnNt699TtYpN2RdUV13UY= + resolve@^1.1.6, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.8.1: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" @@ -14025,6 +14126,13 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rimraf@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + rimraf@2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -15241,6 +15349,11 @@ strip-json-comments@2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-json-comments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" @@ -15547,6 +15660,11 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" From 5b45b8c904a6600635935ccb58cc704b94717d59 Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Wed, 12 Aug 2020 13:34:59 -0400 Subject: [PATCH 3/3] fix: don't emit rerun on initial bundle --- index.ts | 32 ++++++++++++++++++++++---------- test/e2e/compilation.spec.js | 15 ++++++++++++++- test/unit/index.spec.js | 14 ++++++++++++-- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/index.ts b/index.ts index a0c5c5f..0987996 100644 --- a/index.ts +++ b/index.ts @@ -11,9 +11,13 @@ const debug = require('debug')('cypress:webpack') const debugStats = require('debug')('cypress:webpack:stats') type FilePath = string +interface BundleObject { + promise: Promise + initial: boolean +} // bundle promises from input spec filename to output bundled file paths -let bundles: {[key: string]: Promise} = {} +let bundles: {[key: string]: BundleObject} = {} // we don't automatically load the rules, so that the babel dependencies are // not required if a user passes in their own configuration @@ -164,7 +168,7 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F if (bundles[filePath]) { debug(`already have bundle for ${filePath}`) - return bundles[filePath] + return bundles[filePath].promise } const defaultWebpackOptions = getDefaultWebpackOptions() @@ -229,7 +233,10 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F // cache the bundle promise, so it can be returned if this function // is invoked again with the same filePath - bundles[filePath] = latestBundle.promise + bundles[filePath] = { + promise: latestBundle.promise, + initial: true, + } const rejectWithErr = (err: Error) => { err = quietErrorMessage(err) @@ -294,19 +301,24 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F // we overwrite the latest bundle, so that a new call to this function // returns a promise that resolves when the bundling is finished latestBundle = createDeferred() - bundles[filePath] = latestBundle.promise + bundles[filePath].promise = latestBundle.promise - bundles[filePath].finally(() => { - debug('- compile finished for', filePath) + bundles[filePath].promise.finally(() => { + debug('- compile finished for %s, initial? %s', filePath, bundles[filePath].initial) // when the bundling is finished, emit 'rerun' to let Cypress - // know to rerun the spec - file.emit('rerun') + // know to rerun the spec, but NOT when it is the initial + // bundling of the file + if (!bundles[filePath].initial) { + file.emit('rerun') + } + + bundles[filePath].initial = false }) // we suppress unhandled rejections so they don't bubble up to the // unhandledRejection handler and crash the process. Cypress will // eventually take care of the rejection when the file is requested. // note that this does not work if attached to latestBundle.promise - // for some reason. it only works when attached after .tap ¯\_(ツ)_/¯ + // for some reason. it only works when attached after .finally ¯\_(ツ)_/¯ .suppressUnhandledRejections() } @@ -341,7 +353,7 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F // return the promise, which will resolve with the outputPath or reject // with any error encountered - return bundles[filePath] + return bundles[filePath].promise } } diff --git a/test/e2e/compilation.spec.js b/test/e2e/compilation.spec.js index 0aa1a39..1d1816f 100644 --- a/test/e2e/compilation.spec.js +++ b/test/e2e/compilation.spec.js @@ -104,7 +104,7 @@ describe('webpack preprocessor - e2e', () => { }) it('triggers rerun on syntax error', async () => { - const file = createFile({ shouldWatch: true }) + file = createFile({ shouldWatch: true }) await preprocessor()(file) @@ -114,6 +114,19 @@ describe('webpack preprocessor - e2e', () => { await retry(() => expect(_emit).calledWith('rerun')) }) + + it('does not call rerun on initial build, but on subsequent builds', async () => { + file = createFile({ shouldWatch: true }) + const _emit = sinon.spy(file, 'emit') + + await preprocessor()(file) + + expect(_emit).not.to.be.calledWith('rerun') + + await fs.outputFile(file.filePath, 'console.log()') + + await retry(() => expect(_emit).calledWith('rerun')) + }) }) function retry (fn, timeout = 1000) { diff --git a/test/unit/index.spec.js b/test/unit/index.spec.js index f6c7d61..e1790bd 100644 --- a/test/unit/index.spec.js +++ b/test/unit/index.spec.js @@ -2,6 +2,7 @@ const chai = require('chai') const mockery = require('mockery') +const Promise = require('bluebird') const sinon = require('sinon') const expect = chai.expect @@ -247,12 +248,21 @@ describe('webpack preprocessor', function () { }) }) - it('emits "rerun" when shouldWatch is true and there is an update', function () { + it('emits "rerun" when shouldWatch is true after there is an update', function () { this.file.shouldWatch = true this.compilerApi.watch.yields(null, this.statsApi) this.compilerApi.plugin.withArgs('compile').yields() - return this.run().then(() => { + return this.run() + .then(() => { + expect(this.file.emit).not.to.be.calledWith('rerun') + + this.compilerApi.plugin.withArgs('compile').yield() + this.compilerApi.watch.yield(null, this.statsApi) + + return Promise.delay(10) // give assertion time till next tick + }) + .then(() => { expect(this.file.emit).to.be.calledWith('rerun') }) })