From 7457eaf9e395f2e40b8910d0b71bf768564dc1b8 Mon Sep 17 00:00:00 2001 From: Monica Olejniczak Date: Thu, 1 Aug 2024 18:55:20 +1000 Subject: [PATCH] Add test setup for v3 --- .github/workflows/ci.yml | 5 +- .../integration-tests/test/BundleGraph.js | 4 +- packages/core/integration-tests/test/api.js | 14 +- packages/core/integration-tests/test/babel.js | 4 +- .../core/integration-tests/test/blob-url.js | 4 +- .../core/integration-tests/test/bundler.js | 10 +- packages/core/integration-tests/test/cache.js | 4 +- .../integration-tests/test/compressors.js | 4 +- .../integration-tests/test/config-merging.js | 4 +- .../integration-tests/test/contentHashing.js | 11 +- .../integration-tests/test/css-modules.js | 4 +- packages/core/integration-tests/test/css.js | 4 +- packages/core/integration-tests/test/elm.js | 6 +- .../core/integration-tests/test/encodedURI.js | 4 +- .../test/eslint-validation.js | 4 +- .../integration-tests/test/feature-flags.js | 17 +- packages/core/integration-tests/test/fs.js | 4 +- packages/core/integration-tests/test/glob.js | 4 +- .../core/integration-tests/test/globals.js | 11 +- packages/core/integration-tests/test/glsl.js | 4 +- .../core/integration-tests/test/graphql.js | 4 +- packages/core/integration-tests/test/hmr.js | 4 +- packages/core/integration-tests/test/html.js | 8 +- packages/core/integration-tests/test/image.js | 11 +- .../test/incremental-bundling.js | 4 +- .../integration-tests/test/javascript-v3.js | 6116 ------------- .../core/integration-tests/test/javascript.js | 8132 +++++++++-------- .../integration-tests/test/json-reporter.js | 4 +- .../core/integration-tests/test/kotlin.js | 2 +- .../integration-tests/test/lazy-compile.js | 4 +- packages/core/integration-tests/test/less.js | 8 +- .../integration-tests/test/library-bundler.js | 8 +- .../core/integration-tests/test/macros.js | 6 +- .../core/integration-tests/test/markdown.js | 8 +- packages/core/integration-tests/test/mdx.js | 4 +- .../test/metrics-reporter.js | 4 +- .../core/integration-tests/test/monorepos.js | 4 +- packages/core/integration-tests/test/namer.js | 4 +- .../integration-tests/test/output-formats.js | 4 +- .../core/integration-tests/test/packager.js | 4 +- .../integration-tests/test/parcel-link.js | 4 +- .../integration-tests/test/parcel-query.js | 4 +- .../core/integration-tests/test/parcel-v3.js | 87 +- .../core/integration-tests/test/parser.js | 8 +- .../core/integration-tests/test/plugin.js | 4 +- packages/core/integration-tests/test/pnp.js | 11 +- .../core/integration-tests/test/postcss.js | 4 +- .../core/integration-tests/test/posthtml.js | 4 +- packages/core/integration-tests/test/proxy.js | 4 +- packages/core/integration-tests/test/pug.js | 13 +- .../integration-tests/test/react-refresh.js | 4 +- .../test/registered-plugins.js | 19 +- .../core/integration-tests/test/reporters.js | 4 +- .../core/integration-tests/test/resolver.js | 14 +- packages/core/integration-tests/test/sass.js | 4 +- .../integration-tests/test/schema-jsonld.js | 11 +- .../integration-tests/test/scope-hoisting.js | 4 +- .../core/integration-tests/test/server.js | 4 +- .../core/integration-tests/test/sourcemaps.js | 4 +- .../core/integration-tests/test/stylus.js | 4 +- .../core/integration-tests/test/sugarss.js | 11 +- .../core/integration-tests/test/svg-react.js | 4 +- packages/core/integration-tests/test/svg.js | 11 +- .../test/symbol-propagation.js | 11 +- .../integration-tests/test/tailwind-tests.js | 4 +- .../core/integration-tests/test/tracing.js | 4 +- .../integration-tests/test/transpilation.js | 4 +- .../core/integration-tests/test/ts-types.js | 10 +- .../integration-tests/test/ts-validation.js | 4 +- .../integration-tests/test/typescript-tsc.js | 6 +- .../core/integration-tests/test/typescript.js | 8 +- packages/core/integration-tests/test/vue.js | 4 +- packages/core/integration-tests/test/wasm.js | 9 +- .../core/integration-tests/test/watcher.js | 4 +- .../integration-tests/test/webextension.js | 11 +- .../integration-tests/test/webmanifest.js | 11 +- .../core/integration-tests/test/workers.js | 12 +- .../core/integration-tests/test/worklets.js | 8 +- packages/core/integration-tests/test/xml.js | 10 +- packages/core/test-utils/src/utils.js | 118 + 80 files changed, 4868 insertions(+), 10080 deletions(-) delete mode 100644 packages/core/integration-tests/test/javascript-v3.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09406b0cac4..14cfac25dc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,11 +95,12 @@ jobs: packages/core/rust/*.node integration_tests: - name: Integration tests (${{ matrix.os }}, Node ${{ matrix.node }}) + name: Integration tests (${{ matrix.version == 'v3' && 'v3, ' || '' }}${{ matrix.os }}, Node ${{ matrix.node }}) strategy: matrix: node: [18, 20] os: [ubuntu-latest, macos-latest, windows-latest] + version: [v2, v3] # These tend to be quite flakey, so one failed instance shouldn't stop # others from potentially succeeding fail-fast: false @@ -123,6 +124,8 @@ jobs: - run: yarn build-native-release - run: yarn build - run: yarn test:integration-ci + env: + PARCEL_V3: ${{ matrix.version == 'v3' && 'true' || 'false' }} # Deployment steps taken from https://github.com/colinwilson/static-site-to-vercel/blob/master/.github/workflows/deploy-preview.yml repl_build: diff --git a/packages/core/integration-tests/test/BundleGraph.js b/packages/core/integration-tests/test/BundleGraph.js index c8f72037ba6..ec80a46514e 100644 --- a/packages/core/integration-tests/test/BundleGraph.js +++ b/packages/core/integration-tests/test/BundleGraph.js @@ -2,10 +2,10 @@ import assert from 'assert'; import path from 'path'; -import {bundle, fsFixture, overlayFS} from '@parcel/test-utils'; +import {bundle, describe, fsFixture, it, overlayFS} from '@parcel/test-utils'; import type {BundleGraph, BundleGroup, PackagedBundle} from '@parcel/types'; -describe('BundleGraph', () => { +describe.v2('BundleGraph', () => { it('can traverse assets across bundles and contexts', async () => { let b = await bundle( path.join(__dirname, '/integration/worker-shared/index.js'), diff --git a/packages/core/integration-tests/test/api.js b/packages/core/integration-tests/test/api.js index 00d37bcacfd..6a05ef3fe6e 100644 --- a/packages/core/integration-tests/test/api.js +++ b/packages/core/integration-tests/test/api.js @@ -2,17 +2,19 @@ import path from 'path'; import assert from 'assert'; import { - distDir, - bundle, assertBundles, + bundle, + describe, + distDir, + fsFixture, + it, outputFS, overlayFS, - fsFixture, } from '@parcel/test-utils'; import {PARCEL_VERSION} from '../../core/src/constants'; -describe('JS API', function () { +describe.v2('JS API', function () { it('should respect distEntry', async function () { const NAME = 'custom-name.js'; @@ -68,7 +70,7 @@ describe('JS API', function () { await fsFixture(overlayFS, dir)` index.js: export default 'Hi'; - + .parcelrc: { extends: "@parcel/config-default", @@ -81,7 +83,7 @@ describe('JS API', function () { } yarn.lock: - + reporter-plugin.js: import {Reporter} from '@parcel/plugin'; import path from 'node:path'; diff --git a/packages/core/integration-tests/test/babel.js b/packages/core/integration-tests/test/babel.js index 5be6871c581..333bdbf85f4 100644 --- a/packages/core/integration-tests/test/babel.js +++ b/packages/core/integration-tests/test/babel.js @@ -5,9 +5,11 @@ import path from 'path'; import { bundle, bundler, + describe, distDir, getNextBuild, inputFS as fs, + it, outputFS, removeDistDirectory, run, @@ -22,7 +24,7 @@ import {md} from '@parcel/diagnostic'; const parcelCli = require.resolve('parcel/src/bin.js'); const inputDir = path.join(__dirname, '/input'); -describe('babel', function () { +describe.v2('babel', function () { let subscription; beforeEach(async function () { // TODO maybe don't do this for all tests diff --git a/packages/core/integration-tests/test/blob-url.js b/packages/core/integration-tests/test/blob-url.js index 314b36a7a95..cf15ff453d9 100644 --- a/packages/core/integration-tests/test/blob-url.js +++ b/packages/core/integration-tests/test/blob-url.js @@ -2,7 +2,7 @@ import assert from 'assert'; import path from 'path'; -import {bundle, distDir, outputFS, run} from '@parcel/test-utils'; +import {bundle, describe, distDir, it, outputFS, run} from '@parcel/test-utils'; class Blob { data; @@ -18,7 +18,7 @@ const URL = { }, }; -describe('blob urls', () => { +describe.v2('blob urls', () => { it('should inline compiled content as a blob url with `blob-url:*` imports', async () => { let b = await bundle( path.join(__dirname, '/integration/blob-url/index.js'), diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index 1946e03cad2..88b5e305d4d 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -2,9 +2,11 @@ import path from 'path'; import assert from 'assert'; import Logger from '@parcel/logger'; import { - bundle, assertBundles, + bundle, + describe, findAsset, + it, overlayFS, fsFixture, run, @@ -12,7 +14,7 @@ import { import {hashString} from '@parcel/rust'; import {normalizePath} from '@parcel/utils'; -describe('bundler', function () { +describe.v2('bundler', function () { it('should not create shared bundles when a bundle is being reused and disableSharedBundles is enabled', async function () { await fsFixture(overlayFS, __dirname)` disable-shared-bundle-single-source @@ -1877,11 +1879,11 @@ describe('bundler', function () { index.html: - + style.css: @import "common.css"; body { color: red } - + common.css: .common { color: green } diff --git a/packages/core/integration-tests/test/cache.js b/packages/core/integration-tests/test/cache.js index df9133d76c4..e3fd55a7e87 100644 --- a/packages/core/integration-tests/test/cache.js +++ b/packages/core/integration-tests/test/cache.js @@ -7,6 +7,8 @@ import path from 'path'; import { assertBundles, bundler, + describe, + it, run, runBundle as runSingleBundle, overlayFS, @@ -117,7 +119,7 @@ async function testCache(update: UpdateFn | TestConfig, integration) { return b; } -describe('cache', function () { +describe.v2('cache', function () { before(async () => { await inputFS.rimraf(path.join(__dirname, 'input')); }); diff --git a/packages/core/integration-tests/test/compressors.js b/packages/core/integration-tests/test/compressors.js index 867cbe85b84..45308abb012 100644 --- a/packages/core/integration-tests/test/compressors.js +++ b/packages/core/integration-tests/test/compressors.js @@ -1,9 +1,9 @@ import assert from 'assert'; import path from 'path'; import zlib from 'zlib'; -import {bundle, outputFS, distDir} from '@parcel/test-utils'; +import {bundle, describe, it, outputFS, distDir} from '@parcel/test-utils'; -describe('compressors', function () { +describe.v2('compressors', function () { it('should not compress output with gzip and brotli in development', async function () { await bundle(path.join(__dirname, 'integration/compressors/index.js')); diff --git a/packages/core/integration-tests/test/config-merging.js b/packages/core/integration-tests/test/config-merging.js index 7ae55aabb2f..cf3ee0f7238 100644 --- a/packages/core/integration-tests/test/config-merging.js +++ b/packages/core/integration-tests/test/config-merging.js @@ -1,8 +1,8 @@ -import {bundle, run, outputFS} from '@parcel/test-utils'; +import {bundle, describe, it, run, outputFS} from '@parcel/test-utils'; import assert from 'assert'; import path from 'path'; -describe('config merging', function () { +describe.v2('config merging', function () { it('should merge incomplete config packages', async function () { let b = await bundle( path.join(__dirname, '/integration/config-merging/index.js'), diff --git a/packages/core/integration-tests/test/contentHashing.js b/packages/core/integration-tests/test/contentHashing.js index 88aacd6c6cc..0817d283102 100644 --- a/packages/core/integration-tests/test/contentHashing.js +++ b/packages/core/integration-tests/test/contentHashing.js @@ -1,6 +1,13 @@ import assert from 'assert'; import path from 'path'; -import {bundle as _bundle, overlayFS, outputFS, ncp} from '@parcel/test-utils'; +import { + bundle as _bundle, + describe, + it, + overlayFS, + outputFS, + ncp, +} from '@parcel/test-utils'; const distDir = path.join(__dirname, './dist'); @@ -14,7 +21,7 @@ function bundle(path) { }); } -describe('content hashing', function () { +describe.v2('content hashing', function () { beforeEach(async () => { await outputFS.rimraf(path.join(__dirname, '/input')); }); diff --git a/packages/core/integration-tests/test/css-modules.js b/packages/core/integration-tests/test/css-modules.js index 049d783148f..ce1152de26f 100644 --- a/packages/core/integration-tests/test/css-modules.js +++ b/packages/core/integration-tests/test/css-modules.js @@ -2,6 +2,8 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, runBundle, assertBundles, @@ -12,7 +14,7 @@ import { } from '@parcel/test-utils'; import postcss from 'postcss'; -describe('css modules', () => { +describe.v2('css modules', () => { it('should support transforming css modules (require)', async () => { let b = await bundle( path.join(__dirname, '/integration/postcss-modules-cjs/index.js'), diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index af691645025..8e40b74d46a 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -3,6 +3,8 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, assertBundles, distDir, @@ -11,7 +13,7 @@ import { outputFS, } from '@parcel/test-utils'; -describe('css', () => { +describe.v2('css', () => { afterEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/elm.js b/packages/core/integration-tests/test/elm.js index 269f1fd27a1..21da660006d 100644 --- a/packages/core/integration-tests/test/elm.js +++ b/packages/core/integration-tests/test/elm.js @@ -1,14 +1,16 @@ import assert from 'assert'; import path from 'path'; import { + assertBundles, bundle, + describe, distDir, - assertBundles, + it, run, outputFS, } from '@parcel/test-utils'; -describe('elm', function () { +describe.v2('elm', function () { it('should produce a basic Elm bundle', async function () { let b = await bundle(path.join(__dirname, '/integration/elm/index.js')); diff --git a/packages/core/integration-tests/test/encodedURI.js b/packages/core/integration-tests/test/encodedURI.js index d0c676be67c..06a623968d3 100644 --- a/packages/core/integration-tests/test/encodedURI.js +++ b/packages/core/integration-tests/test/encodedURI.js @@ -1,8 +1,8 @@ import assert from 'assert'; import path from 'path'; -import {bundle, outputFS, distDir} from '@parcel/test-utils'; +import {bundle, describe, it, outputFS, distDir} from '@parcel/test-utils'; -describe('encodedURI', function () { +describe.v2('encodedURI', function () { it('should support bundling files which names in encoded URI', async function () { await bundle(path.join(__dirname, '/integration/encodedURI/index.html')); diff --git a/packages/core/integration-tests/test/eslint-validation.js b/packages/core/integration-tests/test/eslint-validation.js index 09d936fb268..8f0895b0d24 100644 --- a/packages/core/integration-tests/test/eslint-validation.js +++ b/packages/core/integration-tests/test/eslint-validation.js @@ -1,14 +1,14 @@ // @flow import assert from 'assert'; import path from 'path'; -import {bundle} from '@parcel/test-utils'; +import {bundle, describe, it} from '@parcel/test-utils'; const config = path.join( __dirname, './integration/custom-configs/.parcelrc-eslint', ); -describe('eslint-validator', function () { +describe.v2('eslint-validator', function () { it('should throw validation error with eslint errors', async function () { let didThrow = false; let entry = path.join(__dirname, '/integration/eslint-error/index.js'); diff --git a/packages/core/integration-tests/test/feature-flags.js b/packages/core/integration-tests/test/feature-flags.js index e9ff1bdf0e8..9219aa67b41 100644 --- a/packages/core/integration-tests/test/feature-flags.js +++ b/packages/core/integration-tests/test/feature-flags.js @@ -1,9 +1,16 @@ import assert from 'assert'; import path from 'node:path'; import {rimraf} from 'rimraf'; -import {bundle, run, overlayFS, fsFixture} from '@parcel/test-utils'; - -describe('feature flags', () => { +import { + bundle, + describe, + it, + run, + overlayFS, + fsFixture, +} from '@parcel/test-utils'; + +describe.v2('feature flags', () => { let dir = path.join(__dirname, 'feature-flags-fixture'); beforeEach(async () => { await rimraf(dir); @@ -20,7 +27,7 @@ describe('feature flags', () => { index.js: module.exports = "MARKER"; - + .parcelrc: { extends: "@parcel/config-default", @@ -35,7 +42,7 @@ describe('feature flags', () => { transformers: { '*.js': ['./transformer-client.js', '...'] }, - } + } transformer.js: const {Transformer} = require('@parcel/plugin'); diff --git a/packages/core/integration-tests/test/fs.js b/packages/core/integration-tests/test/fs.js index f5ed788456c..17b2f211f67 100644 --- a/packages/core/integration-tests/test/fs.js +++ b/packages/core/integration-tests/test/fs.js @@ -6,6 +6,8 @@ import path from 'path'; import { assertBundles, bundle, + describe, + it, removeDistDirectory, run, overlayFS, @@ -13,7 +15,7 @@ import { distDir, } from '@parcel/test-utils'; -describe('fs', function () { +describe.v2('fs', function () { beforeEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/glob.js b/packages/core/integration-tests/test/glob.js index 50ad002c928..e5bd5dc8c32 100644 --- a/packages/core/integration-tests/test/glob.js +++ b/packages/core/integration-tests/test/glob.js @@ -3,6 +3,8 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, assertBundles, outputFS, @@ -10,7 +12,7 @@ import { } from '@parcel/test-utils'; import nullthrows from 'nullthrows'; -describe('glob', function () { +describe.v2('glob', function () { it('should require a glob of files', async function () { let b = await bundle(path.join(__dirname, '/integration/glob/index.js')); diff --git a/packages/core/integration-tests/test/globals.js b/packages/core/integration-tests/test/globals.js index 92821da5744..5cc71fc71f7 100644 --- a/packages/core/integration-tests/test/globals.js +++ b/packages/core/integration-tests/test/globals.js @@ -1,10 +1,17 @@ import assert from 'assert'; import path from 'path'; -import {bundle, fsFixture, overlayFS, run} from '@parcel/test-utils'; +import { + bundle, + describe, + fsFixture, + it, + overlayFS, + run, +} from '@parcel/test-utils'; import sinon from 'sinon'; -describe('globals', function () { +describe.v2('globals', function () { it('should support global alias syntax', async function () { let b = await bundle( path.join(__dirname, '/integration/global-alias/index.js'), diff --git a/packages/core/integration-tests/test/glsl.js b/packages/core/integration-tests/test/glsl.js index 42660b825ec..290e0b2342e 100644 --- a/packages/core/integration-tests/test/glsl.js +++ b/packages/core/integration-tests/test/glsl.js @@ -1,9 +1,9 @@ import assert from 'assert'; import path from 'path'; import fs from 'fs'; -import {bundle, run, normaliseNewlines} from '@parcel/test-utils'; +import {bundle, describe, it, run, normaliseNewlines} from '@parcel/test-utils'; -describe('glsl', function () { +describe.v2('glsl', function () { it('should support requiring GLSL files via glslify', async function () { let b = await bundle(path.join(__dirname, '/integration/glsl/index.js')); diff --git a/packages/core/integration-tests/test/graphql.js b/packages/core/integration-tests/test/graphql.js index dd0b6cde672..cced8fca79b 100644 --- a/packages/core/integration-tests/test/graphql.js +++ b/packages/core/integration-tests/test/graphql.js @@ -1,9 +1,9 @@ import assert from 'assert'; import path from 'path'; -import {bundle, run} from '@parcel/test-utils'; +import {bundle, describe, it, run} from '@parcel/test-utils'; import {parse, print} from 'graphql/language'; -describe('graphql', function () { +describe.v2('graphql', function () { it('should support requiring graphql files', async function () { let b = await bundle(path.join(__dirname, '/integration/graphql/index.js')); diff --git a/packages/core/integration-tests/test/hmr.js b/packages/core/integration-tests/test/hmr.js index 404b5022db2..42d320470e0 100644 --- a/packages/core/integration-tests/test/hmr.js +++ b/packages/core/integration-tests/test/hmr.js @@ -3,8 +3,10 @@ import assert from 'assert'; import path from 'path'; import { bundler, + describe, getNextBuild, getNextBuildSuccess, + it, ncp, outputFS, overlayFS, @@ -46,7 +48,7 @@ async function nextWSMessage(ws: WebSocket) { return json5.parse(await new Promise(resolve => ws.once('message', resolve))); } -describe('hmr', function () { +describe.v2('hmr', function () { let subscription, ws; async function testHMRClient( diff --git a/packages/core/integration-tests/test/html.js b/packages/core/integration-tests/test/html.js index aa9b044765b..77e82850bdd 100644 --- a/packages/core/integration-tests/test/html.js +++ b/packages/core/integration-tests/test/html.js @@ -1,11 +1,13 @@ import assert from 'assert'; import { + assertBundles, bundle, bundler, - assertBundles, - removeDistDirectory, + describe, + it, distDir, getNextBuild, + removeDistDirectory, run, inputFS, outputFS, @@ -14,7 +16,7 @@ import { } from '@parcel/test-utils'; import path from 'path'; -describe('html', function () { +describe.v2('html', function () { beforeEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/image.js b/packages/core/integration-tests/test/image.js index f2f51acfe57..e54db7e6752 100644 --- a/packages/core/integration-tests/test/image.js +++ b/packages/core/integration-tests/test/image.js @@ -1,10 +1,17 @@ import assert from 'assert'; -import {bundle, distDir, inputFS, outputFS} from '@parcel/test-utils'; +import { + bundle, + describe, + distDir, + inputFS, + it, + outputFS, +} from '@parcel/test-utils'; import exifReader from 'exif-reader'; import path from 'path'; import sharp from 'sharp'; -describe('image', function () { +describe.v2('image', function () { this.timeout(10000); it('Should be able to resize images', async () => { diff --git a/packages/core/integration-tests/test/incremental-bundling.js b/packages/core/integration-tests/test/incremental-bundling.js index 1c6c0914f0a..1a328cf6387 100644 --- a/packages/core/integration-tests/test/incremental-bundling.js +++ b/packages/core/integration-tests/test/incremental-bundling.js @@ -1,8 +1,10 @@ // @flow strict-local import { bundler, + describe, getNextBuildSuccess, inputFS, + it, overlayFS, run, fsFixture, @@ -17,7 +19,7 @@ import {type Asset} from '@parcel/types'; const CONFIG = Symbol.for('parcel-plugin-config'); let packageManager = new NodePackageManager(inputFS, '/'); -describe('incremental bundling', function () { +describe.v2('incremental bundling', function () { let defaultBundlerSpy, customBundlerSpy; let assertChangedAssets = (actual: number, expected: number) => { assert.equal( diff --git a/packages/core/integration-tests/test/javascript-v3.js b/packages/core/integration-tests/test/javascript-v3.js deleted file mode 100644 index 7c354d2e3ef..00000000000 --- a/packages/core/integration-tests/test/javascript-v3.js +++ /dev/null @@ -1,6116 +0,0 @@ -import assert from 'assert'; - -import path from 'path'; -import url from 'url'; -import { - assertDependencyWasExcluded, - bundle as baseBundle, - bundler as baseBundler, - findAsset, - findDependency, - getNextBuild, - run, - runBundle, - runBundles, - assertBundles, - ncp, - overlayFS, - removeDistDirectory, - distDir, - outputFS, - inputFS, - fsFixture, -} from '@parcel/test-utils'; -import {makeDeferredWithPromise, normalizePath} from '@parcel/utils'; -import vm from 'vm'; -import Logger from '@parcel/logger'; -import nullthrows from 'nullthrows'; -import {md} from '@parcel/diagnostic'; - -describe('javascript-v3', function () { - // don't retry parcel v3 tests - this.retries(0); - - beforeEach(async () => { - await removeDistDirectory(); - }); - - function bundle(entries, opts) { - let flaggedOpts = { - ...opts, - featureFlags: { - ...opts?.featureFlags, - parcelV3: true, - }, - }; - return baseBundle(entries, flaggedOpts); - } - - function bundler(entries, opts) { - let flaggedOpts = { - ...opts, - featureFlags: { - ...opts?.featureFlags, - parcelV3: true, - }, - }; - return baseBundler(entries, flaggedOpts); - } - - it('should produce a basic JS bundle with CommonJS requires', async function () { - let b = await bundle( - path.join(__dirname, '/integration/commonjs/index.js'), - ); - - // assert.equal(b.assets.size, 8); - // assert.equal(b.childBundles.size, 1); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support url: imports with CommonJS output', async function () { - let b = await bundle( - path.join(__dirname, '/integration/commonjs-import-url/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'esmodule-helpers.js'], - }, - { - type: 'txt', - assets: ['x.txt'], - }, - ]); - - let txtBundle = b.getBundles().find(b => b.type === 'txt').filePath; - - let output = await run(b); - assert.strictEqual(path.basename(output), path.basename(txtBundle)); - }); - - it.skip('should produce a basic JS bundle with ES6 imports', async function () { - let b = await bundle(path.join(__dirname, '/integration/es6/index.js')); - - // assert.equal(b.assets.size, 8); - // assert.equal(b.childBundles.size, 1); - - let output = await run(b); - assert.equal(typeof output, 'object'); - assert.equal(typeof output.default, 'function'); - assert.equal(output.default(), 3); - }); - - it.skip('should detect dependencies inserted by a prior transform', async () => { - let b = await bundle( - path.join(__dirname, '/integration/dependency-prior-transform/index.js'), - ); - - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath); - - assert(!contents.includes('import')); - }); - - it.skip('should ignore unused requires after process.env inlining', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-unused-require/index.js'), - { - env: {ABC: 'XYZ'}, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['index.js'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('unused')); - - let output = await run(b); - assert.strictEqual(output(), 'ok'); - }); - - it.skip('should produce a basic JS bundle with object rest spread support', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/object-rest-spread/object-rest-spread.js', - ), - ); - - // assert.equal(b.assets.size, 1); - - let output = await run(b); - assert.equal(typeof output, 'object'); - assert.equal(typeof output.default, 'function'); - - let res = output.default(); - assert.equal(res.y, 'a'); - assert.deepEqual(res.z, {y: 'a', b: 'b'}); - assert.deepEqual(res.ys, {b: 'b'}); - }); - - it.skip('should bundle node_modules for a browser environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/node_require_browser/main.js'), - ); - - assertBundles(b, [ - { - name: 'main.js', - assets: ['main.js', 'local.js', 'index.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should not bundle node_modules for a node environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/node_require/main.js'), - ); - - assertBundles(b, [ - { - name: 'main.js', - assets: ['main.js', 'local.js'], - }, - ]); - - await outputFS.mkdirp(path.join(distDir, 'node_modules/testmodule')); - await outputFS.writeFile( - path.join(distDir, 'node_modules/testmodule/index.js'), - 'exports.a = 5;', - ); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 7); - }); - - it.skip('should not bundle node_modules on --target=electron', async function () { - let b = await bundle( - path.join(__dirname, '/integration/node_require/main.js'), - { - target: 'electron', - }, - ); - - assertBundles(b, { - name: 'main.js', - assets: ['main.js', 'local.js'], - }); - - await outputFS.mkdirp(path.join(distDir, 'node_modules/testmodule')); - await outputFS.writeFile( - path.join(distDir, 'node_modules/testmodule/index.js'), - 'exports.a = 5;', - ); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 7); - }); - - it.skip('should preserve hashbangs in bundles and preserve executable file mode', async () => { - let fixturePath = path.join(__dirname, '/integration/node_hashbang'); - await bundle(path.join(fixturePath, 'main.js')); - - let mainPath = path.join(fixturePath, 'dist', 'node', 'main.js'); - let main = await outputFS.readFile(mainPath, 'utf8'); - assert.equal(main.lastIndexOf('#!/usr/bin/env node\n'), 0); - assert.equal( - (await outputFS.stat(mainPath)).mode, - (await inputFS.stat(path.join(fixturePath, 'main.js'))).mode, - ); - await outputFS.rimraf(path.join(fixturePath, 'dist')); - }); - - it.skip('should not preserve hashbangs in browser bundles', async () => { - let fixturePath = path.join(__dirname, '/integration/node_hashbang'); - await bundle(path.join(fixturePath, 'main.js')); - - let main = await outputFS.readFile( - path.join(fixturePath, 'dist', 'browser', 'main.js'), - 'utf8', - ); - assert(!main.includes('#!/usr/bin/env node\n')); - await outputFS.rimraf(path.join(fixturePath, 'dist')); - }); - - it.skip('should preserve hashbangs in scopehoisted bundles', async () => { - let fixturePath = path.join(__dirname, '/integration/node_hashbang'); - await bundle(path.join(__dirname, '/integration/node_hashbang/main.js'), { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }); - - let main = await outputFS.readFile( - path.join(fixturePath, 'dist', 'node', 'main.js'), - 'utf8', - ); - assert.equal(main.lastIndexOf('#!/usr/bin/env node\n'), 0); - await outputFS.rimraf(path.join(fixturePath, 'dist')); - }); - - it.skip('should bundle node_modules for a node environment if includeNodeModules is specified', async function () { - let b = await bundle( - path.join(__dirname, '/integration/include_node_modules/main.js'), - ); - - assertBundles(b, [ - { - name: 'main.js', - assets: ['main.js', 'local.js', 'index.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should bundle builtins for a browser environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/include_builtins-browser/main.js'), - ); - - assertBundles(b, [ - { - name: 'main.js', - assets: [ - '_empty.js', - 'browser.js', - 'esmodule-helpers.js', - 'index.js', - 'main.js', - ], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - let [fs, filepath] = output(); - assert.equal(filepath, path.posix.join('app', 'index.js')); - assert.equal(typeof fs, 'object'); - assert.deepEqual(Object.keys(fs), Object.keys({})); - }); - - it.skip('should not bundle builtins for a node environment if includeNodeModules is specified', async function () { - let b = await bundle( - path.join(__dirname, '/integration/include_builtins-node/main.js'), - ); - - assertBundles(b, [ - { - name: 'main.js', - assets: ['esmodule-helpers.js', 'main.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - let [fs, filepath] = output(); - assert.equal(filepath, path.join('app', 'index.js')); - assert.equal(typeof fs.readFile, 'function'); - }); - - it.skip('should bundle node_modules on --target=electron and --bundle-node-modules', async function () { - let b = await bundle( - path.join(__dirname, '/integration/node_require/main.js'), - { - target: 'electron', - bundleNodeModules: true, - }, - ); - - assertBundles(b, { - name: 'main.js', - assets: ['main.js', 'local.js', 'index.js'], - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should produce a JS bundle with default exports and no imports', async function () { - let b = await bundle( - path.join(__dirname, '/integration/es6-default-only/index.js'), - ); - - // assert.equal(b.assets.size, 1); - // assert.equal(b.childBundles.size, 1); - - let output = await run(b); - assert.equal(typeof output, 'object'); - assert.equal(typeof output.default, 'function'); - assert.equal(output.default(), 3); - }); - - it.skip('should split bundles when a dynamic import is used a browser environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/dynamic/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['local.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should prefetch bundles when declared as an import attribute statically', async function () { - let b = await bundle( - path.juoin(__dirname, '/integration/dynamic-static-prefetch/index.js'), - ); - - let output = await run(b); - let headChildren = await output.default; - - assert.strictEqual(headChildren.length, 4); - - assert.strictEqual(headChildren[1].tag, 'script'); - assert(headChildren[1].src.match(/async\..*\.js/)); - - assert.strictEqual(headChildren[2].tag, 'link'); - assert.strictEqual(headChildren[2].rel, 'prefetch'); - assert.strictEqual(headChildren[2].as, 'script'); - assert(headChildren[2].href.match(/prefetched\..*\.js/)); - - assert.strictEqual(headChildren[3].tag, 'link'); - assert.strictEqual(headChildren[3].rel, 'prefetch'); - assert.strictEqual(headChildren[3].as, 'style'); - assert(headChildren[3].href.match(/prefetched\..*\.css/)); - }); - - it.skip('should load additional links that were prefetched', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/dynamic-static-prefetch-loaded/index.js', - ), - ); - - let output = await run(b); - let outputReturn = await output.default; - await outputReturn.loadDependency(); - - let headChildren = outputReturn.children; - assert.equal(headChildren.length, 7); - let cssBundles = headChildren.filter(child => - child.href?.match(/prefetched-loaded\..*\.css/), - ); - assert.equal(cssBundles.length, 2); - - assert(cssBundles[0].tag === 'link'); - assert(cssBundles[0].rel === 'prefetch'); - assert(cssBundles[0].as === 'style'); - assert(cssBundles[0].href.match(/prefetched-loaded\..*\.css/)); - - assert(cssBundles[1].tag === 'link'); - assert(cssBundles[1].rel === 'stylesheet'); - assert(cssBundles[1].href.match(/prefetched-loaded\..*\.css/)); - }); - - it.skip('should preload bundles when declared as an import attribute statically', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-static-preload/index.js'), - ); - - let output = await run(b); - let headChildren = await output.default; - - assert(headChildren.length === 4); - - assert(headChildren[2].tag === 'link'); - assert(headChildren[2].rel === 'preload'); - assert(headChildren[2].as === 'script'); - assert(headChildren[2].href.match(/preloaded\..*\.js/)); - - assert(headChildren[3].tag === 'link'); - assert(headChildren[3].rel === 'preload'); - assert(headChildren[3].as === 'style'); - assert(headChildren[3].href.match(/preloaded\..*\.css/)); - }); - - // TODO: Implement when we can evaluate bundles against esmodule targets - it.skip( - 'targetting esmodule, should modulepreload bundles when declared as an import attribute statically', - ); - - it.skip('should remove import attributes', async () => { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-import-attributes/index.js'), - ); - - let mainBundle = b.getBundles()[0]; - let mainBundleContent = await outputFS.readFile( - mainBundle.filePath, - 'utf8', - ); - assert(!mainBundleContent.includes('foo:')); - }); - - it.skip('should split bundles when a dynamic import is used with a node environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-node/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should split bundles when a dynamic import is used with an electron-main environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-electron-main/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should split bundles when a dynamic import is used with an electron-renderer environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-electron-renderer/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should load dynamic bundle when entry is in a subdirectory', async function () { - let bu = await bundler( - path.join( - __dirname, - '/integration/dynamic-subdirectory/subdirectory/index.js', - ), - { - target: 'browser', - }, - ); - // Set the rootDir to make sure subdirectory is preserved - bu.options.rootDir = path.join( - __dirname, - '/integration/dynamic-subdirectory', - ); - let b = await bu.bundle(); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - // TODO: re-enable when this actually works - it.skip('Should not run parcel over external modules', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-external/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['esmodule-helpers.js', 'index.js'], - }, - ]); - }); - - it.skip('dynamic imports loaded as high-priority scripts when not all engines support esmodules natively', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-imports-high-prio/index.js'), - { - defaultTargetOptions: { - engines: { - browsers: 'IE 11', - }, - }, - }, - ); - - let output = await run(b); - let headChildren = await output.default; - - assert(headChildren[0].tag === 'link'); - assert(headChildren[0].rel === 'preload'); - assert(headChildren[0].as === 'script'); - - assert(headChildren[1].tag === 'script'); - assert(headChildren[1].src.match(/async\..*\.js/)); - - assert(headChildren[0].href === headChildren[1].src); - }); - - it.skip('should deduplicate and remove an unnecessary async bundle when it contains a cyclic reference to its entry', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/deduplicate-from-async-cyclic-bundle-entry/index.js', - ), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bar.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'foo.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.deepEqual(await Promise.all((await run(b)).default), [5, 4]); - }); - - it.skip('does not create bundles for dynamic imports when assets are available up the graph', async () => { - let b = await bundle( - path.join(__dirname, '/integration/internalize-no-bundle-split/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bar.js', 'foo.js', 'esmodule-helpers.js'], - }, - ]); - - assert.deepEqual(await (await run(b)).default, [3, 3]); - }); - - it.skip('should dynamic import files which import raw files', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-references-raw/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['local.js', 'esmodule-helpers.js'], - }, - { - assets: ['test.txt'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should return all exports as an object when using ES modules', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-esm/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - { - assets: ['local.js'], - }, - ]); - - let output = (await run(b)).default; - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it.skip('should duplicate small modules across multiple bundles', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-common-small/index.js'), - ); - - assertBundles(b, [ - { - assets: ['a.js', 'common.js', 'common-dep.js'], - }, - { - assets: ['b.js', 'common.js', 'common-dep.js'], - }, - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 7); - }); - - it.skip('should create a separate bundle for large modules shared between bundles', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-common-large/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - - assertBundles(b, [ - { - assets: ['a.js'], - }, - { - assets: ['b.js'], - }, - { - name: 'index.js', - assets: [ - 'index.js', - 'c.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['common.js', 'lodash.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 7); - }); - - it.skip('should not duplicate a module which is already in a parent bundle', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-hoist-dup/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'common.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['a.js'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 5); - }); - - it.skip('should duplicate an asset if it is not present in every parent bundle', async function () { - let b = await bundle( - ['a.js', 'b.js'].map(entry => - path.join(__dirname, 'integration/dynamic-hoist-no-dedupe', entry), - ), - ); - assertBundles(b, [ - { - assets: ['c.js', 'common.js', 'esmodule-helpers.js'], - }, - { - name: 'b.js', - assets: ['b.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - name: 'a.js', - assets: [ - 'a.js', - 'bundle-url.js', - 'common.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - ]); - }); - - it.skip('should duplicate an asset if it is not available in all possible ancestries', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/dynamic-hoist-no-dedupe-ancestry/index.js', - ), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - { - assets: ['a.js', 'common.js'], - }, - { - assets: ['b.js'], - }, - { - assets: ['c.js'], - }, - { - assets: ['d.js', 'common.js'], - }, - ]); - - let {default: promise} = await run(b); - assert.equal(await promise, 42); - }); - - it.skip('should support shared modules with async imports', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-hoist-deep/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - { - assets: ['a.js', 'c.js'], - }, - { - assets: ['b.js', 'c.js'], - }, - { - assets: ['1.js'], - }, - ]); - - let {default: promise} = await run(b); - assert.ok(await promise); - }); - - it.skip('should support requiring JSON files', async function () { - let b = await bundle(path.join(__dirname, '/integration/json/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.json'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support requiring JSON5 files', async function () { - let b = await bundle(path.join(__dirname, '/integration/json5/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.json5'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support importing a URL to a raw asset', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); - let stats = await outputFS.stat( - path.join(distDir, url.parse(output()).pathname), - ); - assert.equal(stats.size, 9); - }); - - it.skip('should support referencing a raw asset with static URL and import.meta.url', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw-import-meta-url/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'esmodule-helpers.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('import.meta.url')); - - let output = await run(b); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); - let stats = await outputFS.stat( - path.join(distDir, output.default.pathname), - ); - assert.equal(stats.size, 9); - }); - - it.skip('should support referencing a raw asset with static URL and CJS __filename', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw-import-meta-url/cjs.js'), - ); - - assertBundles(b, [ - { - name: 'cjs.js', - assets: ['cjs.js', 'bundle-url.js', 'esmodule-helpers.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('import.meta.url')); - - let output = await run(b); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); - let stats = await outputFS.stat( - path.join(distDir, output.default.pathname), - ); - assert.equal(stats.size, 9); - }); - - it.skip('should ignore new URL and import.meta.url with local binding', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/import-raw-import-meta-url/local-url.js', - ), - ); - - assertBundles(b, [ - { - name: 'local-url.js', - assets: ['esmodule-helpers.js', 'local-url.js'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(contents.includes('"file:///local-url.js"')); - }); - - it.skip('should throw a codeframe for a missing raw asset with static URL and import.meta.url', async function () { - let fixture = path.join( - __dirname, - 'integration/import-raw-import-meta-url/missing.js', - ); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects(() => bundle(fixture), { - name: 'BuildError', - diagnostics: [ - { - codeFrames: [ - { - filePath: fixture, - code, - codeHighlights: [ - { - message: undefined, - end: { - column: 36, - line: 1, - }, - start: { - column: 24, - line: 1, - }, - }, - ], - }, - ], - message: "Failed to resolve 'invalid.txt' from './missing.js'", - origin: '@parcel/core', - }, - { - hints: [], - message: "Cannot load file './invalid.txt' in './'.", - origin: '@parcel/resolver-default', - }, - ], - }); - }); - - it.skip('should support importing a URL to a large raw asset', async function () { - // 6 megabytes, which exceeds the threshold in summarizeRequest for buffering - // entire contents into memory and should stream content instead - let assetSizeBytes = 6000000; - - let distDir = path.join(outputFS.cwd(), '/dist'); - let fixtureDir = path.join(__dirname, '/integration/import-raw'); - let inputDir = path.join(__dirname, 'input'); - - await ncp(fixtureDir, inputDir); - await outputFS.writeFile( - path.join(inputDir, 'test.txt'), - Buffer.alloc(assetSizeBytes), - ); - - let b = await bundle(path.join(inputDir, 'index.js'), { - inputFS: overlayFS, - defaultTargetOptions: { - distDir, - }, - }); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); - let stats = await outputFS.stat( - path.join(distDir, url.parse(output()).pathname), - ); - assert.equal(stats.size, assetSizeBytes); - }); - - it.skip('should minify JS in production mode', async function () { - let b = await bundle(path.join(__dirname, '/integration/uglify/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - - let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(!js.includes('local.a')); - }); - - it.skip('should use terser config', async function () { - await bundle(path.join(__dirname, '/integration/terser-config/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); - - let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(!js.includes('console.log')); - assert(!js.includes('// This is a comment')); - }); - - it.skip('should insert global variables when needed', async function () { - let b = await bundle(path.join(__dirname, '/integration/globals/index.js')); - - let output = await run(b); - assert.deepEqual(output(), { - dir: 'integration/globals', - file: 'integration/globals/index.js', - buf: Buffer.from('browser').toString('base64'), - global: true, - }); - }); - - it.skip('should replace __dirname and __filename with path relative to asset.filePath', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); - - let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/other")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/sub")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', - ), - ); - let f = await run(b); - let output = f(); - assert.equal(output.data, 'hello'); - assert.equal(output.other, 'hello'); - assert.equal( - output.firstDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/data'), - ); - assert.equal( - output.secondDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/other-data'), - ); - assert.equal( - output.firstFilenameTest, - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); - assert.equal( - output.secondFilenameTest, - path.join( - __dirname, - '/integration/env-node-replacements/index.js?query-string=test', - ), - ); - assert.equal( - output.sub.dirname, - path.join(__dirname, '/integration/env-node-replacements/sub'), - ); - assert.equal( - output.sub.filename, - path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), - ); - }); - - it.skip('should replace __dirname and __filename with path relative to asset.filePath with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node-replacements/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: false, - }, - }, - ); - - let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/other")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', - ), - ); - let f = await run(b); - let output = f(); - assert.equal(output.data, 'hello'); - assert.equal(output.other, 'hello'); - assert.equal( - output.firstDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/data'), - ); - assert.equal( - output.secondDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/other-data'), - ); - assert.equal( - output.firstFilenameTest, - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); - assert.equal( - output.secondFilenameTest, - path.join( - __dirname, - '/integration/env-node-replacements/index.js?query-string=test', - ), - ); - assert.equal( - output.sub.dirname, - path.join(__dirname, '/integration/env-node-replacements/sub'), - ); - assert.equal( - output.sub.filename, - path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), - ); - }); - - it.skip('should work when multiple files use globals with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals/multiple.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: false, - }, - }, - ); - - let output = await run(b); - assert.deepEqual(output, { - file: 'integration/globals/multiple.js', - other: 'integration/globals/index.js', - }); - }); - - it.skip('should not insert global variables when used in a module specifier', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals-module-specifier/a.js'), - ); - - assertBundles(b, [ - { - assets: ['a.js', 'b.js', 'c.js', 'esmodule-helpers.js'], - }, - ]); - - let output = await run(b); - assert.deepEqual(output, 1234); - }); - - it.skip('should not insert global variables in dead branches', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals-unused/a.js'), - ); - - assertBundles(b, [ - { - assets: ['a.js'], - }, - ]); - - let output = await run(b); - assert.deepEqual(output, 'foo'); - }); - - it.skip('should handle re-declaration of the global constant', async function () { - let b = await bundle( - path.join(__dirname, '/integration/global-redeclare/index.js'), - ); - - let output = await run(b); - assert.deepEqual(output(), false); - }); - - it.skip('should insert environment variables inserted by a prior transform', async () => { - let b = await bundle( - path.join(__dirname, '/integration/env-prior-transform/index.js'), - ); - - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - - assert(!contents.includes('process.env')); - assert.equal(await run(b), 'test'); - }); - - it.skip('should not insert environment variables in node environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node/index.js'), - ); - - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); - - it.skip('should not replace process.env.hasOwnProperty with undefined', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-hasOwnProperty/index.js'), - ); - - let output = await run(b); - assert.strictEqual(output, false); - }); - - it.skip('should not insert environment variables in electron-main environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - targets: { - main: { - context: 'electron-main', - distDir: path.join(__dirname, '/integration/env/dist.js'), - }, - }, - }); - - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); - - it.skip('should not insert environment variables in electron-renderer environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - targets: { - main: { - context: 'electron-renderer', - distDir: path.join(__dirname, '/integration/env/dist.js'), - }, - }, - }); - - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); - - it.skip('should inline NODE_ENV environment variable in browser environment even if disabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-nodeenv/index.js'), - { - env: { - FOO: 'abc', - }, - }, - ); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'test:undefined'); - }); - - it.skip('should not insert environment variables in browser environment if disabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-disabled/index.js'), - { - env: {FOOBAR: 'abc'}, - }, - ); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'undefined:undefined:undefined'); - }); - - it.skip('should only insert environment variables in browser environment matching the glob', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-disabled-glob/index.js'), - { - env: {A_1: 'abc', B_1: 'def', B_2: 'ghi'}, - }, - ); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'undefined:def:ghi'); - }); - - it.skip('should be able to inline environment variables in browser environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - env: {NODE_ENV: 'abc'}, - }); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'abc:abc'); - }); - - it.skip("should insert the user's NODE_ENV as process.env.NODE_ENV if passed", async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - env: { - NODE_ENV: 'production', - }, - }); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'production:production'); - }); - - it.skip('should not inline computed accesses to process.env', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-computed/index.js'), - { - env: {ABC: 'abc'}, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(contents.includes('process.env')); - - let output = await run(b); - assert.strictEqual(output, undefined); - }); - - it.skip('should inline computed accesses with string literals to process.env', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-computed-string/index.js'), - { - env: {ABC: 'XYZ'}, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); - - let output = await run(b); - assert.strictEqual(output, 'XYZ'); - }); - - it.skip('should inline environment variables when destructured in a variable declaration', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-destructuring/index.js'), - { - env: {TEST: 'XYZ'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', - }, - }, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); - - let output = await run(b); - assert.deepEqual(output, { - env: {}, - NODE_ENV: 'test', - renamed: 'XYZ', - computed: undefined, - fallback: 'yo', - rest: {}, - other: 'hi', - }); - }); - - it.skip('should inline environment variables when destructured in an assignment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-destructuring/assign.js'), - { - env: {TEST: 'XYZ'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', - }, - }, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); - - let output = await run(b); - assert.deepEqual(output, { - env: {}, - NODE_ENV: 'test', - renamed: 'XYZ', - computed: undefined, - fallback: 'yo', - rest: {}, - result: {}, - }); - }); - - it.skip('should inline environment variables with in binary expression whose right branch is process.env and left branch is string literal', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-binary-in-expression/index.js'), - { - env: {ABC: 'any'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', - }, - }, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); - - let output = await run(b); - assert.deepEqual(output, { - existVar: 'correct', - notExistVar: 'correct', - }); - }); - - it.skip('should insert environment variables from a file', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file/index.js'), - ); - - // Make sure dotenv doesn't leak its values into the main process's env - assert(process.env.FOO == null); - - let output = await run(b); - assert.equal(output, 'bartest'); - }); - - it.skip("should insert environment variables matching the user's NODE_ENV if passed", async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file/index.js'), - {env: {NODE_ENV: 'production'}}, - ); - - let output = await run(b); - assert.equal(output, 'productiontest'); - }); - - it.skip('should overwrite environment variables from a file if passed', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file/index.js'), - {env: {BAR: 'baz'}}, - ); - - let output = await run(b); - assert.equal(output, 'barbaz'); - }); - - it.skip('should insert environment variables from a file even if entry file is specified with source value in package.json', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file-with-package-source'), - ); - - let output = await run(b); - assert.equal(output, 'bartest'); - }); - - it.skip('should error on process.env mutations', async function () { - let filePath = path.join(__dirname, '/integration/env-mutate/index.js'); - await assert.rejects(bundle(filePath), { - diagnostics: [ - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 1, - }, - end: { - line: 1, - column: 29, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath, - codeHighlights: [ - { - message: undefined, - start: { - line: 2, - column: 1, - }, - end: { - line: 2, - column: 30, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath, - codeHighlights: [ - { - message: undefined, - start: { - line: 3, - column: 1, - }, - end: { - line: 3, - column: 28, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath, - codeHighlights: [ - { - message: undefined, - start: { - line: 4, - column: 1, - }, - end: { - line: 4, - column: 23, - }, - }, - ], - }, - ], - }, - ], - }); - }); - - it.skip('should warn on process.env mutations in node_modules', async function () { - let logs = []; - let disposable = Logger.onLog(d => { - if (d.level !== 'verbose') { - logs.push(d); - } - }); - let b = await bundle( - path.join(__dirname, '/integration/env-mutate/warn.js'), - ); - disposable.dispose(); - - assert.deepEqual(logs, [ - { - type: 'log', - level: 'warn', - diagnostics: [ - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 8, - }, - end: { - line: 1, - column: 36, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 2, - column: 8, - }, - end: { - line: 2, - column: 35, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 3, - column: 8, - }, - end: { - line: 3, - column: 30, - }, - }, - ], - }, - ], - }, - ], - }, - ]); - - let output = []; - await run(b, { - output(o) { - output.push(o); - }, - }); - assert.deepEqual(output, ['foo', true, undefined]); - }); - - it.skip('should replace process.browser for target browser', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'browser', - distDir: path.join(__dirname, '/integration/process/dist.js'), - }, - }, - }, - ); - - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') === -1); - assert.equal(output(), true); - }); - - it.skip('should not touch process.browser for target node', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'node', - distDir: path.join(__dirname, '/integration/process/dist.js'), - }, - }, - }, - ); - - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') !== -1); - assert.equal(output(), false); - }); - - it.skip('should not touch process.browser for target electron-main', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'electron-main', - distDir: path.join(__dirname, '/integration/process/dist.js'), - }, - }, - }, - ); - - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') !== -1); - assert.equal(output(), false); - }); - - it.skip('should replace process.browser for target electron-renderer', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'electron-renderer', - distDir: path.join(__dirname, '/integration/process/dist.js'), - }, - }, - }, - ); - - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') === -1); - assert.equal(output(), true); - // Running the bundled code has the side effect of setting process.browser = true, which can mess - // up the instantiation of typescript.sys within validator-typescript, so we want to reset it. - process.browser = undefined; - }); - - it.skip('should support adding implicit dependencies', async function () { - let b = await bundle(path.join(__dirname, '/integration/json/index.js'), { - delegate: { - getImplicitDependencies(asset) { - if (asset.basename === 'index.js') { - return [{name: '../css/index.css'}]; - } - }, - }, - }); - - assertBundles(b, { - name: 'index.js', - assets: ['index.js', 'local.json', 'index.css'], - childBundles: [ - { - type: 'css', - assets: ['index.css'], - }, - { - type: 'map', - }, - ], - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support requiring YAML files', async function () { - let b = await bundle(path.join(__dirname, '/integration/yaml/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.yaml'], - childBundles: [ - { - type: 'map', - }, - ], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support requiring TOML files', async function () { - let b = await bundle(path.join(__dirname, '/integration/toml/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.toml'], - childBundles: [ - { - type: 'map', - }, - ], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should support requiring CoffeeScript files', async function () { - let b = await bundle(path.join(__dirname, '/integration/coffee/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.coffee'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it.skip('should resolve the browser field before main', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/browser.js'), - ); - - assertBundles(b, [ - { - name: 'browser.js', - assets: ['browser.js', 'browser-module.js', 'esmodule-helpers.js'], - }, - ]); - - let output = await run(b); - - assert.equal(typeof output.test, 'function'); - assert.equal(output.test(), 'pkg-browser'); - }); - - it.skip('should exclude resolving specifiers that map to false in the browser field in browser builds', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/resolve-entries/pkg-ignore-browser/index.js', - ), - { - targets: ['browsers'], - }, - ); - - assert.deepEqual(await run(b), {}); - }); - - it.skip('should not exclude resolving specifiers that map to false in the browser field in node builds', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/resolve-entries/pkg-ignore-browser/index.js', - ), - { - targets: ['node'], - }, - ); - - assert.equal(await run(b), 'this should only exist in non-browser builds'); - }); - - it.skip('should not resolve the browser field for --target=node', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/browser.js'), - { - target: 'node', - }, - ); - - assertBundles(b, { - name: 'browser.js', - assets: ['browser.js', 'node-module.js'], - childBundles: [ - { - type: 'map', - }, - ], - }); - - let output = await run(b); - - assert.equal(typeof output.test, 'function'); - assert.equal(output.test(), 'pkg-main'); - }); - - it.skip('should resolve advanced browser resolution', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/browser-multiple.js'), - ); - - assertBundles(b, { - name: 'browser-multiple.js', - assets: [ - 'browser-multiple.js', - 'projected-browser.js', - 'browser-entry.js', - ], - childBundles: [ - { - type: 'map', - }, - ], - }); - - let {test: output} = await run(b); - - assert.equal(typeof output.projected.test, 'function'); - assert.equal(typeof output.entry.test, 'function'); - assert.equal(output.projected.test(), 'pkg-browser-multiple'); - assert.equal(output.entry.test(), 'pkg-browser-multiple browser-entry'); - }); - - it.skip('should not resolve advanced browser resolution with --target=node', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/browser-multiple.js'), - { - target: 'node', - }, - ); - - assertBundles(b, { - name: 'browser-multiple.js', - assets: ['browser-multiple.js', 'node-entry.js', 'projected.js'], - childBundles: [ - { - type: 'map', - }, - ], - }); - - let {test: output} = await run(b); - - assert.equal(typeof output.projected.test, 'function'); - assert.equal(typeof output.entry.test, 'function'); - assert.equal(output.projected.test(), 'pkg-main-multiple'); - assert.equal(output.entry.test(), 'pkg-browser-multiple main-entry'); - }); - - it.skip('should resolve the module field before main if scope-hoisting is enabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/module-field.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - name: 'module-field.js', - assets: ['module-field.js', 'es6.module.js'], - }, - ]); - - let output = await run(b); - - assert.equal(typeof output.test, 'function'); - assert.equal(output.test(), 'pkg-es6-module'); - }); - - it.skip('should resolve the module field before main if scope-hoisting is enabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/both-fields.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - name: 'both-fields.js', - assets: ['both-fields.js', 'es6.module.js'], - }, - ]); - - let output = await run(b); - - assert.equal(typeof output.test, 'function'); - assert.equal(output.test(), 'pkg-es6-module'); - }); - - it.skip('should resolve the main field', async function () { - let b = await bundle( - path.join(__dirname, '/integration/resolve-entries/main-field.js'), - ); - - assertBundles(b, [ - { - name: 'main-field.js', - assets: ['main-field.js', 'main.js', 'esmodule-helpers.js'], - }, - ]); - - let output = await run(b); - - assert.equal(typeof output.test, 'function'); - assert.equal(output.test(), 'pkg-main-module'); - }); - - it.skip('should minify JSON files', async function () { - let b = await bundle( - path.join(__dirname, '/integration/uglify-json/index.json'), - { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }, - ); - - let json = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(json.includes('{"test":"test"}')); - - let output = await run(b); - assert.deepEqual(output, {test: 'test'}); - }); - - it.skip('should minify JSON5 files', async function () { - let b = await bundle( - path.join(__dirname, '/integration/uglify-json5/index.json5'), - { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }, - ); - - let json = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(json.includes('{"test":"test"}')); - - let output = await run(b); - assert.deepEqual(output, {test: 'test'}); - }); - - it.skip('should minify YAML for production', async function () { - let b = await bundle(path.join(__dirname, '/integration/yaml/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - - let json = await outputFS.readFile('dist/index.js', 'utf8'); - assert(json.includes('{a:1,b:{c:2}}')); - }); - - it.skip('should minify TOML for production', async function () { - let b = await bundle(path.join(__dirname, '/integration/toml/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - - let json = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(json.includes('{a:1,b:{c:2}}')); - }); - - it.skip('should support optional dependencies in try...catch blocks', async function () { - let b = await bundle( - path.join(__dirname, '/integration/optional-dep/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - ]); - - let output = await run(b); - - assert.equal(Object.getPrototypeOf(output).constructor.name, 'Error'); - assert( - /Cannot find module ['"]optional-dep['"]/.test(output.message), - 'Should set correct error message', - ); - assert.equal(output.code, 'MODULE_NOT_FOUND'); - }); - - it.skip('should support excluding dependencies in falsy branches', async function () { - let b = await bundle( - path.join(__dirname, '/integration/falsy-dep/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'true-alternate.js', 'true-consequent.js'], - }, - ]); - - let output = await run(b); - assert.equal(output, 2); - }); - - it.skip('should not autoinstall if resolve failed on installed module', async function () { - let error; - try { - await bundle( - path.join( - __dirname, - '/integration/dont-autoinstall-resolve-fails/index.js', - ), - ); - } catch (err) { - error = err; - } - assert.equal( - error.message, - `Cannot resolve dependency 'vue/thisDoesNotExist'`, - ); - assert.equal(error.code, 'MODULE_NOT_FOUND'); - }); - - it.skip('should not autoinstall if resolve failed on aliased module', async function () { - let error; - try { - await bundle( - path.join( - __dirname, - '/integration/dont-autoinstall-resolve-alias-fails/index.js', - ), - ); - } catch (err) { - error = err; - } - assert.equal( - error.message, - `Cannot resolve dependency 'aliasVue/thisDoesNotExist'`, - ); - assert.equal(error.code, 'MODULE_NOT_FOUND'); - }); - - it.skip('should ignore require if it is defined in the scope', async function () { - let b = await bundle( - path.join(__dirname, '/integration/require-scope/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - ]); - - let output = await run(b); - - assert.equal(typeof output.test, 'object'); - - let failed = Object.keys(output.test).some( - key => output.test[key] !== 'test passed', - ); - - assert.equal(failed, false); - }); - - it.skip('should expose to CommonJS entry point', async function () { - let b = await bundle( - path.join(__dirname, '/integration/entry-point/index.js'), - ); - - let module = {}; - await run(b, {module, exports: {}}); - assert.equal(module.exports(), 'Test!'); - }); - - it.skip('should expose to RequireJS entry point', async function () { - let b = await bundle( - path.join(__dirname, '/integration/entry-point/index.js'), - ); - let test; - const mockDefine = function (f) { - test = f(); - }; - mockDefine.amd = true; - - await run(b, {define: mockDefine, module: undefined}); - assert.equal(test(), 'Test!'); - }); - - it.skip('should expose variable with --browser-global', async function () { - let b = await bundle( - path.join(__dirname, '/integration/entry-point/index.js'), - { - global: 'testing', - }, - ); - - const ctx = await run(b, {module: undefined}, {require: false}); - assert.equal(ctx.window.testing(), 'Test!'); - }); - - it.skip('should set `define` to undefined so AMD checks in UMD modules do not pass', async function () { - let b = await bundle( - path.join(__dirname, '/integration/define-amd/index.js'), - ); - let test; - const mockDefine = function (f) { - test = f(); - }; - mockDefine.amd = true; - - await run(b, {define: mockDefine, module: undefined}); - assert.equal(test, 2); - }); - - it.skip('should package successfully with comments on last line', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - ); - - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); - - it.skip('should package successfully with comments on last line and minification', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - ); - - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); - - it.skip('should package successfully with comments on last line and scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); - - it.skip('should package successfully with comments on last line, scope hoisting and minification', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - { - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: true, - }, - }, - ); - - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); - - it.skip('should not replace toplevel this with undefined in CommonJS without scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-commonjs/a.js'), - ); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [{foo: 2}, 1234]); - }); - - it.skip('should not replace toplevel this with undefined in CommonJS when scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-commonjs/a.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [{foo: 2}, 1234]); - }); - - it.skip('should replace toplevel this with undefined in ESM without scope-hoisting', async function () { - let b = await bundle(path.join(__dirname, '/integration/js-this-es6/a.js')); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [undefined, 1234]); - }); - - it.skip('should replace toplevel this with undefined in ESM when scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-es6/a.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [undefined, 1234]); - }); - - it.skip('should not dedupe imports with different contents', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-different-contents/index.js`), - { - hmr: false, // enable asset dedupe in JSPackager - }, - ); - - let module = await run(b); - assert.equal(module.default, 'Hello World!'); - }); - - it.skip('should not dedupe imports with same content but different absolute dependency paths', async function () { - let b = await bundle( - path.join( - __dirname, - `/integration/js-same-contents-different-dependencies/index.js`, - ), - { - hmr: false, // enable asset dedupe in JSPackager - }, - ); - - let module = await run(b); - assert.equal(module.default, 'Hello World!'); - }); - - it.skip('should dedupe imports with same content and same dependency paths', async function () { - let b = await bundle( - path.join( - __dirname, - `/integration/js-same-contents-same-dependencies/index.js`, - ), - { - hmr: false, // enable asset dedupe in JSPackager - }, - ); - const {rootDir} = b.entryAsset.options; - const writtenAssets = Array.from(b.offsets.keys()).map(asset => asset.name); - assert.equal(writtenAssets.length, 2); - assert(writtenAssets.includes(path.join(rootDir, 'index.js'))); - assert( - writtenAssets.includes(path.join(rootDir, 'hello1.js')) || - writtenAssets.includes(path.join(rootDir, 'hello2.js')), - ); - assert( - !( - writtenAssets.includes(path.join(rootDir, 'hello1.js')) && - writtenAssets.includes(path.join(rootDir, 'hello2.js')) - ), - ); - - let module = await run(b); - assert.equal(module.default, 'Hello Hello!'); - }); - - it.skip('should not dedupe assets that exist in more than one bundle', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-dedup-hoist/index.js`), - { - hmr: false, // enable asset dedupe in JSPackager - }, - ); - const {rootDir} = b.entryAsset.options; - const writtenAssets = Array.from(b.offsets.keys()).map(asset => asset.name); - assert( - writtenAssets.includes(path.join(rootDir, 'hello1.js')) && - writtenAssets.includes(path.join(rootDir, 'hello2.js')), - ); - - let module = await run(b); - assert.equal(await module.default(), 'Hello Hello! Hello'); - }); - - it.skip('should support importing HTML from JS async', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-html-async/index.js'), - { - defaultTargetOptions: { - sourceMaps: false, - }, - }, - ); - - assertBundles(b, { - name: 'index.js', - assets: ['index.js', 'cacheLoader.js', 'html-loader.js'], - childBundles: [ - { - type: 'html', - assets: ['other.html'], - childBundles: [ - { - type: 'png', - assets: ['100x100.png'], - childBundles: [], - }, - { - type: 'css', - assets: ['index.css'], - }, - ], - }, - ], - }); - - let output = await run(b); - assert.equal(typeof output, 'string'); - assert(output.includes('')); - assert(output.includes('Other page')); - }); - - it.skip('should support importing HTML from JS async with --target=node', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-html-async/index.js'), - { - target: 'node', - defaultTargetOptions: { - sourceMaps: false, - }, - }, - ); - - assertBundles(b, { - name: 'index.js', - assets: ['index.js', 'cacheLoader.js', 'html-loader.js'], - childBundles: [ - { - type: 'html', - assets: ['other.html'], - childBundles: [ - { - type: 'png', - assets: ['100x100.png'], - childBundles: [], - }, - { - type: 'css', - assets: ['index.css'], - }, - ], - }, - ], - }); - - let output = await run(b); - assert.equal(typeof output, 'string'); - assert(output.includes('')); - assert(output.includes('Other page')); - }); - - it.skip('should support importing HTML from JS sync', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-html-sync/index.js'), - { - defaultTargetOptions: { - sourceMaps: false, - }, - }, - ); - - assertBundles(b, { - name: 'index.js', - assets: ['index.js', 'cacheLoader.js', 'html-loader.js'], - childBundles: [ - { - type: 'html', - assets: ['other.html'], - childBundles: [ - { - type: 'png', - assets: ['100x100.png'], - childBundles: [], - }, - { - type: 'css', - assets: ['index.css'], - }, - ], - }, - ], - }); - - let {deferred, promise} = makeDeferredWithPromise(); - await run(b, {output: deferred.resolve}, {require: false}); - let output = await promise; - assert.equal(typeof output, 'string'); - assert(output.includes('')); - assert(output.includes('Other page')); - }); - - it.skip('should stub require.cache', async function () { - let b = await bundle( - path.join(__dirname, '/integration/node_require_cache/main.js'), - { - target: 'node', - }, - ); - - await run(b); - }); - - it.skip('should support async importing the same module from different bundles', async () => { - let b = await bundle( - path.join(__dirname, '/integration/shared-bundlegroup/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - { - assets: ['a.js'], - }, - { - assets: ['b.js'], - }, - { - assets: ['c.js'], - }, - ]); - - let {default: promise} = await run(b); - assert.deepEqual(await promise, ['hello from a test', 'hello from b test']); - }); - - it.skip('should not create shared bundles from contents of entries', async () => { - let b = await bundle( - ['a.js', 'b.js'].map(entry => - path.join( - __dirname, - '/integration/no-shared-bundles-from-entries/', - entry, - ), - ), - ); - - assertBundles(b, [ - { - name: 'a.js', - assets: ['a.js', 'esmodule-helpers.js', 'lodash.js'], - }, - { - name: 'b.js', - assets: ['b.js', 'esmodule-helpers.js', 'lodash.js'], - }, - ]); - }); - - it.skip('should import the same dependency multiple times in the same bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/same-dependency-multiple-times/a1.js'), - ); - - await run(b); - }); - - it.skip("should inline a bundle's compiled text with `bundle-text`", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.js'), - ); - - let cssBundleContent = (await run(b)).default; - - assert( - cssBundleContent.startsWith( - `body { - background-color: #000; -} - -.svg-img { - background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); -}`, - ), - ); - - assert(!cssBundleContent.includes('sourceMappingURL')); - }); - - it.skip('should not include the runtime manifest for `bundle-text`', async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.js'), - { - mode: 'production', - defaultTargetOptions: {shouldScopeHoist: false, shouldOptimize: false}, - }, - ); - - assertBundles(b, [ - { - name: 'index.js', - type: 'js', - assets: ['esmodule-helpers.js', 'index.js'], - }, - { - type: 'svg', - assets: ['img.svg'], - }, - { - type: 'css', - assets: ['text.scss'], - }, - ]); - - let cssBundleContent = (await run(b)).default; - - assert( - cssBundleContent.startsWith( - `body { - background-color: #000; -} - -.svg-img { - background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); -}`, - ), - ); - - assert(!cssBundleContent.includes('sourceMappingURL')); - }); - - it.skip("should inline an HTML bundle's compiled text with `bundle-text`", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.html'), - ); - - let res = await run(b); - assert.equal(res.default, '

test

\n'); - }); - - it.skip('should inline an HTML bundle and inline scripts with `bundle-text`', async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/inline.js'), - ); - - let res = await run(b); - assert.equal( - res.default, - `

test

\n\n`, - ); - }); - - it.skip("should inline a JS bundle's compiled text with `bundle-text` and HMR enabled", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/javascript.js'), - { - hmrOptions: {}, - }, - ); - - let res = await run(b); - let log; - let ctx = vm.createContext({ - console: { - log(x) { - log = x; - }, - }, - }); - vm.runInContext(res.default, ctx); - assert.equal(log, 'hi'); - }); - - it.skip("should inline a JS bundle's compiled text with `bundle-text` with symbol propagation", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/javascript.js'), - { - mode: 'production', - }, - ); - - let res = await run(b); - let log; - let ctx = vm.createContext({ - console: { - log(x) { - log = x; - }, - }, - }); - vm.runInContext(res, ctx); - assert.equal(log, 'hi'); - }); - - it.skip("should inline a bundle's compiled text with `bundle-text` asynchronously", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/async.js'), - ); - - let promise = (await run(b)).default; - assert.equal(typeof promise.then, 'function'); - - let cssBundleContent = await promise; - - assert( - cssBundleContent.startsWith( - `body { - background-color: #000; -} - -.svg-img { - background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); -}`, - ), - ); - - assert(!cssBundleContent.includes('sourceMappingURL')); - }); - - it.skip('should inline text content as url-encoded text and mime type with `data-url:*` imports', async () => { - let b = await bundle(path.join(__dirname, '/integration/data-url/text.js')); - - assert.equal( - (await run(b)).default, - 'data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%3E%3C%2FfeGaussianBlur%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%27%23blur-_.%21~%2a%27%29%22%3E%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A', - ); - }); - - it.skip('should inline binary content as url-encoded base64 and mime type with `data-url:*` imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/data-url/binary.js'), - ); - ``; - - assert((await run(b)).default.startsWith('data:image/webp;base64,UklGR')); - }); - - it.skip('should support both pipeline and non-pipeline imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/multi-pipeline/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'esmodule-helpers.js'], - }, - { - name: 'index.css', - assets: ['style.css'], - }, - { - type: 'css', - assets: ['style.css'], - }, - ]); - - assert((await run(b)).default.startsWith('.test')); - }); - - it.skip('should detect typescript style async requires in commonjs', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts.js'), - ); - - assertBundles(b, [ - { - name: 'ts.js', - assets: ['ts.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['async.js'], - }, - ]); - - assert.equal(await run(b), 2); - }); - - it.skip('should detect typescript style async requires in commonjs with esModuleInterop flag', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts-interop.js'), - ); - - assertBundles(b, [ - { - name: 'ts-interop.js', - assets: [ - 'ts-interop.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.deepEqual(await run(b), {default: 2}); - - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - assert( - /.then\(function\(res\) {\n.*return __importStar\(res\)/.test(contents), - ); - }); - - it.skip('should detect typescript style async requires in commonjs with esModuleInterop flag and arrow functions', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts-interop-arrow.js'), - ); - - assertBundles(b, [ - { - name: 'ts-interop-arrow.js', - assets: [ - 'ts-interop-arrow.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.deepEqual(await run(b), {default: 2}); - - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - assert(/.then\(\(res\)=>__importStar\(res\)/.test(contents)); - }); - - it.skip('should detect rollup style async requires in commonjs', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/rollup.js'), - ); - - assertBundles(b, [ - { - name: 'rollup.js', - assets: [ - 'rollup.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.equal(await run(b), 2); - }); - - it.skip('should only detect requires that are returned from the promise', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/sync.js'), - ); - - assertBundles(b, [ - { - name: 'sync.js', - assets: ['sync.js', 'async.js'], - }, - ]); - - assert.equal(await run(b), 5); - }); - - it.skip('should properly chain a dynamic import wrapped in a Promise.resolve()', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/resolve-chain.js'), - ); - - assertBundles(b, [ - { - name: 'resolve-chain.js', - assets: [ - 'resolve-chain.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.equal(await run(b), 1337); - }); - - it.skip('should detect parcel style async requires in commonjs', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/parcel.js'), - ); - - assertBundles(b, [ - { - name: 'parcel.js', - assets: [ - 'parcel.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); - - assert.equal(await run(b), 2); - }); - - it.skip('should detect requires in commonjs with plain template literals', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/commonjs-template-literal-plain/index.js', - ), - ); - let dist = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - assert(dist.includes('$cPUKg$lodash = require("lodash");')); - - let add = await run(b); - assert.equal(add(2, 3), 5); - }); - - it.skip(`should detect requires in commonjs with plain template literals`, async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/commonjs-template-literal-interpolation/index.js', - ), - ); - let dist = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - - assert( - dist.includes( - 'const add = require(`lodash/${$8cad8166811e0063$var$fn}`);', - ), - ); - - let add = await run(b); - assert.equal(add(2, 3), 5); - }); - - it.skip('only updates bundle names of changed bundles for browsers', async () => { - let fixtureDir = path.join(__dirname, '/integration/name-invalidation'); - let _bundle = () => - bundle(path.join(fixtureDir, 'index.js'), { - inputFS: overlayFS, - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - shouldOptimize: false, - }, - }); - - let first = await _bundle(); - assert.equal(await (await run(first)).default, 42); - - let bPath = path.join(fixtureDir, 'b.js'); - await overlayFS.mkdirp(fixtureDir); - overlayFS.writeFile( - bPath, - (await overlayFS.readFile(bPath, 'utf8')).replace('42', '43'), - ); - - let second = await _bundle(); - assert.equal(await (await run(second)).default, 43); - - let getBundleNameWithPrefix = (b, prefix) => - b - .getBundles() - .map(bundle => path.basename(bundle.filePath)) - .find(name => name.startsWith(prefix)); - - assert.equal( - getBundleNameWithPrefix(first, 'a'), - getBundleNameWithPrefix(second, 'a'), - ); - assert.notEqual( - getBundleNameWithPrefix(first, 'b'), - getBundleNameWithPrefix(second, 'b'), - ); - }); - - it.skip('can load the same resource when referenced in multiple bundles', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/same-resource-multiple-bundles/index.js', - ), - ); - - let res = await run(b); - assert(url.parse(await res.default()).pathname.startsWith('/resource')); - }); - - it.skip('can static import and dynamic import in the same bundle without creating a new bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/sync-async/same-bundle.js'), - {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, - ); - - assertBundles(b, [ - { - name: 'same-bundle.js', - assets: [ - 'same-bundle.js', - 'get-dep.js', - 'get-dep-2.js', - 'dep.js', - 'esmodule-helpers.js', - ], - }, - ]); - - assert.deepEqual(await (await run(b)).default, [42, 42, 42]); - }); - - it.skip('async dependency can be resolved internally and externally from two different bundles', async () => { - let b = await bundle( - ['entry1.js', 'entry2.js'].map(entry => - path.join( - __dirname, - '/integration/async-dep-internal-external/', - entry, - ), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - assets: ['async.js'], - }, - { - name: 'entry1.js', - assets: ['child.js', 'entry1.js', 'async.js'], - }, - { - name: 'entry2.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'child.js', - 'entry2.js', - 'js-loader.js', - ], - }, - ]); - }); - - it.skip('can static import and dynamic import in the same bundle ancestry without creating a new bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/sync-async/same-ancestry.js'), - {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, - ); - - assertBundles(b, [ - { - name: 'same-ancestry.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'dep.js', - 'js-loader.js', - 'same-ancestry.js', - 'esmodule-helpers.js', - ], - }, - { - assets: ['get-dep.js'], - }, - ]); - - assert.deepEqual(await (await run(b)).default, [42, 42]); - }); - - it.skip('can static import and dynamic import in the same bundle when another bundle requires async', async () => { - let b = await bundle( - ['same-bundle.js', 'get-dep.js'].map(entry => - path.join(__dirname, '/integration/sync-async/', entry), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - - assertBundles(b, [ - { - assets: ['dep.js'], - }, - { - name: 'same-bundle.js', - assets: [ - 'same-bundle.js', - 'get-dep.js', - 'get-dep-2.js', - 'dep.js', - 'esmodule-helpers.js', - ], - }, - { - name: 'get-dep.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'get-dep.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - ]); - - let bundles = b.getBundles(); - let sameBundle = bundles.find(b => b.name === 'same-bundle.js'); - let getDep = bundles.find(b => b.name === 'get-dep.js'); - - assert.deepEqual( - await ( - await runBundle(b, sameBundle) - ).default, - [42, 42, 42], - ); - assert.deepEqual(await (await runBundle(b, getDep)).default, 42); - }); - - it.skip("can share dependencies between a shared bundle and its sibling's descendants", async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/shared-exports-for-sibling-descendant/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - - assertBundles(b, [ - { - assets: ['wraps.js', 'lodash.js'], - }, - { - assets: ['a.js'], - }, - { - assets: ['child.js'], - }, - { - assets: ['grandchild.js'], - }, - { - assets: ['b.js'], - }, - { - name: 'index.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'index.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - ]); - - assert.deepEqual(await (await run(b)).default, [3, 5]); - }); - - it.skip('can run an entry bundle whose entry asset is present in another bundle', async () => { - let b = await bundle( - ['index.js', 'value.js'].map(basename => - path.join(__dirname, '/integration/sync-entry-shared', basename), - ), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - {name: 'value.js', assets: ['value.js', 'esmodule-helpers.js']}, - {assets: ['async.js']}, - ]); - - assert.equal(await (await run(b)).default, 43); - }); - - it.skip('can run an async bundle whose entry asset is present in another bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/async-entry-shared/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - {assets: ['value.js']}, - {assets: ['async.js']}, - ]); - - assert.deepEqual(await (await run(b)).default, [42, 43]); - }); - - it.skip('should display a codeframe on a Terser parse error', async () => { - let fixture = path.join(__dirname, 'integration/terser-codeframe/index.js'); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects( - () => - bundle(fixture, { - defaultTargetOptions: { - shouldOptimize: true, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: '`let` cannot be used as an identifier in strict mode', - origin: '@parcel/optimizer-swc', - codeFrames: [ - { - filePath: undefined, - language: 'js', - code, - codeHighlights: [ - { - start: { - column: 1, - line: 1, - }, - end: { - column: 1, - line: 1, - }, - }, - ], - }, - ], - }, - ], - }, - ); - }); - - it.skip('can run an async bundle that depends on a nonentry asset in a sibling', async () => { - let b = await bundle( - ['index.js', 'other-entry.js'].map(basename => - path.join( - __dirname, - '/integration/async-entry-shared-sibling', - basename, - ), - ), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - { - name: 'other-entry.js', - assets: [ - 'other-entry.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - {assets: ['a.js', 'value.js', 'esmodule-helpers.js']}, - {assets: ['b.js']}, - ]); - - assert.deepEqual(await (await run(b)).default, 43); - }); - - it.skip('can share sibling bundles reachable from a common dependency', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/shared-sibling-common-dependency/index.js', - ), - ); - - let bundles = b.getBundles(); - let asyncJsBundles = bundles.filter( - b => !b.needsStableName && b.type === 'js', - ); - assert.equal(asyncJsBundles.length, 2); - - // Every bundlegroup with an async js bundle should have the corresponding css - for (let bundle of asyncJsBundles) { - for (let bundleGroup of b.getBundleGroupsContainingBundle(bundle)) { - let bundlesInGroup = b.getBundlesInBundleGroup(bundleGroup); - assert(bundlesInGroup.find(s => s.type === 'css')); - } - } - }); - - it.skip('should throw a diagnostic for unknown pipelines', async function () { - let fixture = path.join(__dirname, 'integration/pipeline-unknown/a.js'); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects(() => bundle(fixture), { - name: 'BuildError', - diagnostics: [ - { - message: "Failed to resolve 'strange-pipeline:./b.js' from './a.js'", - origin: '@parcel/core', - codeFrames: [ - { - filePath: fixture, - code, - codeHighlights: [ - { - message: undefined, - start: { - column: 19, - line: 1, - }, - end: { - column: 43, - line: 1, - }, - }, - ], - }, - ], - }, - { - message: "Unknown url scheme or pipeline 'strange-pipeline:'", - origin: '@parcel/resolver-default', - }, - ], - }); - }); - - it.skip('can create a bundle starting with a dot', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dotfile-bundle/index.js'), - ); - - assertBundles(b, [ - { - name: '.output.js', - assets: ['index.js'], - }, - ]); - }); - - it.skip('should not automatically name bundle files starting with a dot', async function () { - await bundle( - path.join(__dirname, '/integration/bundle-naming/.invisible/index.js'), - ); - let bundleFiles = await outputFS.readdir(distDir); - let renamedSomeFiles = bundleFiles.some(currFile => - currFile.startsWith('invisible.'), - ); - let namedWithDot = bundleFiles.some(currFile => - currFile.startsWith('.invisible.'), - ); - assert.equal(renamedSomeFiles, true); - assert.equal(namedWithDot, false); - }); - - it.skip('should support duplicate re-exports without scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-duplicate-re-exports/index.js'), - ); - let res = await run(b); - assert.equal(res.a, 'a'); - assert.equal(res.b, 'b'); - assert.equal(typeof res.c, 'function'); - }); - - it.skip('should prioritize named exports before re-exports withput scope hoisting (before)', async () => { - let b = await bundle( - path.join( - __dirname, - 'integration/scope-hoisting/es6/re-export-priority/entry-a.mjs', - ), - ); - - let res = await run(b, null, {require: false}); - assert.equal(res.output, 2); - }); - - it.skip('should prioritize named exports before re-exports without scope hoisting (after)', async () => { - let b = await bundle( - path.join( - __dirname, - 'integration/scope-hoisting/es6/re-export-priority/entry-b.mjs', - ), - ); - - let res = await run(b, null, {require: false}); - assert.equal(res.output, 2); - }); - - it.skip('should exclude default from export all declaration', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-all/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {a: 4}); - }); - - it.skip('should not use arrow functions for reexport declarations unless supported', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-arrow-support/index.js'), - { - // Remove comments containing "=>" - defaultTargetOptions: { - shouldOptimize: true, - }, - }, - ); - let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!content.includes('=>')); - }); - - it.skip('should support import namespace declarations of other ES modules', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/a.js'), - ); - let res = await run(b); - assert.deepEqual(res, {a: 4, default: 1}); - }); - - it.skip('should support import namespace declarations of class from CJS', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/b.js'), - ); - let res = await run(b); - assert.equal(typeof res, 'function'); - }); - - it.skip('should support import namespace declarations of object from CJS', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/c.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: 2, default: 3}); - }); - - it.skip('should support export namespace declarations', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-namespace/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {ns: {a: 4, default: 1}}); - }); - - it.skip('should support export declarations with destructuring', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-destructuring/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: 1, bar: 2}); - }); - - it.skip('should support export default declarations', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-default/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {other: 1}); - }); - - it.skip('should hoist function default exports to allow circular imports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-export-default-fn-circular-named/a.mjs', - ), - ); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, 'b1'); - }); - - it.skip('should hoist anonymous function default exports to allow circular imports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-export-default-fn-circular-anonymous/a.mjs', - ), - ); - - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, 'b1'); - }); - - it.skip('should work with many different types of exports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-many/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, { - foo: 'foo', - bar: 'bar', - default: 'baz', - boo: 'boo', - foobar: 'foobar', - type1: 'type1', - type2: 'type2', - }); - }); - - it.skip('should correctly export functions', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-functions/index.js'), - ); - let res = await run(b); - assert.deepEqual(Object.keys(res), ['foo', 'bar']); - assert.strictEqual(res.foo('test'), 'foo:test'); - assert.strictEqual(res.bar('test'), 'bar:test'); - }); - - it.skip('should handle exports of imports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-import/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {other: 2}); - }); - - it.skip('should handle simultaneous import and reexports of the same identifier', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-import-same/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: '123', bar: '1234'}); - }); - - it.skip('should generate a unique variable name for imports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow/index.js'), - ); - let res = await run(b); - assert.strictEqual(res.baz(), 'foo'); - }); - - it.skip('should not replace identifier with a var declaration inside a for loop', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow-for-var/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.baz(), [0, 1, 2, 3]); - }); - - it.skip('should replace an imported identifier with function locals of the same name', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow-func-var/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, 123); - }); - - it.skip('should replace imported values in member expressions', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-member/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, ['a', 'b', 'bar']); - }); - - it.skip('should retain the correct dependency order between import and reexports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-reexport-dep-order/index.js'), - ); - - let calls = []; - await run(b, { - sideEffect(v) { - calls.push(v); - }, - }); - assert.deepEqual(calls, ['a', 'b', 'c']); - }); - - it.skip('should not freeze live default imports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-default-live/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, [123, 789]); - }); - - it.skip('should not rewrite this in arrow function class properties', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-class-this-esm/a.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, 'x: 123'); - }); - - it.skip('should call named imports without this context', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-this/index.js'), - ); - let res = await run(b, {output: null}, {strict: true}); - assert.deepEqual(res.default, { - unwrappedNamed: [true, false], - unwrappedDefault: [true, false], - unwrappedNamespace: [false, true], - wrappedNamed: [true, false], - wrappedDefault: [true, false], - wrappedNamespace: [false, true], - }); - }); - - it.skip('should only replace free references to require', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-free/index.js'), - ); - let output; - await run(b, { - output(v) { - output = v; - }, - }); - assert.strictEqual(output, 'a'); - }); - - it.skip('should only replace free references to require with scope hoisting', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-free/index.js'), - { - mode: 'production', - }, - ); - let output; - await run(b, { - output(v) { - output = v; - }, - }); - assert.strictEqual(output, 'a'); - }); - - it.skip('should support import and non-top-level require of same asset from different assets', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-import-different/index.js'), - ); - let {output} = await run(b, null, {require: false}); - assert.deepEqual(output, [123, {HooksContext: 123}]); - }); - - it.skip('should support import and non-top-level require of same asset from different assets with scope hoisting', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-import-different/index.js'), - { - mode: 'production', - }, - ); - let {output} = await run(b, null, {require: false}); - assert.deepEqual(output, [123, {HooksContext: 123}]); - }); - - it.skip('should support runtime module deduplication', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-runtime-dedup/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['async1.js', 'shared.js', 'esmodule-helpers.js'], - }, - { - assets: ['async2.js', 'shared.js', 'esmodule-helpers.js'], - }, - ]); - - let res = await run(b); - assert.equal(await res, true); - }); - - it.skip('should support runtime module deduplication with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-runtime-dedup/index.js'), - { - mode: 'production', - }, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['async1.js', 'shared.js'], - }, - { - assets: ['async2.js', 'shared.js'], - }, - ]); - - let res = await run(b); - assert.equal(await res, true); - }); - - it.skip('should remap locations in diagnostics using the input source map', async () => { - let fixture = path.join( - __dirname, - 'integration/diagnostic-sourcemap/index.js', - ); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects( - () => - bundle(fixture, { - defaultTargetOptions: { - shouldOptimize: true, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: "Failed to resolve 'foo' from './index.js'", - origin: '@parcel/core', - codeFrames: [ - { - filePath: fixture, - code, - codeHighlights: [ - { - message: undefined, - start: { - line: 11, - column: 17, - }, - end: { - line: 11, - column: 21, - }, - }, - ], - }, - ], - }, - { - message: "Cannot find module 'foo'", - origin: '@parcel/resolver-default', - hints: [], - }, - ], - }, - ); - }); - it.skip('should reuse a bundle when its main asset (aka bundleroot) is imported sychronously', async function () { - let b = await bundle( - path.join(__dirname, 'integration/shared-bundle-single-source/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'css-loader.js', - 'esmodule-helpers.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['bar.js'], - }, - { - assets: ['a.js', 'b.js', 'foo.js'], - }, - { - assets: ['styles.css'], - }, - { - assets: ['local.html'], - }, - ]); - }); - - it.skip('should error on undeclared external dependencies for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/index.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: "Failed to resolve 'lodash' from './index.js'", - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 19, - }, - end: { - line: 1, - column: 26, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "lodash" is not declared in package.json.', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: await inputFS.readFile(pkg, 'utf8'), - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: undefined, - start: { - line: 5, - column: 3, - }, - end: { - line: 5, - column: 16, - }, - }, - ], - }, - ], - hints: ['Add "lodash" as a dependency.'], - }, - ], - }, - ); - }); - - it.skip('should error on undeclared helpers dependency for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/helpers.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( - require.resolve('@parcel/transformer-js/src/JSTransformer.js'), - )}'`, - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 1, - }, - end: { - line: 1, - column: 1, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "@swc/helpers" is not declared in package.json.', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: await inputFS.readFile(pkg, 'utf8'), - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: undefined, - start: { - line: 5, - column: 3, - }, - end: { - line: 5, - column: 16, - }, - }, - ], - }, - ], - hints: ['Add "@swc/helpers" as a dependency.'], - }, - ], - }, - ); - }); - - it.skip('should error on mismatched helpers version for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/helpers.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - let pkgContents = JSON.stringify( - { - ...JSON.parse(await overlayFS.readFile(pkg, 'utf8')), - dependencies: { - '@swc/helpers': '^0.3.0', - }, - }, - false, - 2, - ); - await overlayFS.mkdirp(path.dirname(pkg)); - await overlayFS.writeFile(pkg, pkgContents); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - inputFS: overlayFS, - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( - require.resolve('@parcel/transformer-js/src/JSTransformer.js'), - )}'`, - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 1, - }, - end: { - line: 1, - column: 1, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "@swc/helpers" does not satisfy required semver range "^0.5.0".', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: pkgContents, - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: 'Found this conflicting requirement.', - start: { - line: 6, - column: 21, - }, - end: { - line: 6, - column: 28, - }, - }, - ], - }, - ], - hints: [ - 'Update the dependency on "@swc/helpers" to satisfy "^0.5.0".', - ], - }, - ], - }, - ); - }); - - describe('multiple import types', function () { - it.skip('supports both static and dynamic imports to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['static-dynamic.js', 'other.js', 'esmodule-helpers.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - }); - - it.skip('supports both static and dynamic imports to the same specifier in the same file with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['static-dynamic.js', 'other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - }); - - it.skip('supports static, dynamic, and url to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic-url.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', - assets: [ - 'static-dynamic-url.js', - 'other.js', - 'esmodule-helpers.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); - - it.skip('supports static, dynamic, and url to the same specifier in the same file with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic-url.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['static-dynamic-url.js', 'other.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); - - it.skip('supports dynamic import and url to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-url.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', - assets: [ - 'dynamic-url.js', - 'esmodule-helpers.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); - - it.skip('supports dynamic import and url to the same specifier in the same file with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-url.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['dynamic-url.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); - - it.skip('supports static import and inline bundle for the same asset', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-inline.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['static-inline.js', 'other.js', 'esmodule-helpers.js'], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.text, 'string'); - }); - - it.skip('supports static import and inline bundle for the same asset with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-inline.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['static-inline.js', 'other.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.text, 'string'); - }); - - it.skip('supports dynamic import and inline bundle for the same asset', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-inline.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', - assets: [ - 'dynamic-inline.js', - 'esmodule-helpers.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - type: 'js', - assets: ['other.js'], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal(typeof res.text, 'string'); - }); - - it.skip('supports dynamic import and inline bundle for the same asset with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-inline.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['dynamic-inline.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal(typeof res.text, 'string'); - }); - }); - - it.skip('should avoid creating a bundle for lazy dependencies already available in a shared bundle', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/shared-bundle-internalization/index.mjs', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - - assert.deepEqual(await (await run(b)).default, [42, 42]); - }); - - it.skip('should support standalone import.meta', async function () { - let b = await bundle( - path.join(__dirname, 'integration/import-meta/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, { - meta: {url: 'file:///integration/import-meta/index.js'}, - url: 'file:///integration/import-meta/index.js', - equal: true, - }); - - assert.equal(Object.getPrototypeOf(res.default.meta), null); - assert.equal(Object.isExtensible(res.default.meta), true); - assert.deepEqual(Object.getOwnPropertyDescriptors(res.default.meta), { - url: { - writable: true, - configurable: true, - enumerable: true, - value: 'file:///integration/import-meta/index.js', - }, - }); - }); - - it.skip('should support importing async bundles from bundles with different dist paths', async function () { - let bundleGraph = await bundle( - ['bar/entry/entry-a.js', 'foo/entry-b.js'].map(f => - path.join(__dirname, 'integration/differing-bundle-urls', f), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, - }, - }, - ); - assertBundles(bundleGraph, [ - { - name: 'entry-a.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'entry-a.js', - 'js-loader.js', - ], - }, - { - name: 'entry-b.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'entry-b.js', - 'js-loader.js', - ], - }, - {name: /deep\.[a-f0-9]+\.js/, assets: ['deep.js']}, - {name: /common\.[a-f0-9]+\.js/, assets: ['index.js']}, - ]); - - let [a, b] = bundleGraph.getBundles().filter(b => b.needsStableName); - let calls = []; - - let bundles = [ - [await outputFS.readFile(a.filePath, 'utf8'), a], - [await outputFS.readFile(b.filePath, 'utf8'), b], - ]; - - await runBundles(bundleGraph, a, bundles, { - sideEffect: v => { - calls.push(v); - }, - }); - - assert.deepEqual(calls, ['common', 'deep']); - }); - - it.skip('supports deferring unused ESM imports with sideEffects: false', async function () { - let b = await bundle( - path.join(__dirname, '/integration/side-effects-false/import.js'), - ); - - let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - - assert(!content.includes('returned from bar')); - - let called = false; - let output = await run(b, { - sideEffect() { - called = true; - }, - }); - - assert(!called, 'side effect called'); - assert.strictEqual(output.default, 4); - }); - - it.skip('supports ESM imports and requires with sideEffects: false', async function () { - let b = await bundle( - path.join(__dirname, '/integration/side-effects-false/import-require.js'), - ); - - let output = await run(b, { - sideEffect() {}, - }); - - assert.strictEqual(output.default, '4returned from bar'); - }); - - it.skip('should not affect ESM import order', async function () { - const b = await bundle( - path.join(__dirname, '/integration/js-import-initialization/a.mjs'), - ); - - await assert.rejects( - run(b), - new ReferenceError("Cannot access 'foo' before initialization"), - ); - }); - - it.skip('should not affect ESM import order with scope hoisting', async function () { - const b = await bundle( - path.join(__dirname, '/integration/js-import-initialization/a.mjs'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - - await assert.rejects( - run(b), - /^ReferenceError: Cannot access '(.+)' before initialization$/, - ); - }); - - it.skip('should produce working output with both scope hoisting and non scope hoisting targets', async function () { - let b = await bundle( - path.join(__dirname, '/integration/re-export-no-scope-hoist'), - { - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); - let bundles = b.getBundles(); - - let o1, o2; - await runBundle(b, bundles[0], { - output: (...o) => (o1 = o), - }); - - await runBundle(b, bundles[1], { - output: (...o) => (o2 = o), - }); - - assert.deepEqual(o1, ['UIIcon', 'Icon']); - assert.deepEqual(o2, ['UIIcon', 'Icon']); - }); - - it.skip('should not deduplicate an asset if it will become unreachable', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/sibling-deduplicate-unreachable/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); - let res = await run(b); - assert.equal(await res.default, 'target'); - }); - - it.skip('should detect shorthand identifier imports', async function () { - const dir = path.join(__dirname, 'js-import-shorthand-identifier'); - overlayFS.mkdirp(dir); - - await fsFixture(overlayFS, dir)` - package.json: - { - "name": "app", - "private": true, - "sideEffects": false - } - - index.js: - import { tokens, mode } from "./tokens.js"; - - export default tokens; - - tokens.js: - import { color } from "./color.js"; - - export const tokens = { - color, - }; - - export { mode } from "./color.js"; - - color.js: - export const color = "blue"; - export const mode = "dark";`; - - let b = await bundle(path.join(dir, '/index.js'), { - inputFS: overlayFS, - }); - - let output = await run(b); - assert.deepEqual(output.default, {color: 'blue'}); - }); - - it.skip('should retain unicode escape sequences', async function () { - // See issue #8877 - await fsFixture(overlayFS, __dirname)` - src/index.js: - export default ['\\u0085', '\\u200b', '\\ufffe']; - `; - - let b = await bundle(path.join(__dirname, 'src/index.js'), { - inputFS: overlayFS, - }); - - let output = (await run(b)).default; - assert.deepEqual(output, ['\u0085', '\u200b', '\ufffe']); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert.equal(contents.match(/\\/g).length, 3); - assert(!contents.includes('\u0085')); - assert(!contents.includes('\u200b')); - assert(!contents.includes('\ufffe')); - }); - - it.skip(`should not wrap assets that are duplicated in different targets`, async function () { - const dir = path.join(__dirname, 'multi-target-duplicates'); - overlayFS.mkdirp(dir); - - await fsFixture(overlayFS, dir)` - shared/index.js: - export default 2; - - packages/a/package.json: - { - "source": "index.js", - "module": "dist/module.js" - } - - packages/a/index.js: - import shared from '../../shared'; - export default shared + 2; - - packages/b/package.json: - { - "source": "index.js", - "module": "dist/module.js" - } - - packages/b/index.js: - import shared from '../../shared'; - export default shared + 2; - `; - - let b = await bundle(path.join(dir, '/packages/*'), { - inputFS: overlayFS, - }); - - for (let bundle of b.getBundles()) { - let contents = await outputFS.readFile(bundle.filePath, 'utf8'); - assert( - !contents.includes('parcelRequire'), - 'should not include parcelRequire', - ); - } - }); - - it.skip(`should also fail on recoverable parse errors`, async () => { - await fsFixture(overlayFS, __dirname)` - js-recoverable-parse-errors - index.js: - 1 / {2}`; - - const fixture = path.join( - __dirname, - '/js-recoverable-parse-errors/index.js', - ); - - await assert.rejects( - () => - bundle(fixture, { - inputFS: overlayFS, - }), - { - name: 'BuildError', - diagnostics: [ - { - origin: '@parcel/transformer-js', - message: 'Unexpected token `}`. Expected identifier', - hints: null, - codeFrames: [ - { - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - column: 7, - line: 1, - }, - end: { - column: 7, - line: 1, - }, - }, - ], - }, - ], - }, - ], - }, - ); - }); - - for (let shouldScopeHoist of [false, true]) { - let options = { - defaultTargetOptions: { - shouldScopeHoist, - }, - mode: 'production', - }; - let usesSymbolPropagation = shouldScopeHoist; - describe(`sideEffects: false with${ - shouldScopeHoist ? '' : 'out' - } scope-hoisting`, function () { - if (usesSymbolPropagation) { - it.skip('supports excluding unused CSS imports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-css/index.html', - ), - options, - ); - - assertBundles(b, [ - { - name: 'index.html', - assets: ['index.html'], - }, - { - type: 'js', - assets: ['index.js', 'b1.js'], - }, - { - type: 'css', - assets: ['b1.css'], - }, - ]); - - let calls = []; - let res = await run( - b, - { - output: null, - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - assert.deepEqual(calls, ['b1']); - assert.deepEqual(res.output, 2); - - let css = await outputFS.readFile( - b.getBundles().find(bundle => bundle.type === 'css').filePath, - 'utf8', - ); - assert(!css.includes('.b2')); - }); - - it.skip("doesn't create new bundles for dynamic imports in excluded assets", async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-no-new-bundle/index.html', - ), - options, - ); - - assertBundles(b, [ - { - name: 'index.html', - assets: ['index.html'], - }, - { - type: 'js', - assets: ['index.js', 'b1.js'], - }, - ]); - - let calls = []; - let res = await run( - b, - { - output: null, - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - assert.deepEqual(calls, ['b1']); - assert.deepEqual(res.output, 2); - }); - } - - it.skip('supports deferring unused ES6 re-exports (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/a.js', - ), - options, - ); - - assertBundles(b, [ - { - type: 'js', - assets: usesSymbolPropagation - ? ['a.js', 'message1.js'] - : ['a.js', 'esmodule-helpers.js', 'index.js', 'message1.js'], - }, - ]); - - if (usesSymbolPropagation) { - // TODO this only excluded, but should be deferred. - assert(!findAsset(b, 'message3.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message1'] : ['message1', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports deferring an unused ES6 re-export (wildcard, empty, unused)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-all-empty/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assertDependencyWasExcluded(b, 'index.js', './empty.js'); - } - - assert.deepEqual((await run(b, null, {require: false})).output, 123); - }); - - it.skip('supports deferring unused ES6 re-exports (reexport named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/b.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - assert(!findAsset(b, 'message3.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message2'] : ['message2', 'index'], - ); - assert.deepEqual(res.output, 'Message 2'); - }); - - it.skip('supports deferring unused ES6 re-exports (namespace rename used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/c.js', - ), - options, - ); - - assertBundles(b, [ - { - type: 'js', - assets: usesSymbolPropagation - ? ['c.js', 'message3.js'] - : ['c.js', 'esmodule-helpers.js', 'index.js', 'message3.js'], - }, - ]); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message3'] : ['message3', 'index'], - ); - assert.deepEqual(res.output, {default: 'Message 3'}); - }); - - it.skip('supports deferring unused ES6 re-exports (direct export used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/d.js', - ), - options, - ); - - assertDependencyWasExcluded(b, 'index.js', './message2.js'); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - assert(!findAsset(b, 'message3.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual(calls, ['index']); - assert.deepEqual(res.output, 'Message 4'); - }); - - it.skip('supports chained ES6 re-exports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-chained/index.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'bar.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - if (shouldScopeHoist) { - try { - assert.deepEqual(calls, ['key', 'foo', 'index']); - } catch (e) { - // A different dependency order, but this is deemed acceptable as it's sideeffect free - assert.deepEqual(calls, ['foo', 'key', 'index']); - } - } else { - assert.deepEqual(calls, ['key', 'foo', 'types', 'index']); - } - - assert.deepEqual(res.output, ['key', 'foo']); - }); - - it.skip('should not optimize away an unused ES6 re-export and an used import', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-import/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 123); - }); - - it.skip('should not optimize away an unused ES6 re-export and an used import (different symbols)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-import-different/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 123); - }); - - it.skip('correctly handles ES6 re-exports in library mode entries', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-library/a.js', - ), - options, - ); - - let contents = await outputFS.readFile( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-library/build.js', - ), - 'utf8', - ); - assert(!contents.includes('console.log')); - - let res = await run(b); - assert.deepEqual(res, {c1: 'foo'}); - }); - - if (shouldScopeHoist) { - it.skip('correctly updates deferred assets that are reexported', async function () { - let testDir = path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-update-deferred-reexported', - ); - - let b = bundler(path.join(testDir, 'index.js'), { - inputFS: overlayFS, - outputFS: overlayFS, - ...options, - }); - - let subscription = await b.watch(); - - let bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - let output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '12345hello'); - - await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); - await overlayFS.copyFile( - path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), - path.join(testDir, 'node_modules', 'foo', 'foo.js'), - ); - - bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '1234556789'); - - await subscription.unsubscribe(); - }); - - it.skip('correctly updates deferred assets that are reexported and imported directly', async function () { - let testDir = path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-update-deferred-direct', - ); - - let b = bundler(path.join(testDir, 'index.js'), { - inputFS: overlayFS, - outputFS: overlayFS, - ...options, - }); - - let subscription = await b.watch(); - - let bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - let output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '12345hello'); - - await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); - await overlayFS.copyFile( - path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), - path.join(testDir, 'node_modules', 'foo', 'foo.js'), - ); - - bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '1234556789'); - - await subscription.unsubscribe(); - }); - - it.skip('removes deferred reexports when imported from multiple asssets', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-multiple-dynamic/a.js', - ), - options, - ); - - let contents = await outputFS.readFile( - b.getBundles()[0].filePath, - 'utf8', - ); - - assert(!contents.includes('$import$')); - assert(/=\s*1234/.test(contents)); - assert(!/=\s*5678/.test(contents)); - - let output = await run(b); - assert.deepEqual(output, [1234, {default: 1234}]); - }); - } - - it.skip('keeps side effects by default', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects/a.js', - ), - options, - ); - - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - - assert(called, 'side effect not called'); - assert.deepEqual(res.output, 4); - }); - - it.skip('supports the package.json sideEffects: false flag', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false/a.js', - ), - options, - ); - - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 4); - }); - - it.skip('supports removing a deferred dependency', async function () { - let testDir = path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false', - ); - - let b = bundler(path.join(testDir, 'a.js'), { - inputFS: overlayFS, - outputFS: overlayFS, - ...options, - }); - - let subscription = await b.watch(); - - try { - let bundleEvent = await getNextBuild(b); - assert.strictEqual(bundleEvent.type, 'buildSuccess'); - let called = false; - let res = await run( - bundleEvent.bundleGraph, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 4); - if (usesSymbolPropagation) { - assert(!findAsset(bundleEvent.bundleGraph, 'index.js')); - } - - await overlayFS.mkdirp(path.join(testDir, 'node_modules/bar')); - await overlayFS.copyFile( - path.join(testDir, 'node_modules/bar/index.1.js'), - path.join(testDir, 'node_modules/bar/index.js'), - ); - - bundleEvent = await getNextBuild(b); - assert.strictEqual(bundleEvent.type, 'buildSuccess'); - called = false; - res = await run( - bundleEvent.bundleGraph, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 4); - } finally { - await subscription.unsubscribe(); - } - }); - - it.skip('supports wildcards', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false-wildcards/a.js', - ), - options, - ); - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - - if (usesSymbolPropagation) { - assert(!called, 'side effect called'); - } - assert.deepEqual(res.output, 'bar'); - }); - - it.skip('correctly handles excluded and wrapped reexport assets', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false-wrap-excluded/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 4); - }); - - it.skip('supports the package.json sideEffects flag with an array', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-array/a.js', - ), - options, - ); - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert(calls.toString() == 'foo', "side effect called for 'foo'"); - assert.deepEqual(res.output, 4); - }); - - it.skip('supports the package.json sideEffects: false flag with shared dependencies', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false-duplicate/a.js', - ), - options, - ); - - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; - }, - }, - {require: false}, - ); - - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 6); - }); - - it.skip('supports the package.json sideEffects: false flag with shared dependencies and code splitting', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-split/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, 581); - }); - - it.skip('supports the package.json sideEffects: false flag with shared dependencies and code splitting II', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-split2/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, [{default: 123, foo: 2}, 581]); - }); - - it.skip('missing exports should be replaced with an empty object', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/empty-module/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, {b: {}}); - }); - - it.skip('supports namespace imports of theoretically excluded reexporting assets', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/import-namespace-sideEffects/index.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, {Main: 'main', a: 'foo', b: 'bar'}); - }); - - it.skip('can import from a different bundle via a re-export', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/re-export-bundle-boundary-side-effects/index.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, ['operational', 'ui']); - }); - - it.skip('supports excluding multiple chained namespace reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-chained-re-exports-multiple/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'symbol1.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message1'] : ['message1', 'message'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports excluding when doing both exports and reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-export-reexport/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'other.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual(calls, ['index']); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports deferring with chained renaming reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-chained/a.js', - ), - options, - ); - - // assertDependencyWasExcluded(b, 'message.js', './message2'); - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist - ? ['message1'] - : ['message1', 'message', 'index2', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports named and renamed reexports of the same asset (default used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, 'bar'); - }); - - it.skip('supports named and renamed reexports of the same asset (named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/b.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, 'bar'); - }); - - it.skip('supports named and renamed reexports of the same asset (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same/index.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, [{value1: 123, value2: 123}, 123, 123]); - }); - - it.skip('supports reexports via variable declaration (unused)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-var-unused/index.js', - ), - options, - ); - - let res = await run(b, {}, {require: false}); - assert.deepEqual((await res.output).foo, 'foo'); - }); - - it.skip('supports named and namespace exports of the same asset (named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['default']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['foo']); - }); - - it.skip('supports named and namespace exports of the same asset (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/b.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['bar']); - }); - - it.skip('supports named and namespace exports of the same asset (both used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/c.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['default', 'bar']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['foo', 'bar']); - }); - - it.skip('supports partially used reexporting index file', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-partially-used/index.js', - ), - options, - ); - - let calls = []; - let res = ( - await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ) - ).output; - - let [v, async] = res; - - assert.deepEqual(calls, shouldScopeHoist ? ['b'] : ['b', 'index']); - assert.deepEqual(v, 2); - - v = await async(); - assert.deepEqual( - calls, - shouldScopeHoist - ? ['b', 'a', 'index', 'dynamic'] - : ['b', 'index', 'a', 'dynamic'], - ); - assert.deepEqual(v.default, [1, 3]); - }); - - it.skip('supports deferring non-weak dependencies that are not used', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-semi-weak/a.js', - ), - options, - ); - - // assertDependencyWasExcluded(b, 'esm2.js', './other.js'); - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['esm1'] : ['esm1', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports excluding CommonJS (CommonJS unused)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-commonjs/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'esm.js')))), - new Set(['message1']), - ); - // We can't statically analyze commonjs.js, so message1 appears to be used - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'commonjs.js')))), - // the exports object is used freely - new Set(['*', 'message1']), - ); - assert.deepStrictEqual( - new Set( - b.getUsedSymbols(findDependency(b, 'index.js', './commonjs.js')), - ), - new Set(['message1']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual(calls, ['esm', 'commonjs', 'index']); - assert.deepEqual(res.output, 'Message 1'); - }); - - it.skip('supports excluding CommonJS (CommonJS used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-commonjs/b.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'esm.js')); - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'commonjs.js')))), - // the exports object is used freely - new Set(['*', 'message2']), - ); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['commonjs'] : ['commonjs', 'index'], - ); - assert.deepEqual(res.output, 'Message 2'); - }); - }); - - it.skip(`ignores missing unused import specifiers in source assets ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-unused-import-specifier/a.js'), - options, - ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); - - it.skip(`ignores missing unused import specifiers in node-modules ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-unused-import-specifier-node-modules/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); - - it.skip(`duplicate assets should share module scope ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - [ - path.join( - __dirname, - '/integration/scope-hoisting/es6/multi-entry-duplicates/one.js', - ), - path.join( - __dirname, - '/integration/scope-hoisting/es6/multi-entry-duplicates/two.js', - ), - ], - options, - ); - - let result = await runBundle(b, b.getBundles()[0], {}, {require: false}); - - assert.equal(await result.output, 2); - }); - - it.skip(`should work correctly with export called hasOwnProperty ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async () => { - await fsFixture(overlayFS, __dirname)` - js-export-all-hasOwnProperty - a.js: - export function hasOwnProperty() { - throw new Error("Shouldn't be called"); - } - b.js: - module.exports = { other: 123 }; - - library.js: - export * from './a'; - export * from './b'; - - index.js: - import * as x from './library'; - output = sideEffectNoop(x).other;`; - - let b = await bundle( - path.join(__dirname, 'js-export-all-hasOwnProperty/index.js'), - { - ...options, - inputFS: overlayFS, - }, - ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); - } -}); diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index ceba29fb657..74319abb849 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -5,9 +5,11 @@ import { assertDependencyWasExcluded, bundle, bundler, + describe, findAsset, findDependency, getNextBuild, + it, run, runBundle, runBundles, @@ -44,7 +46,7 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should support url: imports with CommonJS output', async function () { + it.v2('should support url: imports with CommonJS output', async function () { let b = await bundle( path.join(__dirname, '/integration/commonjs-import-url/index.js'), ); @@ -66,7 +68,7 @@ describe('javascript', function () { assert.strictEqual(path.basename(output), path.basename(txtBundle)); }); - it('should produce a basic JS bundle with ES6 imports', async function () { + it.v2('should produce a basic JS bundle with ES6 imports', async function () { let b = await bundle(path.join(__dirname, '/integration/es6/index.js')); // assert.equal(b.assets.size, 8); @@ -78,16 +80,22 @@ describe('javascript', function () { assert.equal(output.default(), 3); }); - it('should detect dependencies inserted by a prior transform', async () => { - let b = await bundle( - path.join(__dirname, '/integration/dependency-prior-transform/index.js'), - ); + it.v2( + 'should detect dependencies inserted by a prior transform', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/dependency-prior-transform/index.js', + ), + ); - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath); + let jsBundle = b.getBundles()[0]; + let contents = await outputFS.readFile(jsBundle.filePath); - assert(!contents.includes('import')); - }); + assert(!contents.includes('import')); + }, + ); it('should ignore unused requires after process.env inlining', async function () { let b = await bundle( @@ -111,25 +119,28 @@ describe('javascript', function () { assert.strictEqual(output(), 'ok'); }); - it('should produce a basic JS bundle with object rest spread support', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/object-rest-spread/object-rest-spread.js', - ), - ); + it.v2( + 'should produce a basic JS bundle with object rest spread support', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/object-rest-spread/object-rest-spread.js', + ), + ); - // assert.equal(b.assets.size, 1); + // assert.equal(b.assets.size, 1); - let output = await run(b); - assert.equal(typeof output, 'object'); - assert.equal(typeof output.default, 'function'); + let output = await run(b); + assert.equal(typeof output, 'object'); + assert.equal(typeof output.default, 'function'); - let res = output.default(); - assert.equal(res.y, 'a'); - assert.deepEqual(res.z, {y: 'a', b: 'b'}); - assert.deepEqual(res.ys, {b: 'b'}); - }); + let res = output.default(); + assert.equal(res.y, 'a'); + assert.deepEqual(res.z, {y: 'a', b: 'b'}); + assert.deepEqual(res.ys, {b: 'b'}); + }, + ); it('should bundle node_modules for a browser environment', async function () { let b = await bundle( @@ -195,21 +206,24 @@ describe('javascript', function () { assert.equal(output(), 7); }); - it('should preserve hashbangs in bundles and preserve executable file mode', async () => { - let fixturePath = path.join(__dirname, '/integration/node_hashbang'); - await bundle(path.join(fixturePath, 'main.js')); + it.v2( + 'should preserve hashbangs in bundles and preserve executable file mode', + async () => { + let fixturePath = path.join(__dirname, '/integration/node_hashbang'); + await bundle(path.join(fixturePath, 'main.js')); - let mainPath = path.join(fixturePath, 'dist', 'node', 'main.js'); - let main = await outputFS.readFile(mainPath, 'utf8'); - assert.equal(main.lastIndexOf('#!/usr/bin/env node\n'), 0); - assert.equal( - (await outputFS.stat(mainPath)).mode, - (await inputFS.stat(path.join(fixturePath, 'main.js'))).mode, - ); - await outputFS.rimraf(path.join(fixturePath, 'dist')); - }); + let mainPath = path.join(fixturePath, 'dist', 'node', 'main.js'); + let main = await outputFS.readFile(mainPath, 'utf8'); + assert.equal(main.lastIndexOf('#!/usr/bin/env node\n'), 0); + assert.equal( + (await outputFS.stat(mainPath)).mode, + (await inputFS.stat(path.join(fixturePath, 'main.js'))).mode, + ); + await outputFS.rimraf(path.join(fixturePath, 'dist')); + }, + ); - it('should not preserve hashbangs in browser bundles', async () => { + it.v2('should not preserve hashbangs in browser bundles', async () => { let fixturePath = path.join(__dirname, '/integration/node_hashbang'); await bundle(path.join(fixturePath, 'main.js')); @@ -221,7 +235,7 @@ describe('javascript', function () { await outputFS.rimraf(path.join(fixturePath, 'dist')); }); - it('should preserve hashbangs in scopehoisted bundles', async () => { + it.v2('should preserve hashbangs in scopehoisted bundles', async () => { let fixturePath = path.join(__dirname, '/integration/node_hashbang'); await bundle(path.join(__dirname, '/integration/node_hashbang/main.js'), { defaultTargetOptions: { @@ -237,24 +251,27 @@ describe('javascript', function () { await outputFS.rimraf(path.join(fixturePath, 'dist')); }); - it('should bundle node_modules for a node environment if includeNodeModules is specified', async function () { - let b = await bundle( - path.join(__dirname, '/integration/include_node_modules/main.js'), - ); + it.v2( + 'should bundle node_modules for a node environment if includeNodeModules is specified', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/include_node_modules/main.js'), + ); - assertBundles(b, [ - { - name: 'main.js', - assets: ['main.js', 'local.js', 'index.js'], - }, - ]); + assertBundles(b, [ + { + name: 'main.js', + assets: ['main.js', 'local.js', 'index.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 3); + }, + ); - it('should bundle builtins for a browser environment', async function () { + it.v2('should bundle builtins for a browser environment', async function () { let b = await bundle( path.join(__dirname, '/integration/include_builtins-browser/main.js'), ); @@ -280,24 +297,27 @@ describe('javascript', function () { assert.deepEqual(Object.keys(fs), Object.keys({})); }); - it('should not bundle builtins for a node environment if includeNodeModules is specified', async function () { - let b = await bundle( - path.join(__dirname, '/integration/include_builtins-node/main.js'), - ); + it.v2( + 'should not bundle builtins for a node environment if includeNodeModules is specified', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/include_builtins-node/main.js'), + ); - assertBundles(b, [ - { - name: 'main.js', - assets: ['esmodule-helpers.js', 'main.js'], - }, - ]); + assertBundles(b, [ + { + name: 'main.js', + assets: ['esmodule-helpers.js', 'main.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - let [fs, filepath] = output(); - assert.equal(filepath, path.join('app', 'index.js')); - assert.equal(typeof fs.readFile, 'function'); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + let [fs, filepath] = output(); + assert.equal(filepath, path.join('app', 'index.js')); + assert.equal(typeof fs.readFile, 'function'); + }, + ); it.skip('should bundle node_modules on --target=electron and --bundle-node-modules', async function () { let b = await bundle( @@ -318,63 +338,79 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should produce a JS bundle with default exports and no imports', async function () { - let b = await bundle( - path.join(__dirname, '/integration/es6-default-only/index.js'), - ); + it.v2( + 'should produce a JS bundle with default exports and no imports', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/es6-default-only/index.js'), + ); - // assert.equal(b.assets.size, 1); - // assert.equal(b.childBundles.size, 1); + // assert.equal(b.assets.size, 1); + // assert.equal(b.childBundles.size, 1); - let output = await run(b); - assert.equal(typeof output, 'object'); - assert.equal(typeof output.default, 'function'); - assert.equal(output.default(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'object'); + assert.equal(typeof output.default, 'function'); + assert.equal(output.default(), 3); + }, + ); - it('should split bundles when a dynamic import is used a browser environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/dynamic/index.js')); + it.v2( + 'should split bundles when a dynamic import is used a browser environment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['local.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['local.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); - it('should prefetch bundles when declared as an import attribute statically', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-static-prefetch/index.js'), - ); + it.v2( + 'should prefetch bundles when declared as an import attribute statically', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-static-prefetch/index.js'), + ); - let output = await run(b); - let headChildren = await output.default; + let output = await run(b); + let headChildren = await output.default; - assert.strictEqual(headChildren.length, 4); + assert.strictEqual(headChildren.length, 4); - assert.strictEqual(headChildren[1].tag, 'script'); - assert(headChildren[1].src.match(/async\..*\.js/)); + assert.strictEqual(headChildren[1].tag, 'script'); + assert(headChildren[1].src.match(/async\..*\.js/)); - assert.strictEqual(headChildren[2].tag, 'link'); - assert.strictEqual(headChildren[2].rel, 'prefetch'); - assert.strictEqual(headChildren[2].as, 'script'); - assert(headChildren[2].href.match(/prefetched\..*\.js/)); + assert.strictEqual(headChildren[2].tag, 'link'); + assert.strictEqual(headChildren[2].rel, 'prefetch'); + assert.strictEqual(headChildren[2].as, 'script'); + assert(headChildren[2].href.match(/prefetched\..*\.js/)); - assert.strictEqual(headChildren[3].tag, 'link'); - assert.strictEqual(headChildren[3].rel, 'prefetch'); - assert.strictEqual(headChildren[3].as, 'style'); - assert(headChildren[3].href.match(/prefetched\..*\.css/)); - }); + assert.strictEqual(headChildren[3].tag, 'link'); + assert.strictEqual(headChildren[3].rel, 'prefetch'); + assert.strictEqual(headChildren[3].as, 'style'); + assert(headChildren[3].href.match(/prefetched\..*\.css/)); + }, + ); - it('should load additional links that were prefetched', async function () { + it.v2('should load additional links that were prefetched', async function () { let b = await bundle( path.join( __dirname, @@ -403,33 +439,36 @@ describe('javascript', function () { assert(cssBundles[1].href.match(/prefetched-loaded\..*\.css/)); }); - it('should preload bundles when declared as an import attribute statically', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-static-preload/index.js'), - ); + it.v2( + 'should preload bundles when declared as an import attribute statically', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-static-preload/index.js'), + ); - let output = await run(b); - let headChildren = await output.default; + let output = await run(b); + let headChildren = await output.default; - assert(headChildren.length === 4); + assert(headChildren.length === 4); - assert(headChildren[2].tag === 'link'); - assert(headChildren[2].rel === 'preload'); - assert(headChildren[2].as === 'script'); - assert(headChildren[2].href.match(/preloaded\..*\.js/)); + assert(headChildren[2].tag === 'link'); + assert(headChildren[2].rel === 'preload'); + assert(headChildren[2].as === 'script'); + assert(headChildren[2].href.match(/preloaded\..*\.js/)); - assert(headChildren[3].tag === 'link'); - assert(headChildren[3].rel === 'preload'); - assert(headChildren[3].as === 'style'); - assert(headChildren[3].href.match(/preloaded\..*\.css/)); - }); + assert(headChildren[3].tag === 'link'); + assert(headChildren[3].rel === 'preload'); + assert(headChildren[3].as === 'style'); + assert(headChildren[3].href.match(/preloaded\..*\.css/)); + }, + ); // TODO: Implement when we can evaluate bundles against esmodule targets it( 'targetting esmodule, should modulepreload bundles when declared as an import attribute statically', ); - it('should remove import attributes', async () => { + it.v2('should remove import attributes', async () => { let b = await bundle( path.join(__dirname, '/integration/dynamic-import-attributes/index.js'), ); @@ -442,65 +481,74 @@ describe('javascript', function () { assert(!mainBundleContent.includes('foo:')); }); - it('should split bundles when a dynamic import is used with a node environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-node/index.js'), - ); + it.v2( + 'should split bundles when a dynamic import is used with a node environment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-node/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + assets: ['local.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); - it('should split bundles when a dynamic import is used with an electron-main environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-electron-main/index.js'), - ); + it.v2( + 'should split bundles when a dynamic import is used with an electron-main environment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-electron-main/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + assets: ['local.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); - it('should split bundles when a dynamic import is used with an electron-renderer environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-electron-renderer/index.js'), - ); + it.v2( + 'should split bundles when a dynamic import is used with an electron-renderer environment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-electron-renderer/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - assets: ['local.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + assets: ['local.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); it.skip('should load dynamic bundle when entry is in a subdirectory', async function () { let bu = await bundler( @@ -537,101 +585,323 @@ describe('javascript', function () { ]); }); - it('dynamic imports loaded as high-priority scripts when not all engines support esmodules natively', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-imports-high-prio/index.js'), - { - defaultTargetOptions: { - engines: { - browsers: 'IE 11', + it.v2( + 'dynamic imports loaded as high-priority scripts when not all engines support esmodules natively', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-imports-high-prio/index.js'), + { + defaultTargetOptions: { + engines: { + browsers: 'IE 11', + }, }, }, - }, - ); - - let output = await run(b); - let headChildren = await output.default; + ); - assert(headChildren[0].tag === 'link'); - assert(headChildren[0].rel === 'preload'); - assert(headChildren[0].as === 'script'); + let output = await run(b); + let headChildren = await output.default; - assert(headChildren[1].tag === 'script'); - assert(headChildren[1].src.match(/async\..*\.js/)); + assert(headChildren[0].tag === 'link'); + assert(headChildren[0].rel === 'preload'); + assert(headChildren[0].as === 'script'); - assert(headChildren[0].href === headChildren[1].src); - }); + assert(headChildren[1].tag === 'script'); + assert(headChildren[1].src.match(/async\..*\.js/)); - it('should deduplicate and remove an unnecessary async bundle when it contains a cyclic reference to its entry', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/deduplicate-from-async-cyclic-bundle-entry/index.js', - ), - ); + assert(headChildren[0].href === headChildren[1].src); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bar.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'foo.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); + it.v2( + 'should deduplicate and remove an unnecessary async bundle when it contains a cyclic reference to its entry', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/deduplicate-from-async-cyclic-bundle-entry/index.js', + ), + ); - assert.deepEqual(await Promise.all((await run(b)).default), [5, 4]); - }); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bar.js', + 'bundle-url.js', + 'cacheLoader.js', + 'esmodule-helpers.js', + 'foo.js', + 'js-loader.js', + ], + }, + { + assets: ['async.js'], + }, + ]); - it('does not create bundles for dynamic imports when assets are available up the graph', async () => { - let b = await bundle( - path.join(__dirname, '/integration/internalize-no-bundle-split/index.js'), - ); + assert.deepEqual(await Promise.all((await run(b)).default), [5, 4]); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bar.js', 'foo.js', 'esmodule-helpers.js'], - }, - ]); + it.v2( + 'does not create bundles for dynamic imports when assets are available up the graph', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/internalize-no-bundle-split/index.js', + ), + ); - assert.deepEqual(await (await run(b)).default, [3, 3]); - }); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'bar.js', 'foo.js', 'esmodule-helpers.js'], + }, + ]); - it('should dynamic import files which import raw files', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-references-raw/index.js'), - ); + assert.deepEqual(await (await run(b)).default, [3, 3]); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['local.js', 'esmodule-helpers.js'], - }, - { - assets: ['test.txt'], - }, - ]); + it.v2( + 'should dynamic import files which import raw files', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-references-raw/index.js'), + ); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['local.js', 'esmodule-helpers.js'], + }, + { + assets: ['test.txt'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); + + it.v2( + 'should return all exports as an object when using ES modules', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-esm/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'esmodule-helpers.js', + 'js-loader.js', + ], + }, + { + assets: ['local.js'], + }, + ]); + + let output = (await run(b)).default; + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }, + ); + + it.v2( + 'should duplicate small modules across multiple bundles', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-common-small/index.js'), + ); + + assertBundles(b, [ + { + assets: ['a.js', 'common.js', 'common-dep.js'], + }, + { + assets: ['b.js', 'common.js', 'common-dep.js'], + }, + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 7); + }, + ); + + it.v2( + 'should create a separate bundle for large modules shared between bundles', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-common-large/index.js'), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); + + assertBundles(b, [ + { + assets: ['a.js'], + }, + { + assets: ['b.js'], + }, + { + name: 'index.js', + assets: [ + 'index.js', + 'c.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'bundle-manifest.js', + ], + }, + { + assets: ['common.js', 'lodash.js'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 7); + }, + ); + + it.v2( + 'should not duplicate a module which is already in a parent bundle', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-hoist-dup/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'common.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['a.js'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 5); + }, + ); + + it.v2( + 'should duplicate an asset if it is not present in every parent bundle', + async function () { + let b = await bundle( + ['a.js', 'b.js'].map(entry => + path.join(__dirname, 'integration/dynamic-hoist-no-dedupe', entry), + ), + ); + assertBundles(b, [ + { + assets: ['c.js', 'common.js', 'esmodule-helpers.js'], + }, + { + name: 'b.js', + assets: ['b.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], + }, + { + name: 'a.js', + assets: [ + 'a.js', + 'bundle-url.js', + 'common.js', + 'cacheLoader.js', + 'esmodule-helpers.js', + 'js-loader.js', + ], + }, + ]); + }, + ); + + it.v2( + 'should duplicate an asset if it is not available in all possible ancestries', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/dynamic-hoist-no-dedupe-ancestry/index.js', + ), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + { + assets: ['a.js', 'common.js'], + }, + { + assets: ['b.js'], + }, + { + assets: ['c.js'], + }, + { + assets: ['d.js', 'common.js'], + }, + ]); - it('should return all exports as an object when using ES modules', async function () { + let {default: promise} = await run(b); + assert.equal(await promise, 42); + }, + ); + + it.v2('should support shared modules with async imports', async function () { let b = await bundle( - path.join(__dirname, '/integration/dynamic-esm/index.js'), + path.join(__dirname, '/integration/dynamic-hoist-deep/index.js'), ); assertBundles(b, [ @@ -646,877 +916,803 @@ describe('javascript', function () { ], }, { - assets: ['local.js'], + assets: ['a.js', 'c.js'], + }, + { + assets: ['b.js', 'c.js'], + }, + { + assets: ['1.js'], }, ]); - let output = (await run(b)).default; - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); + let {default: promise} = await run(b); + assert.ok(await promise); }); - it('should duplicate small modules across multiple bundles', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-common-small/index.js'), - ); + it.v2('should support requiring JSON files', async function () { + let b = await bundle(path.join(__dirname, '/integration/json/index.js')); assertBundles(b, [ - { - assets: ['a.js', 'common.js', 'common-dep.js'], - }, - { - assets: ['b.js', 'common.js', 'common-dep.js'], - }, { name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], + assets: ['index.js', 'local.json'], }, ]); let output = await run(b); assert.equal(typeof output, 'function'); - assert.equal(await output(), 7); + assert.equal(output(), 3); }); - it('should create a separate bundle for large modules shared between bundles', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-common-large/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, - }, - ); + it.v2('should support requiring JSON5 files', async function () { + let b = await bundle(path.join(__dirname, '/integration/json5/index.js')); assertBundles(b, [ - { - assets: ['a.js'], - }, - { - assets: ['b.js'], - }, { name: 'index.js', - assets: [ - 'index.js', - 'c.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['common.js', 'lodash.js'], + assets: ['index.js', 'local.json5'], }, ]); let output = await run(b); assert.equal(typeof output, 'function'); - assert.equal(await output(), 7); + assert.equal(output(), 3); }); - it('should not duplicate a module which is already in a parent bundle', async function () { + it.v2('should support importing a URL to a raw asset', async function () { let b = await bundle( - path.join(__dirname, '/integration/dynamic-hoist-dup/index.js'), + path.join(__dirname, '/integration/import-raw/index.js'), ); assertBundles(b, [ { name: 'index.js', - assets: [ - 'index.js', - 'common.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], + assets: ['index.js', 'bundle-url.js'], }, { - assets: ['a.js'], + type: 'txt', + assets: ['test.txt'], }, ]); let output = await run(b); assert.equal(typeof output, 'function'); - assert.equal(await output(), 5); - }); - - it('should duplicate an asset if it is not present in every parent bundle', async function () { - let b = await bundle( - ['a.js', 'b.js'].map(entry => - path.join(__dirname, 'integration/dynamic-hoist-no-dedupe', entry), - ), + assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); + let stats = await outputFS.stat( + path.join(distDir, url.parse(output()).pathname), ); - assertBundles(b, [ - { - assets: ['c.js', 'common.js', 'esmodule-helpers.js'], - }, - { - name: 'b.js', - assets: ['b.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - name: 'a.js', - assets: [ - 'a.js', - 'bundle-url.js', - 'common.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - ]); + assert.equal(stats.size, 9); }); - it('should duplicate an asset if it is not available in all possible ancestries', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/dynamic-hoist-no-dedupe-ancestry/index.js', - ), - ); + it.v2( + 'should support referencing a raw asset with static URL and import.meta.url', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/import-raw-import-meta-url/index.js', + ), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - { - assets: ['a.js', 'common.js'], - }, - { - assets: ['b.js'], - }, - { - assets: ['c.js'], - }, - { - assets: ['d.js', 'common.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'bundle-url.js', 'esmodule-helpers.js'], + }, + { + type: 'txt', + assets: ['test.txt'], + }, + ]); - let {default: promise} = await run(b); - assert.equal(await promise, 42); - }); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('import.meta.url')); - it('should support shared modules with async imports', async function () { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-hoist-deep/index.js'), - ); + let output = await run(b); + assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); + let stats = await outputFS.stat( + path.join(distDir, output.default.pathname), + ); + assert.equal(stats.size, 9); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - { - assets: ['a.js', 'c.js'], - }, - { - assets: ['b.js', 'c.js'], - }, - { - assets: ['1.js'], - }, - ]); + it.v2( + 'should support referencing a raw asset with static URL and CJS __filename', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/import-raw-import-meta-url/cjs.js'), + ); - let {default: promise} = await run(b); - assert.ok(await promise); - }); + assertBundles(b, [ + { + name: 'cjs.js', + assets: ['cjs.js', 'bundle-url.js', 'esmodule-helpers.js'], + }, + { + type: 'txt', + assets: ['test.txt'], + }, + ]); - it('should support requiring JSON files', async function () { - let b = await bundle(path.join(__dirname, '/integration/json/index.js')); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('import.meta.url')); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.json'], - }, - ]); + let output = await run(b); + assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); + let stats = await outputFS.stat( + path.join(distDir, output.default.pathname), + ); + assert.equal(stats.size, 9); + }, + ); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); + it.v2( + 'should ignore new URL and import.meta.url with local binding', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/import-raw-import-meta-url/local-url.js', + ), + ); - it('should support requiring JSON5 files', async function () { - let b = await bundle(path.join(__dirname, '/integration/json5/index.js')); + assertBundles(b, [ + { + name: 'local-url.js', + assets: ['esmodule-helpers.js', 'local-url.js'], + }, + ]); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.json5'], - }, - ]); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(contents.includes('"file:///local-url.js"')); + }, + ); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); + it.v2( + 'should throw a codeframe for a missing raw asset with static URL and import.meta.url', + async function () { + let fixture = path.join( + __dirname, + 'integration/import-raw-import-meta-url/missing.js', + ); + let code = await inputFS.readFileSync(fixture, 'utf8'); + await assert.rejects(() => bundle(fixture), { + name: 'BuildError', + diagnostics: [ + { + codeFrames: [ + { + filePath: fixture, + code, + codeHighlights: [ + { + message: undefined, + end: { + column: 36, + line: 1, + }, + start: { + column: 24, + line: 1, + }, + }, + ], + }, + ], + message: "Failed to resolve 'invalid.txt' from './missing.js'", + origin: '@parcel/core', + }, + { + hints: [], + message: "Cannot load file './invalid.txt' in './'.", + origin: '@parcel/resolver-default', + }, + ], + }); + }, + ); - it('should support importing a URL to a raw asset', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw/index.js'), - ); + it.v2( + 'should support importing a URL to a large raw asset', + async function () { + // 6 megabytes, which exceeds the threshold in summarizeRequest for buffering + // entire contents into memory and should stream content instead + let assetSizeBytes = 6000000; + + let distDir = path.join(outputFS.cwd(), '/dist'); + let fixtureDir = path.join(__dirname, '/integration/import-raw'); + let inputDir = path.join(__dirname, 'input'); + + await ncp(fixtureDir, inputDir); + await outputFS.writeFile( + path.join(inputDir, 'test.txt'), + Buffer.alloc(assetSizeBytes), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js'], - }, - { - type: 'txt', - assets: ['test.txt'], + let b = await bundle(path.join(inputDir, 'index.js'), { + inputFS: overlayFS, + defaultTargetOptions: { + distDir, + }, + }); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'bundle-url.js'], + }, + { + type: 'txt', + assets: ['test.txt'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); + let stats = await outputFS.stat( + path.join(distDir, url.parse(output()).pathname), + ); + assert.equal(stats.size, assetSizeBytes); + }, + ); + + it.v2('should minify JS in production mode', async function () { + let b = await bundle(path.join(__dirname, '/integration/uglify/index.js'), { + defaultTargetOptions: { + shouldOptimize: true, + shouldScopeHoist: false, }, - ]); + }); let output = await run(b); assert.equal(typeof output, 'function'); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); - let stats = await outputFS.stat( - path.join(distDir, url.parse(output()).pathname), - ); - assert.equal(stats.size, 9); - }); + assert.equal(output(), 3); - it('should support referencing a raw asset with static URL and import.meta.url', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw-import-meta-url/index.js'), - ); + let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); + assert(!js.includes('local.a')); + }); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js', 'esmodule-helpers.js'], - }, - { - type: 'txt', - assets: ['test.txt'], + it.v2('should use terser config', async function () { + await bundle(path.join(__dirname, '/integration/terser-config/index.js'), { + defaultTargetOptions: { + shouldOptimize: true, + shouldScopeHoist: false, }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('import.meta.url')); + }); - let output = await run(b); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); - let stats = await outputFS.stat( - path.join(distDir, output.default.pathname), - ); - assert.equal(stats.size, 9); + let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); + assert(!js.includes('console.log')); + assert(!js.includes('// This is a comment')); }); - it('should support referencing a raw asset with static URL and CJS __filename', async function () { - let b = await bundle( - path.join(__dirname, '/integration/import-raw-import-meta-url/cjs.js'), - ); - - assertBundles(b, [ - { - name: 'cjs.js', - assets: ['cjs.js', 'bundle-url.js', 'esmodule-helpers.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('import.meta.url')); + it.v2('should insert global variables when needed', async function () { + let b = await bundle(path.join(__dirname, '/integration/globals/index.js')); let output = await run(b); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.default)); - let stats = await outputFS.stat( - path.join(distDir, output.default.pathname), - ); - assert.equal(stats.size, 9); + assert.deepEqual(output(), { + dir: 'integration/globals', + file: 'integration/globals/index.js', + buf: Buffer.from('browser').toString('base64'), + global: true, + }); }); - it('should ignore new URL and import.meta.url with local binding', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/import-raw-import-meta-url/local-url.js', - ), - ); - - assertBundles(b, [ - { - name: 'local-url.js', - assets: ['esmodule-helpers.js', 'local-url.js'], - }, - ]); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(contents.includes('"file:///local-url.js"')); - }); + it.v2( + 'should replace __dirname and __filename with path relative to asset.filePath', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-node-replacements/index.js'), + ); - it('should throw a codeframe for a missing raw asset with static URL and import.meta.url', async function () { - let fixture = path.join( - __dirname, - 'integration/import-raw-import-meta-url/missing.js', - ); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects(() => bundle(fixture), { - name: 'BuildError', - diagnostics: [ - { - codeFrames: [ - { - filePath: fixture, - code, - codeHighlights: [ - { - message: undefined, - end: { - column: 36, - line: 1, - }, - start: { - column: 24, - line: 1, - }, - }, - ], - }, - ], - message: "Failed to resolve 'invalid.txt' from './missing.js'", - origin: '@parcel/core', + let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert( + dist.includes( + 'resolve(__dirname, "../test/integration/env-node-replacements")', + ), + ); + assert( + dist.includes( + 'resolve(__dirname, "../test/integration/env-node-replacements/other")', + ), + ); + assert( + dist.includes( + 'resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', + ), + ); + assert( + dist.includes( + 'resolve(__dirname, "../test/integration/env-node-replacements/sub")', + ), + ); + assert( + dist.includes( + 'resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', + ), + ); + let f = await run(b); + let output = f(); + assert.equal(output.data, 'hello'); + assert.equal(output.other, 'hello'); + assert.equal( + output.firstDirnameTest, + path.join(__dirname, '/integration/env-node-replacements/data'), + ); + assert.equal( + output.secondDirnameTest, + path.join(__dirname, '/integration/env-node-replacements/other-data'), + ); + assert.equal( + output.firstFilenameTest, + path.join(__dirname, '/integration/env-node-replacements/index.js'), + ); + assert.equal( + output.secondFilenameTest, + path.join( + __dirname, + '/integration/env-node-replacements/index.js?query-string=test', + ), + ); + assert.equal( + output.sub.dirname, + path.join(__dirname, '/integration/env-node-replacements/sub'), + ); + assert.equal( + output.sub.filename, + path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), + ); + }, + ); + + it.v2( + 'should replace __dirname and __filename with path relative to asset.filePath with scope hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-node-replacements/index.js'), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: true, + shouldOptimize: false, + }, }, + ); + + let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert( + dist.includes( + 'path.resolve(__dirname, "../test/integration/env-node-replacements")', + ), + ); + assert( + dist.includes( + 'path.resolve(__dirname, "../test/integration/env-node-replacements/other")', + ), + ); + assert( + dist.includes( + 'path.resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', + ), + ); + assert( + dist.includes( + 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub")', + ), + ); + assert( + dist.includes( + 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', + ), + ); + let f = await run(b); + let output = f(); + assert.equal(output.data, 'hello'); + assert.equal(output.other, 'hello'); + assert.equal( + output.firstDirnameTest, + path.join(__dirname, '/integration/env-node-replacements/data'), + ); + assert.equal( + output.secondDirnameTest, + path.join(__dirname, '/integration/env-node-replacements/other-data'), + ); + assert.equal( + output.firstFilenameTest, + path.join(__dirname, '/integration/env-node-replacements/index.js'), + ); + assert.equal( + output.secondFilenameTest, + path.join( + __dirname, + '/integration/env-node-replacements/index.js?query-string=test', + ), + ); + assert.equal( + output.sub.dirname, + path.join(__dirname, '/integration/env-node-replacements/sub'), + ); + assert.equal( + output.sub.filename, + path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), + ); + }, + ); + + it.v2( + 'should work when multiple files use globals with scope hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/globals/multiple.js'), { - hints: [], - message: "Cannot load file './invalid.txt' in './'.", - origin: '@parcel/resolver-default', + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: true, + shouldOptimize: false, + }, }, - ], - }); - }); + ); - it('should support importing a URL to a large raw asset', async function () { - // 6 megabytes, which exceeds the threshold in summarizeRequest for buffering - // entire contents into memory and should stream content instead - let assetSizeBytes = 6000000; + let output = await run(b); + assert.deepEqual(output, { + file: 'integration/globals/multiple.js', + other: 'integration/globals/index.js', + }); + }, + ); - let distDir = path.join(outputFS.cwd(), '/dist'); - let fixtureDir = path.join(__dirname, '/integration/import-raw'); - let inputDir = path.join(__dirname, 'input'); + it.v2( + 'should not insert global variables when used in a module specifier', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/globals-module-specifier/a.js'), + ); - await ncp(fixtureDir, inputDir); - await outputFS.writeFile( - path.join(inputDir, 'test.txt'), - Buffer.alloc(assetSizeBytes), - ); + assertBundles(b, [ + { + assets: ['a.js', 'b.js', 'c.js', 'esmodule-helpers.js'], + }, + ]); - let b = await bundle(path.join(inputDir, 'index.js'), { - inputFS: overlayFS, - defaultTargetOptions: { - distDir, - }, - }); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'bundle-url.js'], - }, - { - type: 'txt', - assets: ['test.txt'], - }, - ]); + let output = await run(b); + assert.deepEqual(output, 1234); + }, + ); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert(/^http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output())); - let stats = await outputFS.stat( - path.join(distDir, url.parse(output()).pathname), - ); - assert.equal(stats.size, assetSizeBytes); - }); + it.v2( + 'should not insert global variables in dead branches', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/globals-unused/a.js'), + ); - it('should minify JS in production mode', async function () { - let b = await bundle(path.join(__dirname, '/integration/uglify/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); + assertBundles(b, [ + { + assets: ['a.js'], + }, + ]); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); + let output = await run(b); + assert.deepEqual(output, 'foo'); + }, + ); - let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(!js.includes('local.a')); - }); + it.v2( + 'should handle re-declaration of the global constant', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/global-redeclare/index.js'), + ); - it('should use terser config', async function () { - await bundle(path.join(__dirname, '/integration/terser-config/index.js'), { - defaultTargetOptions: { - shouldOptimize: true, - shouldScopeHoist: false, - }, - }); + let output = await run(b); + assert.deepEqual(output(), false); + }, + ); - let js = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); - assert(!js.includes('console.log')); - assert(!js.includes('// This is a comment')); - }); + it.v2( + 'should insert environment variables inserted by a prior transform', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/env-prior-transform/index.js'), + ); - it('should insert global variables when needed', async function () { - let b = await bundle(path.join(__dirname, '/integration/globals/index.js')); + let jsBundle = b.getBundles()[0]; + let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - let output = await run(b); - assert.deepEqual(output(), { - dir: 'integration/globals', - file: 'integration/globals/index.js', - buf: Buffer.from('browser').toString('base64'), - global: true, - }); - }); + assert(!contents.includes('process.env')); + assert.equal(await run(b), 'test'); + }, + ); - it('should replace __dirname and __filename with path relative to asset.filePath', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); + it.v2( + 'should not insert environment variables in node environment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-node/index.js'), + ); - let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/other")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/sub")', - ), - ); - assert( - dist.includes( - 'resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', - ), - ); - let f = await run(b); - let output = f(); - assert.equal(output.data, 'hello'); - assert.equal(output.other, 'hello'); - assert.equal( - output.firstDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/data'), - ); - assert.equal( - output.secondDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/other-data'), - ); - assert.equal( - output.firstFilenameTest, - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); - assert.equal( - output.secondFilenameTest, - path.join( - __dirname, - '/integration/env-node-replacements/index.js?query-string=test', - ), - ); - assert.equal( - output.sub.dirname, - path.join(__dirname, '/integration/env-node-replacements/sub'), - ); - assert.equal( - output.sub.filename, - path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), - ); - }); + let output = await run(b); + assert.ok(output.toString().includes('process.env')); + assert.equal(output(), 'test:test'); + }, + ); - it('should replace __dirname and __filename with path relative to asset.filePath with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node-replacements/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: false, - }, - }, - ); + it.v2( + 'should not replace process.env.hasOwnProperty with undefined', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-hasOwnProperty/index.js'), + ); - let dist = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/other")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements", "index.js")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub")', - ), - ); - assert( - dist.includes( - 'path.resolve(__dirname, "../test/integration/env-node-replacements/sub", "index.js")', - ), - ); - let f = await run(b); - let output = f(); - assert.equal(output.data, 'hello'); - assert.equal(output.other, 'hello'); - assert.equal( - output.firstDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/data'), - ); - assert.equal( - output.secondDirnameTest, - path.join(__dirname, '/integration/env-node-replacements/other-data'), - ); - assert.equal( - output.firstFilenameTest, - path.join(__dirname, '/integration/env-node-replacements/index.js'), - ); - assert.equal( - output.secondFilenameTest, - path.join( - __dirname, - '/integration/env-node-replacements/index.js?query-string=test', - ), - ); - assert.equal( - output.sub.dirname, - path.join(__dirname, '/integration/env-node-replacements/sub'), - ); - assert.equal( - output.sub.filename, - path.join(__dirname, '/integration/env-node-replacements/sub/index.js'), - ); - }); + let output = await run(b); + assert.strictEqual(output, false); + }, + ); - it('should work when multiple files use globals with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals/multiple.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: false, + it.v2( + 'should not insert environment variables in electron-main environment', + async function () { + let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { + targets: { + main: { + context: 'electron-main', + distDir: path.join(__dirname, '/integration/env/dist.js'), + }, }, - }, - ); + }); - let output = await run(b); - assert.deepEqual(output, { - file: 'integration/globals/multiple.js', - other: 'integration/globals/index.js', - }); - }); + let output = await run(b); + assert.ok(output.toString().includes('process.env')); + assert.equal(output(), 'test:test'); + }, + ); - it('should not insert global variables when used in a module specifier', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals-module-specifier/a.js'), - ); - - assertBundles(b, [ - { - assets: ['a.js', 'b.js', 'c.js', 'esmodule-helpers.js'], - }, - ]); - - let output = await run(b); - assert.deepEqual(output, 1234); - }); - - it('should not insert global variables in dead branches', async function () { - let b = await bundle( - path.join(__dirname, '/integration/globals-unused/a.js'), - ); - - assertBundles(b, [ - { - assets: ['a.js'], - }, - ]); - - let output = await run(b); - assert.deepEqual(output, 'foo'); - }); - - it('should handle re-declaration of the global constant', async function () { - let b = await bundle( - path.join(__dirname, '/integration/global-redeclare/index.js'), - ); - - let output = await run(b); - assert.deepEqual(output(), false); - }); - - it('should insert environment variables inserted by a prior transform', async () => { - let b = await bundle( - path.join(__dirname, '/integration/env-prior-transform/index.js'), - ); - - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - - assert(!contents.includes('process.env')); - assert.equal(await run(b), 'test'); - }); - - it('should not insert environment variables in node environment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-node/index.js'), - ); - - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); - - it('should not replace process.env.hasOwnProperty with undefined', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-hasOwnProperty/index.js'), - ); - - let output = await run(b); - assert.strictEqual(output, false); - }); - - it('should not insert environment variables in electron-main environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - targets: { - main: { - context: 'electron-main', - distDir: path.join(__dirname, '/integration/env/dist.js'), + it.v2( + 'should not insert environment variables in electron-renderer environment', + async function () { + let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { + targets: { + main: { + context: 'electron-renderer', + distDir: path.join(__dirname, '/integration/env/dist.js'), + }, }, - }, - }); + }); - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); + let output = await run(b); + assert.ok(output.toString().includes('process.env')); + assert.equal(output(), 'test:test'); + }, + ); - it('should not insert environment variables in electron-renderer environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - targets: { - main: { - context: 'electron-renderer', - distDir: path.join(__dirname, '/integration/env/dist.js'), + it.v2( + 'should inline NODE_ENV environment variable in browser environment even if disabled', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-nodeenv/index.js'), + { + env: { + FOO: 'abc', + }, }, - }, - }); + ); - let output = await run(b); - assert.ok(output.toString().includes('process.env')); - assert.equal(output(), 'test:test'); - }); + let output = await run(b); + assert.ok(!output.toString().includes('process.env')); + assert.equal(output(), 'test:undefined'); + }, + ); - it('should inline NODE_ENV environment variable in browser environment even if disabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-nodeenv/index.js'), - { - env: { - FOO: 'abc', + it.v2( + 'should not insert environment variables in browser environment if disabled', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-disabled/index.js'), + { + env: {FOOBAR: 'abc'}, }, - }, - ); - - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'test:undefined'); - }); - - it('should not insert environment variables in browser environment if disabled', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-disabled/index.js'), - { - env: {FOOBAR: 'abc'}, - }, - ); + ); - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'undefined:undefined:undefined'); - }); + let output = await run(b); + assert.ok(!output.toString().includes('process.env')); + assert.equal(output(), 'undefined:undefined:undefined'); + }, + ); - it('should only insert environment variables in browser environment matching the glob', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-disabled-glob/index.js'), - { - env: {A_1: 'abc', B_1: 'def', B_2: 'ghi'}, - }, - ); + it.v2( + 'should only insert environment variables in browser environment matching the glob', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-disabled-glob/index.js'), + { + env: {A_1: 'abc', B_1: 'def', B_2: 'ghi'}, + }, + ); - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'undefined:def:ghi'); - }); + let output = await run(b); + assert.ok(!output.toString().includes('process.env')); + assert.equal(output(), 'undefined:def:ghi'); + }, + ); - it('should be able to inline environment variables in browser environment', async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - env: {NODE_ENV: 'abc'}, - }); + it.v2( + 'should be able to inline environment variables in browser environment', + async function () { + let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { + env: {NODE_ENV: 'abc'}, + }); - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'abc:abc'); - }); + let output = await run(b); + assert.ok(!output.toString().includes('process.env')); + assert.equal(output(), 'abc:abc'); + }, + ); - it("should insert the user's NODE_ENV as process.env.NODE_ENV if passed", async function () { - let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { - env: { - NODE_ENV: 'production', - }, - }); + it.v2( + "should insert the user's NODE_ENV as process.env.NODE_ENV if passed", + async function () { + let b = await bundle(path.join(__dirname, '/integration/env/index.js'), { + env: { + NODE_ENV: 'production', + }, + }); - let output = await run(b); - assert.ok(!output.toString().includes('process.env')); - assert.equal(output(), 'production:production'); - }); + let output = await run(b); + assert.ok(!output.toString().includes('process.env')); + assert.equal(output(), 'production:production'); + }, + ); - it('should not inline computed accesses to process.env', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-computed/index.js'), - { - env: {ABC: 'abc'}, - }, - ); + it.v2( + 'should not inline computed accesses to process.env', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-computed/index.js'), + { + env: {ABC: 'abc'}, + }, + ); - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(contents.includes('process.env')); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(contents.includes('process.env')); - let output = await run(b); - assert.strictEqual(output, undefined); - }); + let output = await run(b); + assert.strictEqual(output, undefined); + }, + ); - it('should inline computed accesses with string literals to process.env', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-computed-string/index.js'), - { - env: {ABC: 'XYZ'}, - }, - ); + it.v2( + 'should inline computed accesses with string literals to process.env', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-computed-string/index.js'), + { + env: {ABC: 'XYZ'}, + }, + ); - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('process.env')); - let output = await run(b); - assert.strictEqual(output, 'XYZ'); - }); + let output = await run(b); + assert.strictEqual(output, 'XYZ'); + }, + ); - it('should inline environment variables when destructured in a variable declaration', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-destructuring/index.js'), - { - env: {TEST: 'XYZ'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', + it.v2( + 'should inline environment variables when destructured in a variable declaration', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-destructuring/index.js'), + { + env: {TEST: 'XYZ'}, + defaultTargetOptions: { + engines: { + browsers: '>= 0.25%', + }, }, }, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); + ); - let output = await run(b); - assert.deepEqual(output, { - env: {}, - NODE_ENV: 'test', - renamed: 'XYZ', - computed: undefined, - fallback: 'yo', - rest: {}, - other: 'hi', - }); - }); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('process.env')); + + let output = await run(b); + assert.deepEqual(output, { + env: {}, + NODE_ENV: 'test', + renamed: 'XYZ', + computed: undefined, + fallback: 'yo', + rest: {}, + other: 'hi', + }); + }, + ); - it('should inline environment variables when destructured in an assignment', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-destructuring/assign.js'), - { - env: {TEST: 'XYZ'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', + it.v2( + 'should inline environment variables when destructured in an assignment', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-destructuring/assign.js'), + { + env: {TEST: 'XYZ'}, + defaultTargetOptions: { + engines: { + browsers: '>= 0.25%', + }, }, }, - }, - ); - - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); + ); - let output = await run(b); - assert.deepEqual(output, { - env: {}, - NODE_ENV: 'test', - renamed: 'XYZ', - computed: undefined, - fallback: 'yo', - rest: {}, - result: {}, - }); - }); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('process.env')); + + let output = await run(b); + assert.deepEqual(output, { + env: {}, + NODE_ENV: 'test', + renamed: 'XYZ', + computed: undefined, + fallback: 'yo', + rest: {}, + result: {}, + }); + }, + ); - it('should inline environment variables with in binary expression whose right branch is process.env and left branch is string literal', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-binary-in-expression/index.js'), - { - env: {ABC: 'any'}, - defaultTargetOptions: { - engines: { - browsers: '>= 0.25%', + it.v2( + 'should inline environment variables with in binary expression whose right branch is process.env and left branch is string literal', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-binary-in-expression/index.js'), + { + env: {ABC: 'any'}, + defaultTargetOptions: { + engines: { + browsers: '>= 0.25%', + }, }, }, - }, - ); + ); - let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!contents.includes('process.env')); + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + assert(!contents.includes('process.env')); - let output = await run(b); - assert.deepEqual(output, { - existVar: 'correct', - notExistVar: 'correct', - }); - }); + let output = await run(b); + assert.deepEqual(output, { + existVar: 'correct', + notExistVar: 'correct', + }); + }, + ); - it('should insert environment variables from a file', async function () { + it.v2('should insert environment variables from a file', async function () { let b = await bundle( path.join(__dirname, '/integration/env-file/index.js'), ); @@ -1528,36 +1724,45 @@ describe('javascript', function () { assert.equal(output, 'bartest'); }); - it("should insert environment variables matching the user's NODE_ENV if passed", async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file/index.js'), - {env: {NODE_ENV: 'production'}}, - ); + it.v2( + "should insert environment variables matching the user's NODE_ENV if passed", + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-file/index.js'), + {env: {NODE_ENV: 'production'}}, + ); - let output = await run(b); - assert.equal(output, 'productiontest'); - }); + let output = await run(b); + assert.equal(output, 'productiontest'); + }, + ); - it('should overwrite environment variables from a file if passed', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file/index.js'), - {env: {BAR: 'baz'}}, - ); + it.v2( + 'should overwrite environment variables from a file if passed', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-file/index.js'), + {env: {BAR: 'baz'}}, + ); - let output = await run(b); - assert.equal(output, 'barbaz'); - }); + let output = await run(b); + assert.equal(output, 'barbaz'); + }, + ); - it('should insert environment variables from a file even if entry file is specified with source value in package.json', async function () { - let b = await bundle( - path.join(__dirname, '/integration/env-file-with-package-source'), - ); + it.v2( + 'should insert environment variables from a file even if entry file is specified with source value in package.json', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/env-file-with-package-source'), + ); - let output = await run(b); - assert.equal(output, 'bartest'); - }); + let output = await run(b); + assert.equal(output, 'bartest'); + }, + ); - it('should error on process.env mutations', async function () { + it.v2('should error on process.env mutations', async function () { let filePath = path.join(__dirname, '/integration/env-mutate/index.js'); await assert.rejects(bundle(filePath), { diagnostics: [ @@ -1657,115 +1862,118 @@ describe('javascript', function () { }); }); - it('should warn on process.env mutations in node_modules', async function () { - let logs = []; - let disposable = Logger.onLog(d => { - if (d.level !== 'verbose') { - logs.push(d); - } - }); - let b = await bundle( - path.join(__dirname, '/integration/env-mutate/warn.js'), - ); - disposable.dispose(); + it.v2( + 'should warn on process.env mutations in node_modules', + async function () { + let logs = []; + let disposable = Logger.onLog(d => { + if (d.level !== 'verbose') { + logs.push(d); + } + }); + let b = await bundle( + path.join(__dirname, '/integration/env-mutate/warn.js'), + ); + disposable.dispose(); - assert.deepEqual(logs, [ - { - type: 'log', - level: 'warn', - diagnostics: [ - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 8, + assert.deepEqual(logs, [ + { + type: 'log', + level: 'warn', + diagnostics: [ + { + origin: '@parcel/transformer-js', + message: 'Mutating process.env is not supported', + hints: null, + codeFrames: [ + { + filePath: path.join( + __dirname, + '/integration/env-mutate/node_modules/foo/index.js', + ), + codeHighlights: [ + { + message: undefined, + start: { + line: 1, + column: 8, + }, + end: { + line: 1, + column: 36, + }, }, - end: { - line: 1, - column: 36, + ], + }, + ], + }, + { + origin: '@parcel/transformer-js', + message: 'Mutating process.env is not supported', + hints: null, + codeFrames: [ + { + filePath: path.join( + __dirname, + '/integration/env-mutate/node_modules/foo/index.js', + ), + codeHighlights: [ + { + message: undefined, + start: { + line: 2, + column: 8, + }, + end: { + line: 2, + column: 35, + }, }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 2, - column: 8, - }, - end: { - line: 2, - column: 35, - }, - }, - ], - }, - ], - }, - { - origin: '@parcel/transformer-js', - message: 'Mutating process.env is not supported', - hints: null, - codeFrames: [ - { - filePath: path.join( - __dirname, - '/integration/env-mutate/node_modules/foo/index.js', - ), - codeHighlights: [ - { - message: undefined, - start: { - line: 3, - column: 8, - }, - end: { - line: 3, - column: 30, + ], + }, + ], + }, + { + origin: '@parcel/transformer-js', + message: 'Mutating process.env is not supported', + hints: null, + codeFrames: [ + { + filePath: path.join( + __dirname, + '/integration/env-mutate/node_modules/foo/index.js', + ), + codeHighlights: [ + { + message: undefined, + start: { + line: 3, + column: 8, + }, + end: { + line: 3, + column: 30, + }, }, - }, - ], - }, - ], - }, - ], - }, - ]); + ], + }, + ], + }, + ], + }, + ]); - let output = []; - await run(b, { - output(o) { - output.push(o); - }, - }); - assert.deepEqual(output, ['foo', true, undefined]); - }); + let output = []; + await run(b, { + output(o) { + output.push(o); + }, + }); + assert.deepEqual(output, ['foo', true, undefined]); + }, + ); - it('should replace process.browser for target browser', async function () { + it.v2('should replace process.browser for target browser', async function () { let b = await bundle( path.join(__dirname, '/integration/process/index.js'), { @@ -1783,7 +1991,7 @@ describe('javascript', function () { assert.equal(output(), true); }); - it('should not touch process.browser for target node', async function () { + it.v2('should not touch process.browser for target node', async function () { let b = await bundle( path.join(__dirname, '/integration/process/index.js'), { @@ -1801,44 +2009,50 @@ describe('javascript', function () { assert.equal(output(), false); }); - it('should not touch process.browser for target electron-main', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'electron-main', - distDir: path.join(__dirname, '/integration/process/dist.js'), + it.v2( + 'should not touch process.browser for target electron-main', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/process/index.js'), + { + targets: { + main: { + context: 'electron-main', + distDir: path.join(__dirname, '/integration/process/dist.js'), + }, }, }, - }, - ); + ); - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') !== -1); - assert.equal(output(), false); - }); + let output = await run(b); + assert.ok(output.toString().indexOf('process.browser') !== -1); + assert.equal(output(), false); + }, + ); - it('should replace process.browser for target electron-renderer', async function () { - let b = await bundle( - path.join(__dirname, '/integration/process/index.js'), - { - targets: { - main: { - context: 'electron-renderer', - distDir: path.join(__dirname, '/integration/process/dist.js'), + it.v2( + 'should replace process.browser for target electron-renderer', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/process/index.js'), + { + targets: { + main: { + context: 'electron-renderer', + distDir: path.join(__dirname, '/integration/process/dist.js'), + }, }, }, - }, - ); + ); - let output = await run(b); - assert.ok(output.toString().indexOf('process.browser') === -1); - assert.equal(output(), true); - // Running the bundled code has the side effect of setting process.browser = true, which can mess - // up the instantiation of typescript.sys within validator-typescript, so we want to reset it. - process.browser = undefined; - }); + let output = await run(b); + assert.ok(output.toString().indexOf('process.browser') === -1); + assert.equal(output(), true); + // Running the bundled code has the side effect of setting process.browser = true, which can mess + // up the instantiation of typescript.sys within validator-typescript, so we want to reset it. + process.browser = undefined; + }, + ); it.skip('should support adding implicit dependencies', async function () { let b = await bundle(path.join(__dirname, '/integration/json/index.js'), { @@ -1870,7 +2084,7 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should support requiring YAML files', async function () { + it.v2('should support requiring YAML files', async function () { let b = await bundle(path.join(__dirname, '/integration/yaml/index.js')); assertBundles(b, [ @@ -1890,7 +2104,7 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should support requiring TOML files', async function () { + it.v2('should support requiring TOML files', async function () { let b = await bundle(path.join(__dirname, '/integration/toml/index.js')); assertBundles(b, [ @@ -1910,7 +2124,7 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should support requiring CoffeeScript files', async function () { + it.v2('should support requiring CoffeeScript files', async function () { let b = await bundle(path.join(__dirname, '/integration/coffee/index.js')); assertBundles(b, [ @@ -1925,7 +2139,7 @@ describe('javascript', function () { assert.equal(output(), 3); }); - it('should resolve the browser field before main', async function () { + it.v2('should resolve the browser field before main', async function () { let b = await bundle( path.join(__dirname, '/integration/resolve-entries/browser.js'), ); @@ -1943,33 +2157,42 @@ describe('javascript', function () { assert.equal(output.test(), 'pkg-browser'); }); - it('should exclude resolving specifiers that map to false in the browser field in browser builds', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/resolve-entries/pkg-ignore-browser/index.js', - ), - { - targets: ['browsers'], - }, - ); + it.v2( + 'should exclude resolving specifiers that map to false in the browser field in browser builds', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/resolve-entries/pkg-ignore-browser/index.js', + ), + { + targets: ['browsers'], + }, + ); - assert.deepEqual(await run(b), {}); - }); + assert.deepEqual(await run(b), {}); + }, + ); - it('should not exclude resolving specifiers that map to false in the browser field in node builds', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/resolve-entries/pkg-ignore-browser/index.js', - ), - { - targets: ['node'], - }, - ); + it.v2( + 'should not exclude resolving specifiers that map to false in the browser field in node builds', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/resolve-entries/pkg-ignore-browser/index.js', + ), + { + targets: ['node'], + }, + ); - assert.equal(await run(b), 'this should only exist in non-browser builds'); - }); + assert.equal( + await run(b), + 'this should only exist in non-browser builds', + ); + }, + ); it.skip('should not resolve the browser field for --target=node', async function () { let b = await bundle( @@ -2094,7 +2317,7 @@ describe('javascript', function () { assert.equal(output.test(), 'pkg-es6-module'); }); - it('should resolve the main field', async function () { + it.v2('should resolve the main field', async function () { let b = await bundle( path.join(__dirname, '/integration/resolve-entries/main-field.js'), ); @@ -2112,7 +2335,7 @@ describe('javascript', function () { assert.equal(output.test(), 'pkg-main-module'); }); - it('should minify JSON files', async function () { + it.v2('should minify JSON files', async function () { let b = await bundle( path.join(__dirname, '/integration/uglify-json/index.json'), { @@ -2130,7 +2353,7 @@ describe('javascript', function () { assert.deepEqual(output, {test: 'test'}); }); - it('should minify JSON5 files', async function () { + it.v2('should minify JSON5 files', async function () { let b = await bundle( path.join(__dirname, '/integration/uglify-json5/index.json5'), { @@ -2164,7 +2387,7 @@ describe('javascript', function () { assert(json.includes('{a:1,b:{c:2}}')); }); - it('should minify TOML for production', async function () { + it.v2('should minify TOML for production', async function () { let b = await bundle(path.join(__dirname, '/integration/toml/index.js'), { defaultTargetOptions: { shouldOptimize: true, @@ -2180,43 +2403,49 @@ describe('javascript', function () { assert(json.includes('{a:1,b:{c:2}}')); }); - it('should support optional dependencies in try...catch blocks', async function () { - let b = await bundle( - path.join(__dirname, '/integration/optional-dep/index.js'), - ); + it.v2( + 'should support optional dependencies in try...catch blocks', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/optional-dep/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + ]); - let output = await run(b); + let output = await run(b); - assert.equal(Object.getPrototypeOf(output).constructor.name, 'Error'); - assert( - /Cannot find module ['"]optional-dep['"]/.test(output.message), - 'Should set correct error message', - ); - assert.equal(output.code, 'MODULE_NOT_FOUND'); - }); + assert.equal(Object.getPrototypeOf(output).constructor.name, 'Error'); + assert( + /Cannot find module ['"]optional-dep['"]/.test(output.message), + 'Should set correct error message', + ); + assert.equal(output.code, 'MODULE_NOT_FOUND'); + }, + ); - it('should support excluding dependencies in falsy branches', async function () { - let b = await bundle( - path.join(__dirname, '/integration/falsy-dep/index.js'), - ); + it.v2( + 'should support excluding dependencies in falsy branches', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/falsy-dep/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'true-alternate.js', 'true-consequent.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'true-alternate.js', 'true-consequent.js'], + }, + ]); - let output = await run(b); - assert.equal(output, 2); - }); + let output = await run(b); + assert.equal(output, 2); + }, + ); it.skip('should not autoinstall if resolve failed on installed module', async function () { let error; @@ -2256,30 +2485,33 @@ describe('javascript', function () { assert.equal(error.code, 'MODULE_NOT_FOUND'); }); - it('should ignore require if it is defined in the scope', async function () { - let b = await bundle( - path.join(__dirname, '/integration/require-scope/index.js'), - ); + it.v2( + 'should ignore require if it is defined in the scope', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/require-scope/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + ]); - let output = await run(b); + let output = await run(b); - assert.equal(typeof output.test, 'object'); + assert.equal(typeof output.test, 'object'); - let failed = Object.keys(output.test).some( - key => output.test[key] !== 'test passed', - ); + let failed = Object.keys(output.test).some( + key => output.test[key] !== 'test passed', + ); - assert.equal(failed, false); - }); + assert.equal(failed, false); + }, + ); - it('should expose to CommonJS entry point', async function () { + it.v2('should expose to CommonJS entry point', async function () { let b = await bundle( path.join(__dirname, '/integration/entry-point/index.js'), ); @@ -2289,7 +2521,7 @@ describe('javascript', function () { assert.equal(module.exports(), 'Test!'); }); - it('should expose to RequireJS entry point', async function () { + it.v2('should expose to RequireJS entry point', async function () { let b = await bundle( path.join(__dirname, '/integration/entry-point/index.js'), ); @@ -2329,112 +2561,138 @@ describe('javascript', function () { assert.equal(test, 2); }); - it('should package successfully with comments on last line', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - ); + it.v2( + 'should package successfully with comments on last line', + async function () { + let b = await bundle( + path.join(__dirname, `/integration/js-comment/index.js`), + ); - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); + let output = await run(b); + assert.equal(output, 'Hello World!'); + }, + ); - it('should package successfully with comments on last line and minification', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - ); + it.v2( + 'should package successfully with comments on last line and minification', + async function () { + let b = await bundle( + path.join(__dirname, `/integration/js-comment/index.js`), + ); - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); + let output = await run(b); + assert.equal(output, 'Hello World!'); + }, + ); - it('should package successfully with comments on last line and scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - { - defaultTargetOptions: { - shouldScopeHoist: true, + it.v2( + 'should package successfully with comments on last line and scope hoisting', + async function () { + let b = await bundle( + path.join(__dirname, `/integration/js-comment/index.js`), + { + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); + ); - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); + let output = await run(b); + assert.equal(output, 'Hello World!'); + }, + ); - it('should package successfully with comments on last line, scope hoisting and minification', async function () { - let b = await bundle( - path.join(__dirname, `/integration/js-comment/index.js`), - { - defaultTargetOptions: { - shouldScopeHoist: true, - shouldOptimize: true, + it.v2( + 'should package successfully with comments on last line, scope hoisting and minification', + async function () { + let b = await bundle( + path.join(__dirname, `/integration/js-comment/index.js`), + { + defaultTargetOptions: { + shouldScopeHoist: true, + shouldOptimize: true, + }, }, - }, - ); + ); - let output = await run(b); - assert.equal(output, 'Hello World!'); - }); + let output = await run(b); + assert.equal(output, 'Hello World!'); + }, + ); - it('should not replace toplevel this with undefined in CommonJS without scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-commonjs/a.js'), - ); + it.v2( + 'should not replace toplevel this with undefined in CommonJS without scope-hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/js-this-commonjs/a.js'), + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [{foo: 2}, 1234]); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, [{foo: 2}, 1234]); + }, + ); - it('should not replace toplevel this with undefined in CommonJS when scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-commonjs/a.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, + it.v2( + 'should not replace toplevel this with undefined in CommonJS when scope-hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/js-this-commonjs/a.js'), + { + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [{foo: 2}, 1234]); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, [{foo: 2}, 1234]); + }, + ); - it('should replace toplevel this with undefined in ESM without scope-hoisting', async function () { - let b = await bundle(path.join(__dirname, '/integration/js-this-es6/a.js')); + it.v2( + 'should replace toplevel this with undefined in ESM without scope-hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/js-this-es6/a.js'), + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [undefined, 1234]); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, [undefined, 1234]); + }, + ); - it('should replace toplevel this with undefined in ESM when scope-hoisting', async function () { - let b = await bundle( - path.join(__dirname, '/integration/js-this-es6/a.js'), - { - defaultTargetOptions: { - shouldScopeHoist: true, + it.v2( + 'should replace toplevel this with undefined in ESM when scope-hoisting', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/js-this-es6/a.js'), + { + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, [undefined, 1234]); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, [undefined, 1234]); + }, + ); it.skip('should not dedupe imports with different contents', async function () { let b = await bundle( @@ -2638,239 +2896,286 @@ describe('javascript', function () { await run(b); }); - it('should support async importing the same module from different bundles', async () => { - let b = await bundle( - path.join(__dirname, '/integration/shared-bundlegroup/index.js'), - ); + it.v2( + 'should support async importing the same module from different bundles', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/shared-bundlegroup/index.js'), + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'esmodule-helpers.js', - 'js-loader.js', - ], - }, - { - assets: ['a.js'], - }, - { - assets: ['b.js'], - }, - { - assets: ['c.js'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'esmodule-helpers.js', + 'js-loader.js', + ], + }, + { + assets: ['a.js'], + }, + { + assets: ['b.js'], + }, + { + assets: ['c.js'], + }, + ]); - let {default: promise} = await run(b); - assert.deepEqual(await promise, ['hello from a test', 'hello from b test']); - }); + let {default: promise} = await run(b); + assert.deepEqual(await promise, [ + 'hello from a test', + 'hello from b test', + ]); + }, + ); - it('should not create shared bundles from contents of entries', async () => { - let b = await bundle( - ['a.js', 'b.js'].map(entry => - path.join( - __dirname, - '/integration/no-shared-bundles-from-entries/', - entry, + it.v2( + 'should not create shared bundles from contents of entries', + async () => { + let b = await bundle( + ['a.js', 'b.js'].map(entry => + path.join( + __dirname, + '/integration/no-shared-bundles-from-entries/', + entry, + ), ), - ), - ); + ); - assertBundles(b, [ - { - name: 'a.js', - assets: ['a.js', 'esmodule-helpers.js', 'lodash.js'], - }, - { - name: 'b.js', - assets: ['b.js', 'esmodule-helpers.js', 'lodash.js'], - }, - ]); - }); + assertBundles(b, [ + { + name: 'a.js', + assets: ['a.js', 'esmodule-helpers.js', 'lodash.js'], + }, + { + name: 'b.js', + assets: ['b.js', 'esmodule-helpers.js', 'lodash.js'], + }, + ]); + }, + ); - it('should import the same dependency multiple times in the same bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/same-dependency-multiple-times/a1.js'), - ); + it.v2( + 'should import the same dependency multiple times in the same bundle', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/same-dependency-multiple-times/a1.js', + ), + ); - await run(b); - }); + await run(b); + }, + ); - it("should inline a bundle's compiled text with `bundle-text`", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.js'), - ); + it.v2( + "should inline a bundle's compiled text with `bundle-text`", + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/index.js'), + ); - let cssBundleContent = (await run(b)).default; + let cssBundleContent = (await run(b)).default; - assert( - cssBundleContent.startsWith( - `body { + assert( + cssBundleContent.startsWith( + `body { background-color: #000; } .svg-img { background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); }`, - ), - ); + ), + ); - assert(!cssBundleContent.includes('sourceMappingURL')); - }); + assert(!cssBundleContent.includes('sourceMappingURL')); + }, + ); - it('should not include the runtime manifest for `bundle-text`', async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.js'), - { - mode: 'production', - defaultTargetOptions: {shouldScopeHoist: false, shouldOptimize: false}, - }, - ); + it.v2( + 'should not include the runtime manifest for `bundle-text`', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/index.js'), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + shouldOptimize: false, + }, + }, + ); - assertBundles(b, [ - { - name: 'index.js', - type: 'js', - assets: ['esmodule-helpers.js', 'index.js'], - }, - { - type: 'svg', - assets: ['img.svg'], - }, - { - type: 'css', - assets: ['text.scss'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + type: 'js', + assets: ['esmodule-helpers.js', 'index.js'], + }, + { + type: 'svg', + assets: ['img.svg'], + }, + { + type: 'css', + assets: ['text.scss'], + }, + ]); - let cssBundleContent = (await run(b)).default; + let cssBundleContent = (await run(b)).default; - assert( - cssBundleContent.startsWith( - `body { + assert( + cssBundleContent.startsWith( + `body { background-color: #000; } .svg-img { background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); }`, - ), - ); + ), + ); - assert(!cssBundleContent.includes('sourceMappingURL')); - }); + assert(!cssBundleContent.includes('sourceMappingURL')); + }, + ); - it("should inline an HTML bundle's compiled text with `bundle-text`", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/index.html'), - ); + it.v2( + "should inline an HTML bundle's compiled text with `bundle-text`", + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/index.html'), + ); - let res = await run(b); - assert.equal(res.default, '

test

\n'); - }); + let res = await run(b); + assert.equal(res.default, '

test

\n'); + }, + ); - it('should inline an HTML bundle and inline scripts with `bundle-text`', async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/inline.js'), - ); + it.v2( + 'should inline an HTML bundle and inline scripts with `bundle-text`', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/inline.js'), + ); - let res = await run(b); - assert.equal( - res.default, - `

test

\n\n`, - ); - }); + let res = await run(b); + assert.equal( + res.default, + `

test

\n\n`, + ); + }, + ); - it("should inline a JS bundle's compiled text with `bundle-text` and HMR enabled", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/javascript.js'), - { - hmrOptions: {}, - }, - ); + it.v2( + "should inline a JS bundle's compiled text with `bundle-text` and HMR enabled", + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/javascript.js'), + { + hmrOptions: {}, + }, + ); - let res = await run(b); - let log; - let ctx = vm.createContext({ - console: { - log(x) { - log = x; + let res = await run(b); + let log; + let ctx = vm.createContext({ + console: { + log(x) { + log = x; + }, }, - }, - }); - vm.runInContext(res.default, ctx); - assert.equal(log, 'hi'); - }); + }); + vm.runInContext(res.default, ctx); + assert.equal(log, 'hi'); + }, + ); - it("should inline a JS bundle's compiled text with `bundle-text` with symbol propagation", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/javascript.js'), - { - mode: 'production', - }, - ); + it.v2( + "should inline a JS bundle's compiled text with `bundle-text` with symbol propagation", + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/javascript.js'), + { + mode: 'production', + }, + ); - let res = await run(b); - let log; - let ctx = vm.createContext({ - console: { - log(x) { - log = x; + let res = await run(b); + let log; + let ctx = vm.createContext({ + console: { + log(x) { + log = x; + }, }, - }, - }); - vm.runInContext(res, ctx); - assert.equal(log, 'hi'); - }); + }); + vm.runInContext(res, ctx); + assert.equal(log, 'hi'); + }, + ); - it("should inline a bundle's compiled text with `bundle-text` asynchronously", async () => { - let b = await bundle( - path.join(__dirname, '/integration/bundle-text/async.js'), - ); + it.v2( + "should inline a bundle's compiled text with `bundle-text` asynchronously", + async () => { + let b = await bundle( + path.join(__dirname, '/integration/bundle-text/async.js'), + ); - let promise = (await run(b)).default; - assert.equal(typeof promise.then, 'function'); + let promise = (await run(b)).default; + assert.equal(typeof promise.then, 'function'); - let cssBundleContent = await promise; + let cssBundleContent = await promise; - assert( - cssBundleContent.startsWith( - `body { + assert( + cssBundleContent.startsWith( + `body { background-color: #000; } .svg-img { background-image: url("data:image/svg+xml,%3Csvg%3E%0A%0A%3C%2Fsvg%3E%0A"); }`, - ), - ); + ), + ); - assert(!cssBundleContent.includes('sourceMappingURL')); - }); + assert(!cssBundleContent.includes('sourceMappingURL')); + }, + ); - it('should inline text content as url-encoded text and mime type with `data-url:*` imports', async () => { - let b = await bundle(path.join(__dirname, '/integration/data-url/text.js')); + it.v2( + 'should inline text content as url-encoded text and mime type with `data-url:*` imports', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/data-url/text.js'), + ); - assert.equal( - (await run(b)).default, - 'data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%3E%3C%2FfeGaussianBlur%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%27%23blur-_.%21~%2a%27%29%22%3E%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A', - ); - }); + assert.equal( + (await run(b)).default, + 'data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%3E%3C%2FfeGaussianBlur%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%27%23blur-_.%21~%2a%27%29%22%3E%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A', + ); + }, + ); - it('should inline binary content as url-encoded base64 and mime type with `data-url:*` imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/data-url/binary.js'), - ); - ``; + it.v2( + 'should inline binary content as url-encoded base64 and mime type with `data-url:*` imports', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/data-url/binary.js'), + ); + ``; - assert((await run(b)).default.startsWith('data:image/webp;base64,UklGR')); - }); + assert((await run(b)).default.startsWith('data:image/webp;base64,UklGR')); + }, + ); - it('should support both pipeline and non-pipeline imports', async () => { + it.v2('should support both pipeline and non-pipeline imports', async () => { let b = await bundle( path.join(__dirname, '/integration/multi-pipeline/index.js'), ); @@ -2893,81 +3198,90 @@ describe('javascript', function () { assert((await run(b)).default.startsWith('.test')); }); - it('should detect typescript style async requires in commonjs', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts.js'), - ); + it.v2( + 'should detect typescript style async requires in commonjs', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/ts.js'), + ); - assertBundles(b, [ - { - name: 'ts.js', - assets: ['ts.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], - }, - { - assets: ['async.js'], - }, - ]); + assertBundles(b, [ + { + name: 'ts.js', + assets: ['ts.js', 'bundle-url.js', 'cacheLoader.js', 'js-loader.js'], + }, + { + assets: ['async.js'], + }, + ]); - assert.equal(await run(b), 2); - }); + assert.equal(await run(b), 2); + }, + ); - it('should detect typescript style async requires in commonjs with esModuleInterop flag', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts-interop.js'), - ); + it.v2( + 'should detect typescript style async requires in commonjs with esModuleInterop flag', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/ts-interop.js'), + ); - assertBundles(b, [ - { - name: 'ts-interop.js', - assets: [ - 'ts-interop.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); + assertBundles(b, [ + { + name: 'ts-interop.js', + assets: [ + 'ts-interop.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['async.js'], + }, + ]); - assert.deepEqual(await run(b), {default: 2}); + assert.deepEqual(await run(b), {default: 2}); - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - assert( - /.then\(function\(res\) {\n.*return __importStar\(res\)/.test(contents), - ); - }); + let jsBundle = b.getBundles()[0]; + let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); + assert( + /.then\(function\(res\) {\n.*return __importStar\(res\)/.test(contents), + ); + }, + ); - it('should detect typescript style async requires in commonjs with esModuleInterop flag and arrow functions', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/ts-interop-arrow.js'), - ); + it.v2( + 'should detect typescript style async requires in commonjs with esModuleInterop flag and arrow functions', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/ts-interop-arrow.js'), + ); - assertBundles(b, [ - { - name: 'ts-interop-arrow.js', - assets: [ - 'ts-interop-arrow.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); + assertBundles(b, [ + { + name: 'ts-interop-arrow.js', + assets: [ + 'ts-interop-arrow.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['async.js'], + }, + ]); - assert.deepEqual(await run(b), {default: 2}); + assert.deepEqual(await run(b), {default: 2}); - let jsBundle = b.getBundles()[0]; - let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); - assert(/.then\(\(res\)=>__importStar\(res\)/.test(contents)); - }); + let jsBundle = b.getBundles()[0]; + let contents = await outputFS.readFile(jsBundle.filePath, 'utf8'); + assert(/.then\(\(res\)=>__importStar\(res\)/.test(contents)); + }, + ); - it('should detect rollup style async requires in commonjs', async () => { + it.v2('should detect rollup style async requires in commonjs', async () => { let b = await bundle( path.join(__dirname, '/integration/require-async/rollup.js'), ); @@ -2990,45 +3304,51 @@ describe('javascript', function () { assert.equal(await run(b), 2); }); - it('should only detect requires that are returned from the promise', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/sync.js'), - ); + it.v2( + 'should only detect requires that are returned from the promise', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/sync.js'), + ); - assertBundles(b, [ - { - name: 'sync.js', - assets: ['sync.js', 'async.js'], - }, - ]); + assertBundles(b, [ + { + name: 'sync.js', + assets: ['sync.js', 'async.js'], + }, + ]); - assert.equal(await run(b), 5); - }); + assert.equal(await run(b), 5); + }, + ); - it('should properly chain a dynamic import wrapped in a Promise.resolve()', async () => { - let b = await bundle( - path.join(__dirname, '/integration/require-async/resolve-chain.js'), - ); + it.v2( + 'should properly chain a dynamic import wrapped in a Promise.resolve()', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/resolve-chain.js'), + ); - assertBundles(b, [ - { - name: 'resolve-chain.js', - assets: [ - 'resolve-chain.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - assets: ['async.js'], - }, - ]); + assertBundles(b, [ + { + name: 'resolve-chain.js', + assets: [ + 'resolve-chain.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['async.js'], + }, + ]); - assert.equal(await run(b), 1337); - }); + assert.equal(await run(b), 1337); + }, + ); - it('should detect parcel style async requires in commonjs', async () => { + it.v2('should detect parcel style async requires in commonjs', async () => { let b = await bundle( path.join(__dirname, '/integration/require-async/parcel.js'), ); @@ -3051,334 +3371,367 @@ describe('javascript', function () { assert.equal(await run(b), 2); }); - it('should detect requires in commonjs with plain template literals', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/commonjs-template-literal-plain/index.js', - ), - ); - let dist = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - assert(dist.includes('$cPUKg$lodash = require("lodash");')); - - let add = await run(b); - assert.equal(add(2, 3), 5); - }); - - it(`should detect requires in commonjs with plain template literals`, async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/commonjs-template-literal-interpolation/index.js', - ), - ); - let dist = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - - assert( - dist.includes( - 'const add = require(`lodash/${$8cad8166811e0063$var$fn}`);', - ), - ); - - let add = await run(b); - assert.equal(add(2, 3), 5); - }); - - it('only updates bundle names of changed bundles for browsers', async () => { - let fixtureDir = path.join(__dirname, '/integration/name-invalidation'); - let _bundle = () => - bundle(path.join(fixtureDir, 'index.js'), { - inputFS: overlayFS, - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - shouldOptimize: false, - }, - }); + it.v2( + 'should detect requires in commonjs with plain template literals', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/commonjs-template-literal-plain/index.js', + ), + ); + let dist = await outputFS.readFile( + b.getBundles().find(b => b.type === 'js').filePath, + 'utf8', + ); + assert(dist.includes('$cPUKg$lodash = require("lodash");')); - let first = await _bundle(); - assert.equal(await (await run(first)).default, 42); + let add = await run(b); + assert.equal(add(2, 3), 5); + }, + ); - let bPath = path.join(fixtureDir, 'b.js'); - await overlayFS.mkdirp(fixtureDir); - overlayFS.writeFile( - bPath, - (await overlayFS.readFile(bPath, 'utf8')).replace('42', '43'), - ); + it.v2( + `should detect requires in commonjs with plain template literals`, + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/commonjs-template-literal-interpolation/index.js', + ), + ); + let dist = await outputFS.readFile( + b.getBundles().find(b => b.type === 'js').filePath, + 'utf8', + ); - let second = await _bundle(); - assert.equal(await (await run(second)).default, 43); + assert( + dist.includes( + 'const add = require(`lodash/${$8cad8166811e0063$var$fn}`);', + ), + ); - let getBundleNameWithPrefix = (b, prefix) => - b - .getBundles() - .map(bundle => path.basename(bundle.filePath)) - .find(name => name.startsWith(prefix)); + let add = await run(b); + assert.equal(add(2, 3), 5); + }, + ); - assert.equal( - getBundleNameWithPrefix(first, 'a'), - getBundleNameWithPrefix(second, 'a'), - ); - assert.notEqual( - getBundleNameWithPrefix(first, 'b'), - getBundleNameWithPrefix(second, 'b'), - ); - }); + it.v2( + 'only updates bundle names of changed bundles for browsers', + async () => { + let fixtureDir = path.join(__dirname, '/integration/name-invalidation'); + let _bundle = () => + bundle(path.join(fixtureDir, 'index.js'), { + inputFS: overlayFS, + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + shouldOptimize: false, + }, + }); - it('can load the same resource when referenced in multiple bundles', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/same-resource-multiple-bundles/index.js', - ), - ); + let first = await _bundle(); + assert.equal(await (await run(first)).default, 42); - let res = await run(b); - assert(url.parse(await res.default()).pathname.startsWith('/resource')); - }); + let bPath = path.join(fixtureDir, 'b.js'); + await overlayFS.mkdirp(fixtureDir); + overlayFS.writeFile( + bPath, + (await overlayFS.readFile(bPath, 'utf8')).replace('42', '43'), + ); - it('can static import and dynamic import in the same bundle without creating a new bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/sync-async/same-bundle.js'), - {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, - ); + let second = await _bundle(); + assert.equal(await (await run(second)).default, 43); - assertBundles(b, [ - { - name: 'same-bundle.js', - assets: [ - 'same-bundle.js', - 'get-dep.js', - 'get-dep-2.js', - 'dep.js', - 'esmodule-helpers.js', - ], - }, - ]); + let getBundleNameWithPrefix = (b, prefix) => + b + .getBundles() + .map(bundle => path.basename(bundle.filePath)) + .find(name => name.startsWith(prefix)); - assert.deepEqual(await (await run(b)).default, [42, 42, 42]); - }); + assert.equal( + getBundleNameWithPrefix(first, 'a'), + getBundleNameWithPrefix(second, 'a'), + ); + assert.notEqual( + getBundleNameWithPrefix(first, 'b'), + getBundleNameWithPrefix(second, 'b'), + ); + }, + ); - it('async dependency can be resolved internally and externally from two different bundles', async () => { - let b = await bundle( - ['entry1.js', 'entry2.js'].map(entry => + it.v2( + 'can load the same resource when referenced in multiple bundles', + async () => { + let b = await bundle( path.join( __dirname, - '/integration/async-dep-internal-external/', - entry, + '/integration/same-resource-multiple-bundles/index.js', ), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ); + ); - assertBundles(b, [ - { - assets: ['async.js'], - }, - { - name: 'entry1.js', - assets: ['child.js', 'entry1.js', 'async.js'], - }, - { - name: 'entry2.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'child.js', - 'entry2.js', - 'js-loader.js', - ], - }, - ]); - }); + let res = await run(b); + assert(url.parse(await res.default()).pathname.startsWith('/resource')); + }, + ); - it('can static import and dynamic import in the same bundle ancestry without creating a new bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/sync-async/same-ancestry.js'), - {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, - ); + it.v2( + 'can static import and dynamic import in the same bundle without creating a new bundle', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/sync-async/same-bundle.js'), + {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, + ); - assertBundles(b, [ - { - name: 'same-ancestry.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'dep.js', - 'js-loader.js', - 'same-ancestry.js', - 'esmodule-helpers.js', - ], - }, - { - assets: ['get-dep.js'], - }, - ]); + assertBundles(b, [ + { + name: 'same-bundle.js', + assets: [ + 'same-bundle.js', + 'get-dep.js', + 'get-dep-2.js', + 'dep.js', + 'esmodule-helpers.js', + ], + }, + ]); - assert.deepEqual(await (await run(b)).default, [42, 42]); - }); + assert.deepEqual(await (await run(b)).default, [42, 42, 42]); + }, + ); - it('can static import and dynamic import in the same bundle when another bundle requires async', async () => { - let b = await bundle( - ['same-bundle.js', 'get-dep.js'].map(entry => - path.join(__dirname, '/integration/sync-async/', entry), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + it.v2( + 'async dependency can be resolved internally and externally from two different bundles', + async () => { + let b = await bundle( + ['entry1.js', 'entry2.js'].map(entry => + path.join( + __dirname, + '/integration/async-dep-internal-external/', + entry, + ), + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); + ); - assertBundles(b, [ - { - assets: ['dep.js'], - }, - { - name: 'same-bundle.js', - assets: [ - 'same-bundle.js', - 'get-dep.js', - 'get-dep-2.js', - 'dep.js', - 'esmodule-helpers.js', - ], - }, - { - name: 'get-dep.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'get-dep.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - ]); + assertBundles(b, [ + { + assets: ['async.js'], + }, + { + name: 'entry1.js', + assets: ['child.js', 'entry1.js', 'async.js'], + }, + { + name: 'entry2.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'child.js', + 'entry2.js', + 'js-loader.js', + ], + }, + ]); + }, + ); - let bundles = b.getBundles(); - let sameBundle = bundles.find(b => b.name === 'same-bundle.js'); - let getDep = bundles.find(b => b.name === 'get-dep.js'); + it.v2( + 'can static import and dynamic import in the same bundle ancestry without creating a new bundle', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/sync-async/same-ancestry.js'), + {mode: 'production', defaultTargetOptions: {shouldScopeHoist: false}}, + ); - assert.deepEqual( - await ( - await runBundle(b, sameBundle) - ).default, - [42, 42, 42], - ); - assert.deepEqual(await (await runBundle(b, getDep)).default, 42); - }); + assertBundles(b, [ + { + name: 'same-ancestry.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'dep.js', + 'js-loader.js', + 'same-ancestry.js', + 'esmodule-helpers.js', + ], + }, + { + assets: ['get-dep.js'], + }, + ]); - it("can share dependencies between a shared bundle and its sibling's descendants", async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/shared-exports-for-sibling-descendant/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + assert.deepEqual(await (await run(b)).default, [42, 42]); + }, + ); + + it.v2( + 'can static import and dynamic import in the same bundle when another bundle requires async', + async () => { + let b = await bundle( + ['same-bundle.js', 'get-dep.js'].map(entry => + path.join(__dirname, '/integration/sync-async/', entry), + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, }, - }, - ); + ); - assertBundles(b, [ - { - assets: ['wraps.js', 'lodash.js'], - }, - { - assets: ['a.js'], - }, - { - assets: ['child.js'], - }, - { - assets: ['grandchild.js'], - }, - { - assets: ['b.js'], - }, - { - name: 'index.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'index.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - ]); + assertBundles(b, [ + { + assets: ['dep.js'], + }, + { + name: 'same-bundle.js', + assets: [ + 'same-bundle.js', + 'get-dep.js', + 'get-dep-2.js', + 'dep.js', + 'esmodule-helpers.js', + ], + }, + { + name: 'get-dep.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'get-dep.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + ]); - assert.deepEqual(await (await run(b)).default, [3, 5]); - }); + let bundles = b.getBundles(); + let sameBundle = bundles.find(b => b.name === 'same-bundle.js'); + let getDep = bundles.find(b => b.name === 'get-dep.js'); - it('can run an entry bundle whose entry asset is present in another bundle', async () => { - let b = await bundle( - ['index.js', 'value.js'].map(basename => - path.join(__dirname, '/integration/sync-entry-shared', basename), - ), - ); + assert.deepEqual( + await ( + await runBundle(b, sameBundle) + ).default, + [42, 42, 42], + ); + assert.deepEqual(await (await runBundle(b, getDep)).default, 42); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - {name: 'value.js', assets: ['value.js', 'esmodule-helpers.js']}, - {assets: ['async.js']}, - ]); + it.v2( + "can share dependencies between a shared bundle and its sibling's descendants", + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/shared-exports-for-sibling-descendant/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); - assert.equal(await (await run(b)).default, 43); - }); + assertBundles(b, [ + { + assets: ['wraps.js', 'lodash.js'], + }, + { + assets: ['a.js'], + }, + { + assets: ['child.js'], + }, + { + assets: ['grandchild.js'], + }, + { + assets: ['b.js'], + }, + { + name: 'index.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'index.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + ]); - it('can run an async bundle whose entry asset is present in another bundle', async () => { - let b = await bundle( - path.join(__dirname, '/integration/async-entry-shared/index.js'), - ); + assert.deepEqual(await (await run(b)).default, [3, 5]); + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - {assets: ['value.js']}, - {assets: ['async.js']}, - ]); + it.v2( + 'can run an entry bundle whose entry asset is present in another bundle', + async () => { + let b = await bundle( + ['index.js', 'value.js'].map(basename => + path.join(__dirname, '/integration/sync-entry-shared', basename), + ), + ); - assert.deepEqual(await (await run(b)).default, [42, 43]); - }); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + {name: 'value.js', assets: ['value.js', 'esmodule-helpers.js']}, + {assets: ['async.js']}, + ]); + + assert.equal(await (await run(b)).default, 43); + }, + ); + + it.v2( + 'can run an async bundle whose entry asset is present in another bundle', + async () => { + let b = await bundle( + path.join(__dirname, '/integration/async-entry-shared/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + {assets: ['value.js']}, + {assets: ['async.js']}, + ]); + + assert.deepEqual(await (await run(b)).default, [42, 43]); + }, + ); - it('should display a codeframe on a Terser parse error', async () => { + it.v2('should display a codeframe on a Terser parse error', async () => { let fixture = path.join(__dirname, 'integration/terser-codeframe/index.js'); let code = await inputFS.readFileSync(fixture, 'utf8'); await assert.rejects( @@ -3419,68 +3772,74 @@ describe('javascript', function () { ); }); - it('can run an async bundle that depends on a nonentry asset in a sibling', async () => { - let b = await bundle( - ['index.js', 'other-entry.js'].map(basename => - path.join( - __dirname, - '/integration/async-entry-shared-sibling', - basename, + it.v2( + 'can run an async bundle that depends on a nonentry asset in a sibling', + async () => { + let b = await bundle( + ['index.js', 'other-entry.js'].map(basename => + path.join( + __dirname, + '/integration/async-entry-shared-sibling', + basename, + ), ), - ), - ); + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'esmodule-helpers.js', - ], - }, - { - name: 'other-entry.js', - assets: [ - 'other-entry.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - {assets: ['a.js', 'value.js', 'esmodule-helpers.js']}, - {assets: ['b.js']}, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'esmodule-helpers.js', + ], + }, + { + name: 'other-entry.js', + assets: [ + 'other-entry.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + {assets: ['a.js', 'value.js', 'esmodule-helpers.js']}, + {assets: ['b.js']}, + ]); - assert.deepEqual(await (await run(b)).default, 43); - }); + assert.deepEqual(await (await run(b)).default, 43); + }, + ); - it('can share sibling bundles reachable from a common dependency', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/shared-sibling-common-dependency/index.js', - ), - ); + it.v2( + 'can share sibling bundles reachable from a common dependency', + async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/shared-sibling-common-dependency/index.js', + ), + ); - let bundles = b.getBundles(); - let asyncJsBundles = bundles.filter( - b => !b.needsStableName && b.type === 'js', - ); - assert.equal(asyncJsBundles.length, 2); + let bundles = b.getBundles(); + let asyncJsBundles = bundles.filter( + b => !b.needsStableName && b.type === 'js', + ); + assert.equal(asyncJsBundles.length, 2); - // Every bundlegroup with an async js bundle should have the corresponding css - for (let bundle of asyncJsBundles) { - for (let bundleGroup of b.getBundleGroupsContainingBundle(bundle)) { - let bundlesInGroup = b.getBundlesInBundleGroup(bundleGroup); - assert(bundlesInGroup.find(s => s.type === 'css')); + // Every bundlegroup with an async js bundle should have the corresponding css + for (let bundle of asyncJsBundles) { + for (let bundleGroup of b.getBundleGroupsContainingBundle(bundle)) { + let bundlesInGroup = b.getBundlesInBundleGroup(bundleGroup); + assert(bundlesInGroup.find(s => s.type === 'css')); + } } - } - }); + }, + ); - it('should throw a diagnostic for unknown pipelines', async function () { + it.v2('should throw a diagnostic for unknown pipelines', async function () { let fixture = path.join(__dirname, 'integration/pipeline-unknown/a.js'); let code = await inputFS.readFileSync(fixture, 'utf8'); await assert.rejects(() => bundle(fixture), { @@ -3517,7 +3876,7 @@ describe('javascript', function () { }); }); - it('can create a bundle starting with a dot', async function () { + it.v2('can create a bundle starting with a dot', async function () { let b = await bundle( path.join(__dirname, '/integration/dotfile-bundle/index.js'), ); @@ -3530,102 +3889,129 @@ describe('javascript', function () { ]); }); - it('should not automatically name bundle files starting with a dot', async function () { - await bundle( - path.join(__dirname, '/integration/bundle-naming/.invisible/index.js'), - ); - let bundleFiles = await outputFS.readdir(distDir); - let renamedSomeFiles = bundleFiles.some(currFile => - currFile.startsWith('invisible.'), - ); - let namedWithDot = bundleFiles.some(currFile => - currFile.startsWith('.invisible.'), - ); - assert.equal(renamedSomeFiles, true); - assert.equal(namedWithDot, false); - }); - - it('should support duplicate re-exports without scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-duplicate-re-exports/index.js'), - ); - let res = await run(b); - assert.equal(res.a, 'a'); - assert.equal(res.b, 'b'); - assert.equal(typeof res.c, 'function'); - }); + it.v2( + 'should not automatically name bundle files starting with a dot', + async function () { + await bundle( + path.join(__dirname, '/integration/bundle-naming/.invisible/index.js'), + ); + let bundleFiles = await outputFS.readdir(distDir); + let renamedSomeFiles = bundleFiles.some(currFile => + currFile.startsWith('invisible.'), + ); + let namedWithDot = bundleFiles.some(currFile => + currFile.startsWith('.invisible.'), + ); + assert.equal(renamedSomeFiles, true); + assert.equal(namedWithDot, false); + }, + ); - it('should prioritize named exports before re-exports withput scope hoisting (before)', async () => { - let b = await bundle( - path.join( - __dirname, - 'integration/scope-hoisting/es6/re-export-priority/entry-a.mjs', - ), - ); + it.v2( + 'should support duplicate re-exports without scope hoisting', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-duplicate-re-exports/index.js'), + ); + let res = await run(b); + assert.equal(res.a, 'a'); + assert.equal(res.b, 'b'); + assert.equal(typeof res.c, 'function'); + }, + ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 2); - }); + it.v2( + 'should prioritize named exports before re-exports withput scope hoisting (before)', + async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/scope-hoisting/es6/re-export-priority/entry-a.mjs', + ), + ); - it('should prioritize named exports before re-exports without scope hoisting (after)', async () => { - let b = await bundle( - path.join( - __dirname, - 'integration/scope-hoisting/es6/re-export-priority/entry-b.mjs', - ), - ); + let res = await run(b, null, {require: false}); + assert.equal(res.output, 2); + }, + ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 2); - }); + it.v2( + 'should prioritize named exports before re-exports without scope hoisting (after)', + async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/scope-hoisting/es6/re-export-priority/entry-b.mjs', + ), + ); - it('should exclude default from export all declaration', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-all/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {a: 4}); - }); + let res = await run(b, null, {require: false}); + assert.equal(res.output, 2); + }, + ); - it('should not use arrow functions for reexport declarations unless supported', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-arrow-support/index.js'), - { - // Remove comments containing "=>" - defaultTargetOptions: { - shouldOptimize: true, + it.v2( + 'should exclude default from export all declaration', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-export-all/index.js'), + ); + let res = await run(b); + assert.deepEqual(res, {a: 4}); + }, + ); + + it.v2( + 'should not use arrow functions for reexport declarations unless supported', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-export-arrow-support/index.js'), + { + // Remove comments containing "=>" + defaultTargetOptions: { + shouldOptimize: true, + }, }, - }, - ); - let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!content.includes('=>')); - }); + ); + let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert(!content.includes('=>')); + }, + ); - it('should support import namespace declarations of other ES modules', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/a.js'), - ); - let res = await run(b); - assert.deepEqual(res, {a: 4, default: 1}); - }); + it.v2( + 'should support import namespace declarations of other ES modules', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-namespace/a.js'), + ); + let res = await run(b); + assert.deepEqual(res, {a: 4, default: 1}); + }, + ); - it('should support import namespace declarations of class from CJS', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/b.js'), - ); - let res = await run(b); - assert.equal(typeof res, 'function'); - }); + it.v2( + 'should support import namespace declarations of class from CJS', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-namespace/b.js'), + ); + let res = await run(b); + assert.equal(typeof res, 'function'); + }, + ); - it('should support import namespace declarations of object from CJS', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-namespace/c.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: 2, default: 3}); - }); + it.v2( + 'should support import namespace declarations of object from CJS', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-namespace/c.js'), + ); + let res = await run(b); + assert.deepEqual(res, {foo: 2, default: 3}); + }, + ); - it('should support export namespace declarations', async function () { + it.v2('should support export namespace declarations', async function () { let b = await bundle( path.join(__dirname, 'integration/js-export-namespace/index.js'), ); @@ -3633,15 +4019,18 @@ describe('javascript', function () { assert.deepEqual(res, {ns: {a: 4, default: 1}}); }); - it('should support export declarations with destructuring', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-destructuring/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: 1, bar: 2}); - }); + it.v2( + 'should support export declarations with destructuring', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-export-destructuring/index.js'), + ); + let res = await run(b); + assert.deepEqual(res, {foo: 1, bar: 2}); + }, + ); - it('should support export default declarations', async function () { + it.v2('should support export default declarations', async function () { let b = await bundle( path.join(__dirname, 'integration/js-export-default/index.js'), ); @@ -3649,39 +4038,45 @@ describe('javascript', function () { assert.deepEqual(res, {other: 1}); }); - it('should hoist function default exports to allow circular imports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-export-default-fn-circular-named/a.mjs', - ), - ); + it.v2( + 'should hoist function default exports to allow circular imports', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/js-export-default-fn-circular-named/a.mjs', + ), + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, 'b1'); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, 'b1'); + }, + ); - it('should hoist anonymous function default exports to allow circular imports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-export-default-fn-circular-anonymous/a.mjs', - ), - ); + it.v2( + 'should hoist anonymous function default exports to allow circular imports', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/js-export-default-fn-circular-anonymous/a.mjs', + ), + ); - let output; - function result(v) { - output = v; - } - await run(b, {result}); - assert.deepEqual(output, 'b1'); - }); + let output; + function result(v) { + output = v; + } + await run(b, {result}); + assert.deepEqual(output, 'b1'); + }, + ); - it('should work with many different types of exports', async function () { + it.v2('should work with many different types of exports', async function () { let b = await bundle( path.join(__dirname, 'integration/js-export-many/index.js'), ); @@ -3697,7 +4092,7 @@ describe('javascript', function () { }); }); - it('should correctly export functions', async function () { + it.v2('should correctly export functions', async function () { let b = await bundle( path.join(__dirname, 'integration/js-export-functions/index.js'), ); @@ -3707,7 +4102,7 @@ describe('javascript', function () { assert.strictEqual(res.bar('test'), 'bar:test'); }); - it('should handle exports of imports', async function () { + it.v2('should handle exports of imports', async function () { let b = await bundle( path.join(__dirname, 'integration/js-export-import/index.js'), ); @@ -3715,61 +4110,82 @@ describe('javascript', function () { assert.deepEqual(res, {other: 2}); }); - it('should handle simultaneous import and reexports of the same identifier', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-export-import-same/index.js'), - ); - let res = await run(b); - assert.deepEqual(res, {foo: '123', bar: '1234'}); - }); + it.v2( + 'should handle simultaneous import and reexports of the same identifier', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-export-import-same/index.js'), + ); + let res = await run(b); + assert.deepEqual(res, {foo: '123', bar: '1234'}); + }, + ); - it('should generate a unique variable name for imports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow/index.js'), - ); - let res = await run(b); - assert.strictEqual(res.baz(), 'foo'); - }); + it.v2( + 'should generate a unique variable name for imports', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-shadow/index.js'), + ); + let res = await run(b); + assert.strictEqual(res.baz(), 'foo'); + }, + ); - it('should not replace identifier with a var declaration inside a for loop', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow-for-var/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.baz(), [0, 1, 2, 3]); - }); + it.v2( + 'should not replace identifier with a var declaration inside a for loop', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-shadow-for-var/index.js'), + ); + let res = await run(b); + assert.deepEqual(res.baz(), [0, 1, 2, 3]); + }, + ); - it('should replace an imported identifier with function locals of the same name', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-shadow-func-var/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, 123); - }); + it.v2( + 'should replace an imported identifier with function locals of the same name', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-shadow-func-var/index.js'), + ); + let res = await run(b); + assert.deepEqual(res.default, 123); + }, + ); - it('should replace imported values in member expressions', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-member/index.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, ['a', 'b', 'bar']); - }); + it.v2( + 'should replace imported values in member expressions', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-import-member/index.js'), + ); + let res = await run(b); + assert.deepEqual(res.default, ['a', 'b', 'bar']); + }, + ); - it('should retain the correct dependency order between import and reexports', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-import-reexport-dep-order/index.js'), - ); + it.v2( + 'should retain the correct dependency order between import and reexports', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/js-import-reexport-dep-order/index.js', + ), + ); - let calls = []; - await run(b, { - sideEffect(v) { - calls.push(v); - }, - }); - assert.deepEqual(calls, ['a', 'b', 'c']); - }); + let calls = []; + await run(b, { + sideEffect(v) { + calls.push(v); + }, + }); + assert.deepEqual(calls, ['a', 'b', 'c']); + }, + ); - it('should not freeze live default imports', async function () { + it.v2('should not freeze live default imports', async function () { let b = await bundle( path.join(__dirname, 'integration/js-import-default-live/index.js'), ); @@ -3777,15 +4193,18 @@ describe('javascript', function () { assert.deepEqual(res.default, [123, 789]); }); - it('should not rewrite this in arrow function class properties', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-class-this-esm/a.js'), - ); - let res = await run(b); - assert.deepEqual(res.default, 'x: 123'); - }); + it.v2( + 'should not rewrite this in arrow function class properties', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-class-this-esm/a.js'), + ); + let res = await run(b); + assert.deepEqual(res.default, 'x: 123'); + }, + ); - it('should call named imports without this context', async function () { + it.v2('should call named imports without this context', async function () { let b = await bundle( path.join(__dirname, 'integration/js-import-this/index.js'), ); @@ -3800,7 +4219,7 @@ describe('javascript', function () { }); }); - it('should only replace free references to require', async () => { + it.v2('should only replace free references to require', async () => { let b = await bundle( path.join(__dirname, 'integration/js-require-free/index.js'), ); @@ -3813,42 +4232,57 @@ describe('javascript', function () { assert.strictEqual(output, 'a'); }); - it('should only replace free references to require with scope hoisting', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-free/index.js'), - { - mode: 'production', - }, - ); - let output; - await run(b, { - output(v) { - output = v; - }, - }); - assert.strictEqual(output, 'a'); - }); + it.v2( + 'should only replace free references to require with scope hoisting', + async () => { + let b = await bundle( + path.join(__dirname, 'integration/js-require-free/index.js'), + { + mode: 'production', + }, + ); + let output; + await run(b, { + output(v) { + output = v; + }, + }); + assert.strictEqual(output, 'a'); + }, + ); - it('should support import and non-top-level require of same asset from different assets', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-import-different/index.js'), - ); - let {output} = await run(b, null, {require: false}); - assert.deepEqual(output, [123, {HooksContext: 123}]); - }); + it.v2( + 'should support import and non-top-level require of same asset from different assets', + async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/js-require-import-different/index.js', + ), + ); + let {output} = await run(b, null, {require: false}); + assert.deepEqual(output, [123, {HooksContext: 123}]); + }, + ); - it('should support import and non-top-level require of same asset from different assets with scope hoisting', async () => { - let b = await bundle( - path.join(__dirname, 'integration/js-require-import-different/index.js'), - { - mode: 'production', - }, - ); - let {output} = await run(b, null, {require: false}); - assert.deepEqual(output, [123, {HooksContext: 123}]); - }); + it.v2( + 'should support import and non-top-level require of same asset from different assets with scope hoisting', + async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/js-require-import-different/index.js', + ), + { + mode: 'production', + }, + ); + let {output} = await run(b, null, {require: false}); + assert.deepEqual(output, [123, {HooksContext: 123}]); + }, + ); - it('should support runtime module deduplication', async function () { + it.v2('should support runtime module deduplication', async function () { let b = await bundle( path.join(__dirname, 'integration/js-runtime-dedup/index.js'), ); @@ -3870,700 +4304,754 @@ describe('javascript', function () { assert.equal(await res, true); }); - it('should support runtime module deduplication with scope hoisting', async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-runtime-dedup/index.js'), - { - mode: 'production', - }, - ); + it.v2( + 'should support runtime module deduplication with scope hoisting', + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-runtime-dedup/index.js'), + { + mode: 'production', + }, + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['async1.js', 'shared.js'], - }, - { - assets: ['async2.js', 'shared.js'], - }, - ]); - - let res = await run(b); - assert.equal(await res, true); - }); - - it('should remap locations in diagnostics using the input source map', async () => { - let fixture = path.join( - __dirname, - 'integration/diagnostic-sourcemap/index.js', - ); - let code = await inputFS.readFileSync(fixture, 'utf8'); - await assert.rejects( - () => - bundle(fixture, { - defaultTargetOptions: { - shouldOptimize: true, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: "Failed to resolve 'foo' from './index.js'", - origin: '@parcel/core', - codeFrames: [ - { - filePath: fixture, - code, - codeHighlights: [ - { - message: undefined, - start: { - line: 11, - column: 17, - }, - end: { - line: 11, - column: 21, - }, - }, - ], - }, - ], - }, - { - message: "Cannot find module 'foo'", - origin: '@parcel/resolver-default', - hints: [], - }, - ], - }, - ); - }); - it('should reuse a bundle when its main asset (aka bundleroot) is imported sychronously', async function () { - let b = await bundle( - path.join(__dirname, 'integration/shared-bundle-single-source/index.js'), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + 'bundle-manifest.js', + ], }, - }, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'css-loader.js', - 'esmodule-helpers.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['bar.js'], - }, - { - assets: ['a.js', 'b.js', 'foo.js'], - }, - { - assets: ['styles.css'], - }, - { - assets: ['local.html'], - }, - ]); - }); - - it('should error on undeclared external dependencies for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/index.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: "Failed to resolve 'lodash' from './index.js'", - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 19, - }, - end: { - line: 1, - column: 26, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "lodash" is not declared in package.json.', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: await inputFS.readFile(pkg, 'utf8'), - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: undefined, - start: { - line: 5, - column: 3, - }, - end: { - line: 5, - column: 16, - }, - }, - ], - }, - ], - hints: ['Add "lodash" as a dependency.'], - }, - ], - }, - ); - }); - - it('should error on undeclared helpers dependency for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/helpers.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( - require.resolve('@parcel/transformer-js/src/JSTransformer.js'), - )}'`, - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 1, - }, - end: { - line: 1, - column: 1, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "@swc/helpers" is not declared in package.json.', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: await inputFS.readFile(pkg, 'utf8'), - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: undefined, - start: { - line: 5, - column: 3, - }, - end: { - line: 5, - column: 16, - }, - }, - ], - }, - ], - hints: ['Add "@swc/helpers" as a dependency.'], - }, - ], - }, - ); - }); - - it('should error on mismatched helpers version for libraries', async function () { - let fixture = path.join( - __dirname, - 'integration/undeclared-external/helpers.js', - ); - let pkg = path.join( - __dirname, - 'integration/undeclared-external/package.json', - ); - let pkgContents = JSON.stringify( - { - ...JSON.parse(await overlayFS.readFile(pkg, 'utf8')), - dependencies: { - '@swc/helpers': '^0.3.0', + { + assets: ['async1.js', 'shared.js'], }, - }, - false, - 2, - ); - await overlayFS.mkdirp(path.dirname(pkg)); - await overlayFS.writeFile(pkg, pkgContents); - await assert.rejects( - () => - bundle(fixture, { - mode: 'production', - inputFS: overlayFS, - defaultTargetOptions: { - shouldOptimize: false, - }, - }), - { - name: 'BuildError', - diagnostics: [ - { - message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( - require.resolve('@parcel/transformer-js/src/JSTransformer.js'), - )}'`, - origin: '@parcel/core', - codeFrames: [ - { - code: await inputFS.readFile(fixture, 'utf8'), - filePath: fixture, - codeHighlights: [ - { - message: undefined, - start: { - line: 1, - column: 1, - }, - end: { - line: 1, - column: 1, - }, - }, - ], - }, - ], - }, - { - message: - 'External dependency "@swc/helpers" does not satisfy required semver range "^0.5.0".', - origin: '@parcel/resolver-default', - codeFrames: [ - { - code: pkgContents, - filePath: pkg, - language: 'json', - codeHighlights: [ - { - message: 'Found this conflicting requirement.', - start: { - line: 6, - column: 21, - }, - end: { - line: 6, - column: 28, - }, - }, - ], - }, - ], - hints: [ - 'Update the dependency on "@swc/helpers" to satisfy "^0.5.0".', - ], - }, - ], - }, - ); - }); - - describe('multiple import types', function () { - it('supports both static and dynamic imports to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic.js', - ), - ); - - assertBundles(b, [ { - type: 'js', - assets: ['static-dynamic.js', 'other.js', 'esmodule-helpers.js'], + assets: ['async2.js', 'shared.js'], }, ]); let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - }); + assert.equal(await res, true); + }, + ); - it('supports both static and dynamic imports to the same specifier in the same file with scope hoisting', async function () { + it.v2( + 'should remap locations in diagnostics using the input source map', + async () => { + let fixture = path.join( + __dirname, + 'integration/diagnostic-sourcemap/index.js', + ); + let code = await inputFS.readFileSync(fixture, 'utf8'); + await assert.rejects( + () => + bundle(fixture, { + defaultTargetOptions: { + shouldOptimize: true, + }, + }), + { + name: 'BuildError', + diagnostics: [ + { + message: "Failed to resolve 'foo' from './index.js'", + origin: '@parcel/core', + codeFrames: [ + { + filePath: fixture, + code, + codeHighlights: [ + { + message: undefined, + start: { + line: 11, + column: 17, + }, + end: { + line: 11, + column: 21, + }, + }, + ], + }, + ], + }, + { + message: "Cannot find module 'foo'", + origin: '@parcel/resolver-default', + hints: [], + }, + ], + }, + ); + }, + ); + it.v2( + 'should reuse a bundle when its main asset (aka bundleroot) is imported sychronously', + async function () { let b = await bundle( path.join( __dirname, - 'integration/multiple-import-types/static-dynamic.js', + 'integration/shared-bundle-single-source/index.js', ), { + mode: 'production', defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, + shouldScopeHoist: false, }, }, ); assertBundles(b, [ { - type: 'js', - assets: ['static-dynamic.js', 'other.js'], - }, - ]); - - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - }); - - it('supports static, dynamic, and url to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic-url.js', - ), - ); - - assertBundles(b, [ - { - type: 'js', + name: 'index.js', assets: [ - 'static-dynamic-url.js', - 'other.js', - 'esmodule-helpers.js', + 'index.js', 'bundle-url.js', 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', 'js-loader.js', + 'bundle-manifest.js', ], }, { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], + assets: ['bar.js'], + }, + { + assets: ['a.js', 'b.js', 'foo.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], }, ]); + }, + ); - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), + it.v2( + 'should error on undeclared external dependencies for libraries', + async function () { + let fixture = path.join( + __dirname, + 'integration/undeclared-external/index.js', ); - }); + let pkg = path.join( + __dirname, + 'integration/undeclared-external/package.json', + ); + await assert.rejects( + () => + bundle(fixture, { + mode: 'production', + defaultTargetOptions: { + shouldOptimize: false, + }, + }), + { + name: 'BuildError', + diagnostics: [ + { + message: "Failed to resolve 'lodash' from './index.js'", + origin: '@parcel/core', + codeFrames: [ + { + code: await inputFS.readFile(fixture, 'utf8'), + filePath: fixture, + codeHighlights: [ + { + message: undefined, + start: { + line: 1, + column: 19, + }, + end: { + line: 1, + column: 26, + }, + }, + ], + }, + ], + }, + { + message: + 'External dependency "lodash" is not declared in package.json.', + origin: '@parcel/resolver-default', + codeFrames: [ + { + code: await inputFS.readFile(pkg, 'utf8'), + filePath: pkg, + language: 'json', + codeHighlights: [ + { + message: undefined, + start: { + line: 5, + column: 3, + }, + end: { + line: 5, + column: 16, + }, + }, + ], + }, + ], + hints: ['Add "lodash" as a dependency.'], + }, + ], + }, + ); + }, + ); - it('supports static, dynamic, and url to the same specifier in the same file with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-dynamic-url.js', - ), + it.v2( + 'should error on undeclared helpers dependency for libraries', + async function () { + let fixture = path.join( + __dirname, + 'integration/undeclared-external/helpers.js', + ); + let pkg = path.join( + __dirname, + 'integration/undeclared-external/package.json', + ); + await assert.rejects( + () => + bundle(fixture, { + mode: 'production', + defaultTargetOptions: { + shouldOptimize: false, + }, + }), { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, - }, + name: 'BuildError', + diagnostics: [ + { + message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( + require.resolve('@parcel/transformer-js/src/JSTransformer.js'), + )}'`, + origin: '@parcel/core', + codeFrames: [ + { + code: await inputFS.readFile(fixture, 'utf8'), + filePath: fixture, + codeHighlights: [ + { + message: undefined, + start: { + line: 1, + column: 1, + }, + end: { + line: 1, + column: 1, + }, + }, + ], + }, + ], + }, + { + message: + 'External dependency "@swc/helpers" is not declared in package.json.', + origin: '@parcel/resolver-default', + codeFrames: [ + { + code: await inputFS.readFile(pkg, 'utf8'), + filePath: pkg, + language: 'json', + codeHighlights: [ + { + message: undefined, + start: { + line: 5, + column: 3, + }, + end: { + line: 5, + column: 16, + }, + }, + ], + }, + ], + hints: ['Add "@swc/helpers" as a dependency.'], + }, + ], }, ); + }, + ); - assertBundles(b, [ + it.v2( + 'should error on mismatched helpers version for libraries', + async function () { + let fixture = path.join( + __dirname, + 'integration/undeclared-external/helpers.js', + ); + let pkg = path.join( + __dirname, + 'integration/undeclared-external/package.json', + ); + let pkgContents = JSON.stringify( { - type: 'js', - assets: ['static-dynamic-url.js', 'other.js'], + ...JSON.parse(await overlayFS.readFile(pkg, 'utf8')), + dependencies: { + '@swc/helpers': '^0.3.0', + }, }, + false, + 2, + ); + await overlayFS.mkdirp(path.dirname(pkg)); + await overlayFS.writeFile(pkg, pkgContents); + await assert.rejects( + () => + bundle(fixture, { + mode: 'production', + inputFS: overlayFS, + defaultTargetOptions: { + shouldOptimize: false, + }, + }), { - type: 'js', - assets: ['other.js'], + name: 'BuildError', + diagnostics: [ + { + message: md`Failed to resolve '${'@swc/helpers/cjs/_class_call_check.cjs'}' from '${normalizePath( + require.resolve('@parcel/transformer-js/src/JSTransformer.js'), + )}'`, + origin: '@parcel/core', + codeFrames: [ + { + code: await inputFS.readFile(fixture, 'utf8'), + filePath: fixture, + codeHighlights: [ + { + message: undefined, + start: { + line: 1, + column: 1, + }, + end: { + line: 1, + column: 1, + }, + }, + ], + }, + ], + }, + { + message: + 'External dependency "@swc/helpers" does not satisfy required semver range "^0.5.0".', + origin: '@parcel/resolver-default', + codeFrames: [ + { + code: pkgContents, + filePath: pkg, + language: 'json', + codeHighlights: [ + { + message: 'Found this conflicting requirement.', + start: { + line: 6, + column: 21, + }, + end: { + line: 6, + column: 28, + }, + }, + ], + }, + ], + hints: [ + 'Update the dependency on "@swc/helpers" to satisfy "^0.5.0".', + ], + }, + ], }, - ]); + ); + }, + ); + + describe('multiple import types', function () { + it.v2( + 'supports both static and dynamic imports to the same specifier in the same file', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-dynamic.js', + ), + ); + + assertBundles(b, [ + { + type: 'js', + assets: ['static-dynamic.js', 'other.js', 'esmodule-helpers.js'], + }, + ]); + + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.LazyFoo, 'object'); + assert.equal(res.Foo, await res.LazyFoo); + }, + ); + + it.v2( + 'supports both static and dynamic imports to the same specifier in the same file with scope hoisting', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-dynamic.js', + ), + { + defaultTargetOptions: { + outputFormat: 'esmodule', + isLibrary: true, + shouldScopeHoist: true, + }, + }, + ); + + assertBundles(b, [ + { + type: 'js', + assets: ['static-dynamic.js', 'other.js'], + }, + ]); + + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.LazyFoo, 'object'); + assert.equal(res.Foo, await res.LazyFoo); + }, + ); + + it.v2( + 'supports static, dynamic, and url to the same specifier in the same file', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-dynamic-url.js', + ), + ); + + assertBundles(b, [ + { + type: 'js', + assets: [ + 'static-dynamic-url.js', + 'other.js', + 'esmodule-helpers.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + type: 'js', + assets: ['other.js', 'esmodule-helpers.js'], + }, + ]); + + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.LazyFoo, 'object'); + assert.equal(res.Foo, await res.LazyFoo); + assert.equal( + res.url, + 'http://localhost/' + path.basename(b.getBundles()[1].filePath), + ); + }, + ); + + it.v2( + 'supports static, dynamic, and url to the same specifier in the same file with scope hoisting', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-dynamic-url.js', + ), + { + defaultTargetOptions: { + outputFormat: 'esmodule', + isLibrary: true, + shouldScopeHoist: true, + }, + }, + ); - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.LazyFoo, 'object'); - assert.equal(res.Foo, await res.LazyFoo); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); + assertBundles(b, [ + { + type: 'js', + assets: ['static-dynamic-url.js', 'other.js'], + }, + { + type: 'js', + assets: ['other.js'], + }, + ]); - it('supports dynamic import and url to the same specifier in the same file', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-url.js', - ), - ); + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.LazyFoo, 'object'); + assert.equal(res.Foo, await res.LazyFoo); + assert.equal( + res.url, + 'http://localhost/' + path.basename(b.getBundles()[1].filePath), + ); + }, + ); - assertBundles(b, [ - { - type: 'js', - assets: [ - 'dynamic-url.js', - 'esmodule-helpers.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); + it.v2( + 'supports dynamic import and url to the same specifier in the same file', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/dynamic-url.js', + ), + ); - it('supports dynamic import and url to the same specifier in the same file with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-url.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, + assertBundles(b, [ + { + type: 'js', + assets: [ + 'dynamic-url.js', + 'esmodule-helpers.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], }, - }, - ); - - assertBundles(b, [ - { - type: 'js', - assets: ['dynamic-url.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); + { + type: 'js', + assets: ['other.js', 'esmodule-helpers.js'], + }, + ]); + let res = await run(b); + assert.equal(typeof res.lazy, 'object'); + assert.equal(typeof (await res.lazy), 'function'); + assert.equal( + res.url, + 'http://localhost/' + path.basename(b.getBundles()[1].filePath), + ); + }, + ); - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal( - res.url, - 'http://localhost/' + path.basename(b.getBundles()[1].filePath), - ); - }); + it.v2( + 'supports dynamic import and url to the same specifier in the same file with scope hoisting', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/dynamic-url.js', + ), + { + defaultTargetOptions: { + outputFormat: 'esmodule', + isLibrary: true, + shouldScopeHoist: true, + }, + }, + ); - it('supports static import and inline bundle for the same asset', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-inline.js', - ), - ); + assertBundles(b, [ + { + type: 'js', + assets: ['dynamic-url.js'], + }, + { + type: 'js', + assets: ['other.js'], + }, + ]); - assertBundles(b, [ - { - type: 'js', - assets: ['static-inline.js', 'other.js', 'esmodule-helpers.js'], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); + let res = await run(b); + assert.equal(typeof res.lazy, 'object'); + assert.equal(typeof (await res.lazy), 'function'); + assert.equal( + res.url, + 'http://localhost/' + path.basename(b.getBundles()[1].filePath), + ); + }, + ); - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.text, 'string'); - }); + it.v2( + 'supports static import and inline bundle for the same asset', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-inline.js', + ), + ); - it('supports static import and inline bundle for the same asset with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/static-inline.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, + assertBundles(b, [ + { + type: 'js', + assets: ['static-inline.js', 'other.js', 'esmodule-helpers.js'], }, - }, - ); + { + type: 'js', + assets: ['other.js', 'esmodule-helpers.js'], + }, + ]); - assertBundles(b, [ - { - type: 'js', - assets: ['static-inline.js', 'other.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.text, 'string'); + }, + ); - let res = await run(b); - assert.equal(typeof res.Foo, 'function'); - assert.equal(typeof res.text, 'string'); - }); + it.v2( + 'supports static import and inline bundle for the same asset with scope hoisting', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/static-inline.js', + ), + { + defaultTargetOptions: { + outputFormat: 'esmodule', + isLibrary: true, + shouldScopeHoist: true, + }, + }, + ); - it('supports dynamic import and inline bundle for the same asset', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-inline.js', - ), - ); + assertBundles(b, [ + { + type: 'js', + assets: ['static-inline.js', 'other.js'], + }, + { + type: 'js', + assets: ['other.js'], + }, + ]); - assertBundles(b, [ - { - type: 'js', - assets: [ - 'dynamic-inline.js', - 'esmodule-helpers.js', - 'bundle-url.js', - 'cacheLoader.js', - 'js-loader.js', - ], - }, - { - type: 'js', - assets: ['other.js'], - }, - { - type: 'js', - assets: ['other.js', 'esmodule-helpers.js'], - }, - ]); + let res = await run(b); + assert.equal(typeof res.Foo, 'function'); + assert.equal(typeof res.text, 'string'); + }, + ); - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal(typeof res.text, 'string'); - }); + it.v2( + 'supports dynamic import and inline bundle for the same asset', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/dynamic-inline.js', + ), + ); - it('supports dynamic import and inline bundle for the same asset with scope hoisting', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/multiple-import-types/dynamic-inline.js', - ), - { - defaultTargetOptions: { - outputFormat: 'esmodule', - isLibrary: true, - shouldScopeHoist: true, + assertBundles(b, [ + { + type: 'js', + assets: [ + 'dynamic-inline.js', + 'esmodule-helpers.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], }, - }, - ); + { + type: 'js', + assets: ['other.js'], + }, + { + type: 'js', + assets: ['other.js', 'esmodule-helpers.js'], + }, + ]); - assertBundles(b, [ - { - type: 'js', - assets: ['dynamic-inline.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - { - type: 'js', - assets: ['other.js'], - }, - ]); + let res = await run(b); + assert.equal(typeof res.lazy, 'object'); + assert.equal(typeof (await res.lazy), 'function'); + assert.equal(typeof res.text, 'string'); + }, + ); - let res = await run(b); - assert.equal(typeof res.lazy, 'object'); - assert.equal(typeof (await res.lazy), 'function'); - assert.equal(typeof res.text, 'string'); - }); - }); + it.v2( + 'supports dynamic import and inline bundle for the same asset with scope hoisting', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/multiple-import-types/dynamic-inline.js', + ), + { + defaultTargetOptions: { + outputFormat: 'esmodule', + isLibrary: true, + shouldScopeHoist: true, + }, + }, + ); - it('should avoid creating a bundle for lazy dependencies already available in a shared bundle', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/shared-bundle-internalization/index.mjs', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, - }, + assertBundles(b, [ + { + type: 'js', + assets: ['dynamic-inline.js'], + }, + { + type: 'js', + assets: ['other.js'], + }, + { + type: 'js', + assets: ['other.js'], + }, + ]); + + let res = await run(b); + assert.equal(typeof res.lazy, 'object'); + assert.equal(typeof (await res.lazy), 'function'); + assert.equal(typeof res.text, 'string'); }, ); - - assert.deepEqual(await (await run(b)).default, [42, 42]); }); - it('should support standalone import.meta', async function () { + it.v2( + 'should avoid creating a bundle for lazy dependencies already available in a shared bundle', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-internalization/index.mjs', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); + + assert.deepEqual(await (await run(b)).default, [42, 42]); + }, + ); + + it.v2('should support standalone import.meta', async function () { let b = await bundle( path.join(__dirname, 'integration/import-meta/index.js'), ); @@ -4586,93 +5074,105 @@ describe('javascript', function () { }); }); - it('should support importing async bundles from bundles with different dist paths', async function () { - let bundleGraph = await bundle( - ['bar/entry/entry-a.js', 'foo/entry-b.js'].map(f => - path.join(__dirname, 'integration/differing-bundle-urls', f), - ), - { - mode: 'production', - defaultTargetOptions: { - shouldOptimize: false, + it.v2( + 'should support importing async bundles from bundles with different dist paths', + async function () { + let bundleGraph = await bundle( + ['bar/entry/entry-a.js', 'foo/entry-b.js'].map(f => + path.join(__dirname, 'integration/differing-bundle-urls', f), + ), + { + mode: 'production', + defaultTargetOptions: { + shouldOptimize: false, + }, }, - }, - ); - assertBundles(bundleGraph, [ - { - name: 'entry-a.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'entry-a.js', - 'js-loader.js', - ], - }, - { - name: 'entry-b.js', - assets: [ - 'bundle-manifest.js', - 'bundle-url.js', - 'cacheLoader.js', - 'entry-b.js', - 'js-loader.js', - ], - }, - {name: /deep\.[a-f0-9]+\.js/, assets: ['deep.js']}, - {name: /common\.[a-f0-9]+\.js/, assets: ['index.js']}, - ]); + ); + assertBundles(bundleGraph, [ + { + name: 'entry-a.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'entry-a.js', + 'js-loader.js', + ], + }, + { + name: 'entry-b.js', + assets: [ + 'bundle-manifest.js', + 'bundle-url.js', + 'cacheLoader.js', + 'entry-b.js', + 'js-loader.js', + ], + }, + {name: /deep\.[a-f0-9]+\.js/, assets: ['deep.js']}, + {name: /common\.[a-f0-9]+\.js/, assets: ['index.js']}, + ]); - let [a, b] = bundleGraph.getBundles().filter(b => b.needsStableName); - let calls = []; + let [a, b] = bundleGraph.getBundles().filter(b => b.needsStableName); + let calls = []; - let bundles = [ - [await outputFS.readFile(a.filePath, 'utf8'), a], - [await outputFS.readFile(b.filePath, 'utf8'), b], - ]; + let bundles = [ + [await outputFS.readFile(a.filePath, 'utf8'), a], + [await outputFS.readFile(b.filePath, 'utf8'), b], + ]; - await runBundles(bundleGraph, a, bundles, { - sideEffect: v => { - calls.push(v); - }, - }); + await runBundles(bundleGraph, a, bundles, { + sideEffect: v => { + calls.push(v); + }, + }); - assert.deepEqual(calls, ['common', 'deep']); - }); + assert.deepEqual(calls, ['common', 'deep']); + }, + ); - it('supports deferring unused ESM imports with sideEffects: false', async function () { - let b = await bundle( - path.join(__dirname, '/integration/side-effects-false/import.js'), - ); + it.v2( + 'supports deferring unused ESM imports with sideEffects: false', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/side-effects-false/import.js'), + ); - let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + let content = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert(!content.includes('returned from bar')); + assert(!content.includes('returned from bar')); - let called = false; - let output = await run(b, { - sideEffect() { - called = true; - }, - }); + let called = false; + let output = await run(b, { + sideEffect() { + called = true; + }, + }); - assert(!called, 'side effect called'); - assert.strictEqual(output.default, 4); - }); + assert(!called, 'side effect called'); + assert.strictEqual(output.default, 4); + }, + ); - it('supports ESM imports and requires with sideEffects: false', async function () { - let b = await bundle( - path.join(__dirname, '/integration/side-effects-false/import-require.js'), - ); + it.v2( + 'supports ESM imports and requires with sideEffects: false', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/side-effects-false/import-require.js', + ), + ); - let output = await run(b, { - sideEffect() {}, - }); + let output = await run(b, { + sideEffect() {}, + }); - assert.strictEqual(output.default, '4returned from bar'); - }); + assert.strictEqual(output.default, '4returned from bar'); + }, + ); - it('should not affect ESM import order', async function () { + it.v2('should not affect ESM import order', async function () { const b = await bundle( path.join(__dirname, '/integration/js-import-initialization/a.mjs'), ); @@ -4683,64 +5183,73 @@ describe('javascript', function () { ); }); - it('should not affect ESM import order with scope hoisting', async function () { - const b = await bundle( - path.join(__dirname, '/integration/js-import-initialization/a.mjs'), - { - defaultTargetOptions: { - shouldScopeHoist: true, + it.v2( + 'should not affect ESM import order with scope hoisting', + async function () { + const b = await bundle( + path.join(__dirname, '/integration/js-import-initialization/a.mjs'), + { + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); + ); - await assert.rejects( - run(b), - /^ReferenceError: Cannot access '(.+)' before initialization$/, - ); - }); + await assert.rejects( + run(b), + /^ReferenceError: Cannot access '(.+)' before initialization$/, + ); + }, + ); - it('should produce working output with both scope hoisting and non scope hoisting targets', async function () { - let b = await bundle( - path.join(__dirname, '/integration/re-export-no-scope-hoist'), - { - defaultTargetOptions: { - shouldScopeHoist: true, + it.v2( + 'should produce working output with both scope hoisting and non scope hoisting targets', + async function () { + let b = await bundle( + path.join(__dirname, '/integration/re-export-no-scope-hoist'), + { + defaultTargetOptions: { + shouldScopeHoist: true, + }, }, - }, - ); - let bundles = b.getBundles(); + ); + let bundles = b.getBundles(); - let o1, o2; - await runBundle(b, bundles[0], { - output: (...o) => (o1 = o), - }); + let o1, o2; + await runBundle(b, bundles[0], { + output: (...o) => (o1 = o), + }); - await runBundle(b, bundles[1], { - output: (...o) => (o2 = o), - }); + await runBundle(b, bundles[1], { + output: (...o) => (o2 = o), + }); - assert.deepEqual(o1, ['UIIcon', 'Icon']); - assert.deepEqual(o2, ['UIIcon', 'Icon']); - }); + assert.deepEqual(o1, ['UIIcon', 'Icon']); + assert.deepEqual(o2, ['UIIcon', 'Icon']); + }, + ); - it('should not deduplicate an asset if it will become unreachable', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/sibling-deduplicate-unreachable/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + it.v2( + 'should not deduplicate an asset if it will become unreachable', + async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/sibling-deduplicate-unreachable/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, }, - }, - ); - let res = await run(b); - assert.equal(await res.default, 'target'); - }); + ); + let res = await run(b); + assert.equal(await res.default, 'target'); + }, + ); - it('should detect shorthand identifier imports', async function () { + it.v2('should detect shorthand identifier imports', async function () { const dir = path.join(__dirname, 'js-import-shorthand-identifier'); overlayFS.mkdirp(dir); @@ -4778,7 +5287,7 @@ describe('javascript', function () { assert.deepEqual(output.default, {color: 'blue'}); }); - it('should retain unicode escape sequences', async function () { + it.v2('should retain unicode escape sequences', async function () { // See issue #8877 await fsFixture(overlayFS, __dirname)` src/index.js: @@ -4799,11 +5308,13 @@ describe('javascript', function () { assert(!contents.includes('\ufffe')); }); - it(`should not wrap assets that are duplicated in different targets`, async function () { - const dir = path.join(__dirname, 'multi-target-duplicates'); - overlayFS.mkdirp(dir); + it.v2( + `should not wrap assets that are duplicated in different targets`, + async function () { + const dir = path.join(__dirname, 'multi-target-duplicates'); + overlayFS.mkdirp(dir); - await fsFixture(overlayFS, dir)` + await fsFixture(overlayFS, dir)` shared/index.js: export default 2; @@ -4828,20 +5339,21 @@ describe('javascript', function () { export default shared + 2; `; - let b = await bundle(path.join(dir, '/packages/*'), { - inputFS: overlayFS, - }); + let b = await bundle(path.join(dir, '/packages/*'), { + inputFS: overlayFS, + }); - for (let bundle of b.getBundles()) { - let contents = await outputFS.readFile(bundle.filePath, 'utf8'); - assert( - !contents.includes('parcelRequire'), - 'should not include parcelRequire', - ); - } - }); + for (let bundle of b.getBundles()) { + let contents = await outputFS.readFile(bundle.filePath, 'utf8'); + assert( + !contents.includes('parcelRequire'), + 'should not include parcelRequire', + ); + } + }, + ); - it(`should also fail on recoverable parse errors`, async () => { + it.v2(`should also fail on recoverable parse errors`, async () => { await fsFixture(overlayFS, __dirname)` js-recoverable-parse-errors index.js: @@ -4900,247 +5412,265 @@ describe('javascript', function () { shouldScopeHoist ? '' : 'out' } scope-hoisting`, function () { if (usesSymbolPropagation) { - it('supports excluding unused CSS imports', async function () { + it.v2('supports excluding unused CSS imports', async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-css/index.html', + ), + options, + ); + + assertBundles(b, [ + { + name: 'index.html', + assets: ['index.html'], + }, + { + type: 'js', + assets: ['index.js', 'b1.js'], + }, + { + type: 'css', + assets: ['b1.css'], + }, + ]); + + let calls = []; + let res = await run( + b, + { + output: null, + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); + assert.deepEqual(calls, ['b1']); + assert.deepEqual(res.output, 2); + + let css = await outputFS.readFile( + b.getBundles().find(bundle => bundle.type === 'css').filePath, + 'utf8', + ); + assert(!css.includes('.b2')); + }); + + it.v2( + "doesn't create new bundles for dynamic imports in excluded assets", + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-no-new-bundle/index.html', + ), + options, + ); + + assertBundles(b, [ + { + name: 'index.html', + assets: ['index.html'], + }, + { + type: 'js', + assets: ['index.js', 'b1.js'], + }, + ]); + + let calls = []; + let res = await run( + b, + { + output: null, + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); + assert.deepEqual(calls, ['b1']); + assert.deepEqual(res.output, 2); + }, + ); + } + + it.v2( + 'supports deferring unused ES6 re-exports (namespace used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports/a.js', + ), + options, + ); + + assertBundles(b, [ + { + type: 'js', + assets: usesSymbolPropagation + ? ['a.js', 'message1.js'] + : ['a.js', 'esmodule-helpers.js', 'index.js', 'message1.js'], + }, + ]); + + if (usesSymbolPropagation) { + // TODO this only excluded, but should be deferred. + assert(!findAsset(b, 'message3.js')); + } + + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); + + assert.deepEqual( + calls, + shouldScopeHoist ? ['message1'] : ['message1', 'index'], + ); + assert.deepEqual(res.output, 'Message 1'); + }, + ); + + it.v2( + 'supports deferring an unused ES6 re-export (wildcard, empty, unused)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-all-empty/a.js', + ), + options, + ); + + if (usesSymbolPropagation) { + assertDependencyWasExcluded(b, 'index.js', './empty.js'); + } + + assert.deepEqual((await run(b, null, {require: false})).output, 123); + }, + ); + + it.v2( + 'supports deferring unused ES6 re-exports (reexport named used)', + async function () { let b = await bundle( path.join( __dirname, - '/integration/scope-hoisting/es6/side-effects-css/index.html', + '/integration/scope-hoisting/es6/side-effects-re-exports/b.js', ), options, ); - assertBundles(b, [ - { - name: 'index.html', - assets: ['index.html'], - }, - { - type: 'js', - assets: ['index.js', 'b1.js'], - }, - { - type: 'css', - assets: ['b1.css'], - }, - ]); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'message1.js')); + assert(!findAsset(b, 'message3.js')); + } let calls = []; let res = await run( b, { - output: null, sideEffect: caller => { calls.push(caller); }, }, {require: false}, ); - assert.deepEqual(calls, ['b1']); - assert.deepEqual(res.output, 2); - let css = await outputFS.readFile( - b.getBundles().find(bundle => bundle.type === 'css').filePath, - 'utf8', + assert.deepEqual( + calls, + shouldScopeHoist ? ['message2'] : ['message2', 'index'], ); - assert(!css.includes('.b2')); - }); + assert.deepEqual(res.output, 'Message 2'); + }, + ); - it("doesn't create new bundles for dynamic imports in excluded assets", async function () { + it.v2( + 'supports deferring unused ES6 re-exports (namespace rename used)', + async function () { let b = await bundle( path.join( __dirname, - '/integration/scope-hoisting/es6/side-effects-no-new-bundle/index.html', + '/integration/scope-hoisting/es6/side-effects-re-exports/c.js', ), options, ); assertBundles(b, [ - { - name: 'index.html', - assets: ['index.html'], - }, { type: 'js', - assets: ['index.js', 'b1.js'], + assets: usesSymbolPropagation + ? ['c.js', 'message3.js'] + : ['c.js', 'esmodule-helpers.js', 'index.js', 'message3.js'], }, ]); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'message1.js')); + } + let calls = []; let res = await run( b, { - output: null, sideEffect: caller => { calls.push(caller); }, }, {require: false}, ); - assert.deepEqual(calls, ['b1']); - assert.deepEqual(res.output, 2); - }); - } - - it('supports deferring unused ES6 re-exports (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/a.js', - ), - options, - ); - - assertBundles(b, [ - { - type: 'js', - assets: usesSymbolPropagation - ? ['a.js', 'message1.js'] - : ['a.js', 'esmodule-helpers.js', 'index.js', 'message1.js'], - }, - ]); - - if (usesSymbolPropagation) { - // TODO this only excluded, but should be deferred. - assert(!findAsset(b, 'message3.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message1'] : ['message1', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); - - it('supports deferring an unused ES6 re-export (wildcard, empty, unused)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-all-empty/a.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assertDependencyWasExcluded(b, 'index.js', './empty.js'); - } - - assert.deepEqual((await run(b, null, {require: false})).output, 123); - }); - - it('supports deferring unused ES6 re-exports (reexport named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/b.js', - ), - options, - ); - - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - assert(!findAsset(b, 'message3.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message2'] : ['message2', 'index'], - ); - assert.deepEqual(res.output, 'Message 2'); - }); - - it('supports deferring unused ES6 re-exports (namespace rename used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/c.js', - ), - options, - ); - - assertBundles(b, [ - { - type: 'js', - assets: usesSymbolPropagation - ? ['c.js', 'message3.js'] - : ['c.js', 'esmodule-helpers.js', 'index.js', 'message3.js'], - }, - ]); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - } - - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist ? ['message3'] : ['message3', 'index'], - ); - assert.deepEqual(res.output, {default: 'Message 3'}); - }); + assert.deepEqual( + calls, + shouldScopeHoist ? ['message3'] : ['message3', 'index'], + ); + assert.deepEqual(res.output, {default: 'Message 3'}); + }, + ); - it('supports deferring unused ES6 re-exports (direct export used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports/d.js', - ), - options, - ); + it.v2( + 'supports deferring unused ES6 re-exports (direct export used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports/d.js', + ), + options, + ); - assertDependencyWasExcluded(b, 'index.js', './message2.js'); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'message1.js')); - assert(!findAsset(b, 'message3.js')); - } + assertDependencyWasExcluded(b, 'index.js', './message2.js'); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'message1.js')); + assert(!findAsset(b, 'message3.js')); + } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert.deepEqual(calls, ['index']); - assert.deepEqual(res.output, 'Message 4'); - }); + assert.deepEqual(calls, ['index']); + assert.deepEqual(res.output, 'Message 4'); + }, + ); - it('supports chained ES6 re-exports', async function () { + it.v2('supports chained ES6 re-exports', async function () { let b = await bundle( path.join( __dirname, @@ -5155,168 +5685,186 @@ describe('javascript', function () { let calls = []; let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); - - if (shouldScopeHoist) { - try { - assert.deepEqual(calls, ['key', 'foo', 'index']); - } catch (e) { - // A different dependency order, but this is deemed acceptable as it's sideeffect free - assert.deepEqual(calls, ['foo', 'key', 'index']); - } - } else { - assert.deepEqual(calls, ['key', 'foo', 'types', 'index']); - } - - assert.deepEqual(res.output, ['key', 'foo']); - }); - - it('should not optimize away an unused ES6 re-export and an used import', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-import/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 123); - }); - - it('should not optimize away an unused ES6 re-export and an used import (different symbols)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-import-different/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 123); - }); - - it('correctly handles ES6 re-exports in library mode entries', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-library/a.js', - ), - options, - ); - - let contents = await outputFS.readFile( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-library/build.js', - ), - 'utf8', - ); - assert(!contents.includes('console.log')); - - let res = await run(b); - assert.deepEqual(res, {c1: 'foo'}); - }); - - if (shouldScopeHoist) { - it('correctly updates deferred assets that are reexported', async function () { - let testDir = path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-update-deferred-reexported', - ); - - let b = bundler(path.join(testDir, 'index.js'), { - inputFS: overlayFS, - outputFS: overlayFS, - ...options, - }); - - let subscription = await b.watch(); - - let bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - let output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '12345hello'); - - await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); - await overlayFS.copyFile( - path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), - path.join(testDir, 'node_modules', 'foo', 'foo.js'), - ); + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); - bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '1234556789'); + if (shouldScopeHoist) { + try { + assert.deepEqual(calls, ['key', 'foo', 'index']); + } catch (e) { + // A different dependency order, but this is deemed acceptable as it's sideeffect free + assert.deepEqual(calls, ['foo', 'key', 'index']); + } + } else { + assert.deepEqual(calls, ['key', 'foo', 'types', 'index']); + } - await subscription.unsubscribe(); - }); + assert.deepEqual(res.output, ['key', 'foo']); + }); - it('correctly updates deferred assets that are reexported and imported directly', async function () { - let testDir = path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-update-deferred-direct', + it.v2( + 'should not optimize away an unused ES6 re-export and an used import', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-import/a.js', + ), + options, ); - let b = bundler(path.join(testDir, 'index.js'), { - inputFS: overlayFS, - outputFS: overlayFS, - ...options, - }); - - let subscription = await b.watch(); - - let bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - let output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '12345hello'); + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, 123); + }, + ); - await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); - await overlayFS.copyFile( - path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), - path.join(testDir, 'node_modules', 'foo', 'foo.js'), + it.v2( + 'should not optimize away an unused ES6 re-export and an used import (different symbols)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-import-different/a.js', + ), + options, ); - bundleEvent = await getNextBuild(b); - assert(bundleEvent.type === 'buildSuccess'); - output = await run(bundleEvent.bundleGraph); - assert.deepEqual(output, '1234556789'); - - await subscription.unsubscribe(); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, 123); + }, + ); - it('removes deferred reexports when imported from multiple asssets', async function () { + it.v2( + 'correctly handles ES6 re-exports in library mode entries', + async function () { let b = await bundle( path.join( __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-multiple-dynamic/a.js', + '/integration/scope-hoisting/es6/side-effects-re-exports-library/a.js', ), options, ); let contents = await outputFS.readFile( - b.getBundles()[0].filePath, + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-library/build.js', + ), 'utf8', ); + assert(!contents.includes('console.log')); - assert(!contents.includes('$import$')); - assert(/=\s*1234/.test(contents)); - assert(!/=\s*5678/.test(contents)); + let res = await run(b); + assert.deepEqual(res, {c1: 'foo'}); + }, + ); - let output = await run(b); - assert.deepEqual(output, [1234, {default: 1234}]); - }); + if (shouldScopeHoist) { + it.v2( + 'correctly updates deferred assets that are reexported', + async function () { + let testDir = path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-update-deferred-reexported', + ); + + let b = bundler(path.join(testDir, 'index.js'), { + inputFS: overlayFS, + outputFS: overlayFS, + ...options, + }); + + let subscription = await b.watch(); + + let bundleEvent = await getNextBuild(b); + assert(bundleEvent.type === 'buildSuccess'); + let output = await run(bundleEvent.bundleGraph); + assert.deepEqual(output, '12345hello'); + + await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); + await overlayFS.copyFile( + path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), + path.join(testDir, 'node_modules', 'foo', 'foo.js'), + ); + + bundleEvent = await getNextBuild(b); + assert(bundleEvent.type === 'buildSuccess'); + output = await run(bundleEvent.bundleGraph); + assert.deepEqual(output, '1234556789'); + + await subscription.unsubscribe(); + }, + ); + + it.v2( + 'correctly updates deferred assets that are reexported and imported directly', + async function () { + let testDir = path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-update-deferred-direct', + ); + + let b = bundler(path.join(testDir, 'index.js'), { + inputFS: overlayFS, + outputFS: overlayFS, + ...options, + }); + + let subscription = await b.watch(); + + let bundleEvent = await getNextBuild(b); + assert(bundleEvent.type === 'buildSuccess'); + let output = await run(bundleEvent.bundleGraph); + assert.deepEqual(output, '12345hello'); + + await overlayFS.mkdirp(path.join(testDir, 'node_modules', 'foo')); + await overlayFS.copyFile( + path.join(testDir, 'node_modules', 'foo', 'foo_updated.js'), + path.join(testDir, 'node_modules', 'foo', 'foo.js'), + ); + + bundleEvent = await getNextBuild(b); + assert(bundleEvent.type === 'buildSuccess'); + output = await run(bundleEvent.bundleGraph); + assert.deepEqual(output, '1234556789'); + + await subscription.unsubscribe(); + }, + ); + + it.v2( + 'removes deferred reexports when imported from multiple asssets', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-multiple-dynamic/a.js', + ), + options, + ); + + let contents = await outputFS.readFile( + b.getBundles()[0].filePath, + 'utf8', + ); + + assert(!contents.includes('$import$')); + assert(/=\s*1234/.test(contents)); + assert(!/=\s*5678/.test(contents)); + + let output = await run(b); + assert.deepEqual(output, [1234, {default: 1234}]); + }, + ); } - it('keeps side effects by default', async function () { + it.v2('keeps side effects by default', async function () { let b = await bundle( path.join( __dirname, @@ -5340,31 +5888,34 @@ describe('javascript', function () { assert.deepEqual(res.output, 4); }); - it('supports the package.json sideEffects: false flag', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false/a.js', - ), - options, - ); + it.v2( + 'supports the package.json sideEffects: false flag', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-false/a.js', + ), + options, + ); - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; + let called = false; + let res = await run( + b, + { + sideEffect: () => { + called = true; + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 4); - }); + assert(!called, 'side effect called'); + assert.deepEqual(res.output, 4); + }, + ); - it('supports removing a deferred dependency', async function () { + it.v2('supports removing a deferred dependency', async function () { let testDir = path.join( __dirname, '/integration/scope-hoisting/es6/side-effects-false', @@ -5422,7 +5973,7 @@ describe('javascript', function () { } }); - it('supports wildcards', async function () { + it.v2('supports wildcards', async function () { let b = await bundle( path.join( __dirname, @@ -5447,433 +5998,458 @@ describe('javascript', function () { assert.deepEqual(res.output, 'bar'); }); - it('correctly handles excluded and wrapped reexport assets', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false-wrap-excluded/a.js', - ), - options, - ); + it.v2( + 'correctly handles excluded and wrapped reexport assets', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-false-wrap-excluded/a.js', + ), + options, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, 4); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, 4); + }, + ); - it('supports the package.json sideEffects flag with an array', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-array/a.js', - ), - options, - ); + it.v2( + 'supports the package.json sideEffects flag with an array', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-array/a.js', + ), + options, + ); - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert(calls.toString() == 'foo', "side effect called for 'foo'"); - assert.deepEqual(res.output, 4); - }); + assert(calls.toString() == 'foo', "side effect called for 'foo'"); + assert.deepEqual(res.output, 4); + }, + ); - it('supports the package.json sideEffects: false flag with shared dependencies', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-false-duplicate/a.js', - ), - options, - ); + it.v2( + 'supports the package.json sideEffects: false flag with shared dependencies', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-false-duplicate/a.js', + ), + options, + ); - let called = false; - let res = await run( - b, - { - sideEffect: () => { - called = true; + let called = false; + let res = await run( + b, + { + sideEffect: () => { + called = true; + }, }, - }, - {require: false}, - ); - - assert(!called, 'side effect called'); - assert.deepEqual(res.output, 6); - }); - - it('supports the package.json sideEffects: false flag with shared dependencies and code splitting', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-split/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, 581); - }); - - it('supports the package.json sideEffects: false flag with shared dependencies and code splitting II', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-split2/a.js', - ), - options, - ); + {require: false}, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, [{default: 123, foo: 2}, 581]); - }); + assert(!called, 'side effect called'); + assert.deepEqual(res.output, 6); + }, + ); - it('missing exports should be replaced with an empty object', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/empty-module/a.js', - ), - options, - ); + it.v2( + 'supports the package.json sideEffects: false flag with shared dependencies and code splitting', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-split/a.js', + ), + options, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, {b: {}}); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(await res.output, 581); + }, + ); - it('supports namespace imports of theoretically excluded reexporting assets', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/import-namespace-sideEffects/index.js', - ), - options, - ); + it.v2( + 'supports the package.json sideEffects: false flag with shared dependencies and code splitting II', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-split2/a.js', + ), + options, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, {Main: 'main', a: 'foo', b: 'bar'}); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(await res.output, [{default: 123, foo: 2}, 581]); + }, + ); - it('can import from a different bundle via a re-export', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/re-export-bundle-boundary-side-effects/index.js', - ), - options, - ); + it.v2( + 'missing exports should be replaced with an empty object', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/empty-module/a.js', + ), + options, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(await res.output, ['operational', 'ui']); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, {b: {}}); + }, + ); - it('supports excluding multiple chained namespace reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-chained-re-exports-multiple/a.js', - ), - options, - ); + it.v2( + 'supports namespace imports of theoretically excluded reexporting assets', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/import-namespace-sideEffects/index.js', + ), + options, + ); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'symbol1.js')); - } + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, {Main: 'main', a: 'foo', b: 'bar'}); + }, + ); - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); + it.v2( + 'can import from a different bundle via a re-export', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/re-export-bundle-boundary-side-effects/index.js', + ), + options, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['message1'] : ['message1', 'message'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); + let res = await run(b, null, {require: false}); + assert.deepEqual(await res.output, ['operational', 'ui']); + }, + ); - it('supports excluding when doing both exports and reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-export-reexport/a.js', - ), - options, - ); + it.v2( + 'supports excluding multiple chained namespace reexports', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-chained-re-exports-multiple/a.js', + ), + options, + ); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'other.js')); - } + if (usesSymbolPropagation) { + assert(!findAsset(b, 'symbol1.js')); + } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert.deepEqual(calls, ['index']); - assert.deepEqual(res.output, 'Message 1'); - }); + assert.deepEqual( + calls, + shouldScopeHoist ? ['message1'] : ['message1', 'message'], + ); + assert.deepEqual(res.output, 'Message 1'); + }, + ); - it('supports deferring with chained renaming reexports', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-chained/a.js', - ), - options, - ); + it.v2( + 'supports excluding when doing both exports and reexports', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-export-reexport/a.js', + ), + options, + ); - // assertDependencyWasExcluded(b, 'message.js', './message2'); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'other.js')); + } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); - - assert.deepEqual( - calls, - shouldScopeHoist - ? ['message1'] - : ['message1', 'message', 'index2', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); + {require: false}, + ); - it('supports named and renamed reexports of the same asset (default used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/a.js', - ), - options, - ); + assert.deepEqual(calls, ['index']); + assert.deepEqual(res.output, 'Message 1'); + }, + ); - if (usesSymbolPropagation) { - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), + it.v2( + 'supports deferring with chained renaming reexports', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-rename-chained/a.js', + ), + options, ); - } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); + // assertDependencyWasExcluded(b, 'message.js', './message2'); - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, 'bar'); - }); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); - it('supports named and renamed reexports of the same asset (named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/b.js', - ), - options, - ); + assert.deepEqual( + calls, + shouldScopeHoist + ? ['message1'] + : ['message1', 'message', 'index2', 'index'], + ); + assert.deepEqual(res.output, 'Message 1'); + }, + ); - if (usesSymbolPropagation) { - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), + it.v2( + 'supports named and renamed reexports of the same asset (default used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/a.js', + ), + options, ); - } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + if (usesSymbolPropagation) { + assert.deepStrictEqual( + new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), + new Set(['bar']), + ); + } + + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, 'bar'); - }); + assert.deepEqual( + calls, + shouldScopeHoist ? ['other'] : ['other', 'index'], + ); + assert.deepEqual(res.output, 'bar'); + }, + ); - it('supports named and renamed reexports of the same asset (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same/index.js', - ), - options, - ); + it.v2( + 'supports named and renamed reexports of the same asset (named used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same2/b.js', + ), + options, + ); - let res = await run(b, null, {require: false}); - assert.deepEqual(res.output, [{value1: 123, value2: 123}, 123, 123]); - }); + if (usesSymbolPropagation) { + assert.deepStrictEqual( + new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), + new Set(['bar']), + ); + } - it('supports reexports via variable declaration (unused)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-rename-var-unused/index.js', - ), - options, - ); + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ); - let res = await run(b, {}, {require: false}); - assert.deepEqual((await res.output).foo, 'foo'); - }); + assert.deepEqual( + calls, + shouldScopeHoist ? ['other'] : ['other', 'index'], + ); + assert.deepEqual(res.output, 'bar'); + }, + ); - it('supports named and namespace exports of the same asset (named used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/a.js', - ), - options, - ); + it.v2( + 'supports named and renamed reexports of the same asset (namespace used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-rename-same/index.js', + ), + options, + ); - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['default']), + let res = await run(b, null, {require: false}); + assert.deepEqual(res.output, [{value1: 123, value2: 123}, 123, 123]); + }, + ); + + it.v2( + 'supports reexports via variable declaration (unused)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-rename-var-unused/index.js', + ), + options, ); - } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); + let res = await run(b, {}, {require: false}); + assert.deepEqual((await res.output).foo, 'foo'); + }, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['foo']); - }); + it.v2( + 'supports named and namespace exports of the same asset (named used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/a.js', + ), + options, + ); - it('supports named and namespace exports of the same asset (namespace used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/b.js', - ), - options, - ); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'index.js')); + assert.deepStrictEqual( + new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), + new Set(['default']), + ); + } - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['bar']), + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, ); - } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); + assert.deepEqual( + calls, + shouldScopeHoist ? ['other'] : ['other', 'index'], + ); + assert.deepEqual(res.output, ['foo']); + }, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['bar']); - }); + it.v2( + 'supports named and namespace exports of the same asset (namespace used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/b.js', + ), + options, + ); - it('supports named and namespace exports of the same asset (both used)', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/c.js', - ), - options, - ); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'index.js')); + assert.deepStrictEqual( + new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), + new Set(['bar']), + ); + } - if (usesSymbolPropagation) { - assert(!findAsset(b, 'index.js')); - assert.deepStrictEqual( - new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), - new Set(['default', 'bar']), + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, ); - } - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); - }, - }, - {require: false}, - ); + assert.deepEqual( + calls, + shouldScopeHoist ? ['other'] : ['other', 'index'], + ); + assert.deepEqual(res.output, ['bar']); + }, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['other'] : ['other', 'index'], - ); - assert.deepEqual(res.output, ['foo', 'bar']); - }); + it.v2( + 'supports named and namespace exports of the same asset (both used)', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-namespace-same/c.js', + ), + options, + ); - it('supports partially used reexporting index file', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-re-exports-partially-used/index.js', - ), - options, - ); + if (usesSymbolPropagation) { + assert(!findAsset(b, 'index.js')); + assert.deepStrictEqual( + new Set(b.getUsedSymbols(nullthrows(findAsset(b, 'other.js')))), + new Set(['default', 'bar']), + ); + } - let calls = []; - let res = ( - await run( + let calls = []; + let res = await run( b, { sideEffect: caller => { @@ -5881,54 +6457,89 @@ describe('javascript', function () { }, }, {require: false}, - ) - ).output; + ); - let [v, async] = res; + assert.deepEqual( + calls, + shouldScopeHoist ? ['other'] : ['other', 'index'], + ); + assert.deepEqual(res.output, ['foo', 'bar']); + }, + ); - assert.deepEqual(calls, shouldScopeHoist ? ['b'] : ['b', 'index']); - assert.deepEqual(v, 2); + it.v2( + 'supports partially used reexporting index file', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-re-exports-partially-used/index.js', + ), + options, + ); - v = await async(); - assert.deepEqual( - calls, - shouldScopeHoist - ? ['b', 'a', 'index', 'dynamic'] - : ['b', 'index', 'a', 'dynamic'], - ); - assert.deepEqual(v.default, [1, 3]); - }); + let calls = []; + let res = ( + await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, + }, + {require: false}, + ) + ).output; - it('supports deferring non-weak dependencies that are not used', async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/scope-hoisting/es6/side-effects-semi-weak/a.js', - ), - options, - ); + let [v, async] = res; - // assertDependencyWasExcluded(b, 'esm2.js', './other.js'); + assert.deepEqual(calls, shouldScopeHoist ? ['b'] : ['b', 'index']); + assert.deepEqual(v, 2); - let calls = []; - let res = await run( - b, - { - sideEffect: caller => { - calls.push(caller); + v = await async(); + assert.deepEqual( + calls, + shouldScopeHoist + ? ['b', 'a', 'index', 'dynamic'] + : ['b', 'index', 'a', 'dynamic'], + ); + assert.deepEqual(v.default, [1, 3]); + }, + ); + + it.v2( + 'supports deferring non-weak dependencies that are not used', + async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/side-effects-semi-weak/a.js', + ), + options, + ); + + // assertDependencyWasExcluded(b, 'esm2.js', './other.js'); + + let calls = []; + let res = await run( + b, + { + sideEffect: caller => { + calls.push(caller); + }, }, - }, - {require: false}, - ); + {require: false}, + ); - assert.deepEqual( - calls, - shouldScopeHoist ? ['esm1'] : ['esm1', 'index'], - ); - assert.deepEqual(res.output, 'Message 1'); - }); + assert.deepEqual( + calls, + shouldScopeHoist ? ['esm1'] : ['esm1', 'index'], + ); + assert.deepEqual(res.output, 'Message 1'); + }, + ); - it('supports excluding CommonJS (CommonJS unused)', async function () { + it.v2('supports excluding CommonJS (CommonJS unused)', async function () { let b = await bundle( path.join( __dirname, @@ -5971,7 +6582,7 @@ describe('javascript', function () { assert.deepEqual(res.output, 'Message 1'); }); - it('supports excluding CommonJS (CommonJS used)', async function () { + it.v2('supports excluding CommonJS (CommonJS used)', async function () { let b = await bundle( path.join( __dirname, @@ -6008,58 +6619,74 @@ describe('javascript', function () { }); }); - it(`ignores missing unused import specifiers in source assets ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - path.join(__dirname, 'integration/js-unused-import-specifier/a.js'), - options, - ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); - - it(`ignores missing unused import specifiers in node-modules ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - path.join( - __dirname, - '/integration/js-unused-import-specifier-node-modules/a.js', - ), - options, - ); - - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); + it.v2( + `ignores missing unused import specifiers in source assets ${ + shouldScopeHoist ? 'with' : 'without' + } scope-hoisting`, + async function () { + let b = await bundle( + path.join(__dirname, 'integration/js-unused-import-specifier/a.js'), + options, + ); + let res = await run(b, null, {require: false}); + assert.equal(res.output, 123); + }, + ); - it(`duplicate assets should share module scope ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async function () { - let b = await bundle( - [ - path.join( - __dirname, - '/integration/scope-hoisting/es6/multi-entry-duplicates/one.js', - ), + it.v2( + `ignores missing unused import specifiers in node-modules ${ + shouldScopeHoist ? 'with' : 'without' + } scope-hoisting`, + async function () { + let b = await bundle( path.join( __dirname, - '/integration/scope-hoisting/es6/multi-entry-duplicates/two.js', + '/integration/js-unused-import-specifier-node-modules/a.js', ), - ], - options, - ); + options, + ); - let result = await runBundle(b, b.getBundles()[0], {}, {require: false}); + let res = await run(b, null, {require: false}); + assert.equal(res.output, 123); + }, + ); - assert.equal(await result.output, 2); - }); + it.v2( + `duplicate assets should share module scope ${ + shouldScopeHoist ? 'with' : 'without' + } scope-hoisting`, + async function () { + let b = await bundle( + [ + path.join( + __dirname, + '/integration/scope-hoisting/es6/multi-entry-duplicates/one.js', + ), + path.join( + __dirname, + '/integration/scope-hoisting/es6/multi-entry-duplicates/two.js', + ), + ], + options, + ); - it(`should work correctly with export called hasOwnProperty ${ - shouldScopeHoist ? 'with' : 'without' - } scope-hoisting`, async () => { - await fsFixture(overlayFS, __dirname)` + let result = await runBundle( + b, + b.getBundles()[0], + {}, + {require: false}, + ); + + assert.equal(await result.output, 2); + }, + ); + + it.v2( + `should work correctly with export called hasOwnProperty ${ + shouldScopeHoist ? 'with' : 'without' + } scope-hoisting`, + async () => { + await fsFixture(overlayFS, __dirname)` js-export-all-hasOwnProperty a.js: export function hasOwnProperty() { @@ -6076,15 +6703,16 @@ describe('javascript', function () { import * as x from './library'; output = sideEffectNoop(x).other;`; - let b = await bundle( - path.join(__dirname, 'js-export-all-hasOwnProperty/index.js'), - { - ...options, - inputFS: overlayFS, - }, - ); - let res = await run(b, null, {require: false}); - assert.equal(res.output, 123); - }); + let b = await bundle( + path.join(__dirname, 'js-export-all-hasOwnProperty/index.js'), + { + ...options, + inputFS: overlayFS, + }, + ); + let res = await run(b, null, {require: false}); + assert.equal(res.output, 123); + }, + ); } }); diff --git a/packages/core/integration-tests/test/json-reporter.js b/packages/core/integration-tests/test/json-reporter.js index a3d2aa2e47a..cb4c17aba05 100644 --- a/packages/core/integration-tests/test/json-reporter.js +++ b/packages/core/integration-tests/test/json-reporter.js @@ -5,7 +5,7 @@ import assert from 'assert'; import invariant from 'assert'; import path from 'path'; -import {bundle} from '@parcel/test-utils'; +import {bundle, describe, it} from '@parcel/test-utils'; import sinon from 'sinon'; const config = path.join( @@ -13,7 +13,7 @@ const config = path.join( './integration/custom-configs/.parcelrc-json-reporter', ); -describe('json reporter', () => { +describe.v2('json reporter', () => { it('logs bundling a commonjs bundle to stdout as json', async () => { let consoleStub = sinon.stub(console, 'log'); try { diff --git a/packages/core/integration-tests/test/kotlin.js b/packages/core/integration-tests/test/kotlin.js index 50cda460710..7a0603dfcb2 100644 --- a/packages/core/integration-tests/test/kotlin.js +++ b/packages/core/integration-tests/test/kotlin.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import {bundle, assertBundleTree, run} from '@parcel/test-utils'; +import {assertBundleTree, bundle, describe, it, run} from '@parcel/test-utils'; import commandExists from 'command-exists'; describe.skip('kotlin', function () { diff --git a/packages/core/integration-tests/test/lazy-compile.js b/packages/core/integration-tests/test/lazy-compile.js index 6f72b57d0cf..4a41a7f3302 100644 --- a/packages/core/integration-tests/test/lazy-compile.js +++ b/packages/core/integration-tests/test/lazy-compile.js @@ -2,6 +2,8 @@ import assert from 'assert'; import path from 'path'; import { bundler, + describe, + it, outputFS, distDir, getNextBuild, @@ -47,7 +49,7 @@ const distDirIncludes = async matches => { return true; }; -describe('lazy compile', function () { +describe.v2('lazy compile', function () { it('should lazy compile', async function () { const b = await bundler( path.join(__dirname, '/integration/lazy-compile/index.js'), diff --git a/packages/core/integration-tests/test/less.js b/packages/core/integration-tests/test/less.js index 409e7f2cc56..7bc7658eada 100644 --- a/packages/core/integration-tests/test/less.js +++ b/packages/core/integration-tests/test/less.js @@ -1,15 +1,17 @@ import assert from 'assert'; import path from 'path'; import { - bundle, - run, assertBundles, + bundle, + describe, distDir, + it, outputFS, + run, } from '@parcel/test-utils'; import {md} from '@parcel/diagnostic'; -describe('less', function () { +describe.v2('less', function () { it('should support requiring less files', async function () { let b = await bundle(path.join(__dirname, '/integration/less/index.js')); diff --git a/packages/core/integration-tests/test/library-bundler.js b/packages/core/integration-tests/test/library-bundler.js index 61cf8941199..eb22c3ebb10 100644 --- a/packages/core/integration-tests/test/library-bundler.js +++ b/packages/core/integration-tests/test/library-bundler.js @@ -3,6 +3,8 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, runBundle, overlayFS, @@ -12,7 +14,7 @@ import { } from '@parcel/test-utils'; import nullthrows from 'nullthrows'; -describe('library bundler', function () { +describe.v2('library bundler', function () { let count = 0; let dir; beforeEach(async () => { @@ -50,7 +52,7 @@ describe('library bundler', function () { export function foo() { return 'foo' + baz(); } - + bar.js: import {baz} from './baz'; export function bar() { @@ -147,7 +149,7 @@ describe('library bundler', function () { export function bar() { return css('.b { color: pink }'); } - + macro.js: export function css(content) { this.addAsset({type: 'css', content}); diff --git a/packages/core/integration-tests/test/macros.js b/packages/core/integration-tests/test/macros.js index fd6d978abc2..47be2dcd917 100644 --- a/packages/core/integration-tests/test/macros.js +++ b/packages/core/integration-tests/test/macros.js @@ -5,13 +5,15 @@ import path from 'path'; import { bundle, bundler, + describe, + it, run, overlayFS, fsFixture, getNextBuild, } from '@parcel/test-utils'; -describe('macros', function () { +describe.v2('macros', function () { let count = 0; let dir; beforeEach(async () => { @@ -227,7 +229,7 @@ describe('macros', function () { await fsFixture(overlayFS, dir)` index.js: import { test } from "./macro.js" with { type: "macro" }; - + if (test()) { console.log('bad'); } else { diff --git a/packages/core/integration-tests/test/markdown.js b/packages/core/integration-tests/test/markdown.js index 6e9c2cecf18..34df7c1ef23 100644 --- a/packages/core/integration-tests/test/markdown.js +++ b/packages/core/integration-tests/test/markdown.js @@ -1,6 +1,12 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundleTree, outputFS} from '@parcel/test-utils'; +import { + assertBundleTree, + bundle, + describe, + it, + outputFS, +} from '@parcel/test-utils'; describe.skip('markdown', function () { it('should support bundling Markdown', async function () { diff --git a/packages/core/integration-tests/test/mdx.js b/packages/core/integration-tests/test/mdx.js index 585581d7770..13becb7fc24 100644 --- a/packages/core/integration-tests/test/mdx.js +++ b/packages/core/integration-tests/test/mdx.js @@ -1,8 +1,8 @@ const assert = require('assert'); const path = require('path'); -const {bundle, run} = require('@parcel/test-utils'); +const {bundle, describe, it, run} = require('@parcel/test-utils'); -describe('mdx', function () { +describe.v2('mdx', function () { it('should support bundling MDX', async function () { let b = await bundle(path.join(__dirname, '/integration/mdx/index.mdx')); diff --git a/packages/core/integration-tests/test/metrics-reporter.js b/packages/core/integration-tests/test/metrics-reporter.js index e1115fb514c..78cc602b8c7 100644 --- a/packages/core/integration-tests/test/metrics-reporter.js +++ b/packages/core/integration-tests/test/metrics-reporter.js @@ -2,14 +2,14 @@ import assert from 'assert'; import path from 'path'; -import {bundler, outputFS} from '@parcel/test-utils'; +import {bundler, describe, it, outputFS} from '@parcel/test-utils'; const config = path.join( __dirname, './integration/custom-configs/.parcelrc-build-metrics', ); -describe('Build Metrics Reporter', () => { +describe.v2('Build Metrics Reporter', () => { it('Should dump bundle metrics to parcel-metrics.json', async () => { let b = bundler(path.join(__dirname, '/integration/commonjs/index.js'), { config, diff --git a/packages/core/integration-tests/test/monorepos.js b/packages/core/integration-tests/test/monorepos.js index a8573625afd..f35effafecc 100644 --- a/packages/core/integration-tests/test/monorepos.js +++ b/packages/core/integration-tests/test/monorepos.js @@ -4,7 +4,9 @@ import { bundle, bundler, assertBundles, + describe, inputFS, + it, outputFS, fsFixture, ncp, @@ -16,7 +18,7 @@ import { const distDir = path.join(__dirname, '/integration/monorepo/dist/default'); -describe('monorepos', function () { +describe.v2('monorepos', function () { beforeEach(async () => { await outputFS.rimraf(path.join(__dirname, '/monorepo')); }); diff --git a/packages/core/integration-tests/test/namer.js b/packages/core/integration-tests/test/namer.js index 3baf808b474..d9b0b3155b7 100644 --- a/packages/core/integration-tests/test/namer.js +++ b/packages/core/integration-tests/test/namer.js @@ -1,8 +1,8 @@ import assert from 'assert'; import path from 'path'; -import {bundle, outputFS, distDir} from '@parcel/test-utils'; +import {bundle, describe, it, outputFS, distDir} from '@parcel/test-utils'; -describe('namer', function () { +describe.v2('namer', function () { it('should determine correct entry root when building a directory', async function () { await bundle(path.join(__dirname, 'integration/namer-dir')); diff --git a/packages/core/integration-tests/test/output-formats.js b/packages/core/integration-tests/test/output-formats.js index b86e43255e9..8a25f70d90b 100644 --- a/packages/core/integration-tests/test/output-formats.js +++ b/packages/core/integration-tests/test/output-formats.js @@ -6,6 +6,8 @@ import { assertBundles, assertESMExports, bundle as _bundle, + describe, + it, mergeParcelOptions, outputFS, run, @@ -29,7 +31,7 @@ const bundle = (name, opts = {}) => { ); }; -describe('output formats', function () { +describe.v2('output formats', function () { describe('commonjs', function () { it('should support commonjs output (exports)', async function () { let b = await bundle( diff --git a/packages/core/integration-tests/test/packager.js b/packages/core/integration-tests/test/packager.js index 8768e77c869..279f37c245d 100644 --- a/packages/core/integration-tests/test/packager.js +++ b/packages/core/integration-tests/test/packager.js @@ -3,6 +3,8 @@ import path from 'path'; import nullthrows from 'nullthrows'; import { bundle as _bundle, + describe, + it, mergeParcelOptions, overlayFS, } from '@parcel/test-utils'; @@ -21,7 +23,7 @@ function hasPolyfill(code) { return code.includes(polyfill) && !code.includes(noPolyfill); } -describe('packager', function () { +describe.v2('packager', function () { describe('globalThis polyfill', function () { it('should exclude globalThis polyfill in modern builds', async function () { const entryPoint = path.join( diff --git a/packages/core/integration-tests/test/parcel-link.js b/packages/core/integration-tests/test/parcel-link.js index c348d201a50..6ad3df93454 100644 --- a/packages/core/integration-tests/test/parcel-link.js +++ b/packages/core/integration-tests/test/parcel-link.js @@ -3,7 +3,7 @@ import type {ProgramOptions} from '@parcel/link'; import {createProgram as _createProgram} from '@parcel/link'; -import {overlayFS, fsFixture} from '@parcel/test-utils'; +import {describe, fsFixture, it, overlayFS} from '@parcel/test-utils'; import assert from 'assert'; import path from 'path'; @@ -19,7 +19,7 @@ function createProgram(opts: ProgramOptions) { return cli; } -describe('@parcel/link', () => { +describe.v2('@parcel/link', () => { let _cwd; let _stdout; diff --git a/packages/core/integration-tests/test/parcel-query.js b/packages/core/integration-tests/test/parcel-query.js index 8bccdb92717..3f78611a30d 100644 --- a/packages/core/integration-tests/test/parcel-query.js +++ b/packages/core/integration-tests/test/parcel-query.js @@ -1,10 +1,10 @@ // @flow import assert from 'assert'; import path from 'path'; -import {overlayFS, bundle, fsFixture} from '@parcel/test-utils'; +import {bundle, describe, fsFixture, overlayFS} from '@parcel/test-utils'; import {loadGraphs} from '../../../dev/query/src'; -describe('parcel-query', () => { +describe.v2('parcel-query', () => { it('loadGraphs', async function () { let entries = 'index.js'; let options = { diff --git a/packages/core/integration-tests/test/parcel-v3.js b/packages/core/integration-tests/test/parcel-v3.js index aa42abd6f45..1160ad37276 100644 --- a/packages/core/integration-tests/test/parcel-v3.js +++ b/packages/core/integration-tests/test/parcel-v3.js @@ -1,77 +1,36 @@ // @flow -import assert from 'assert'; import {join} from 'path'; import {ParcelV3, toFileSystemV3} from '@parcel/core'; import {NodePackageManager} from '@parcel/package-manager'; -import {bundle, fsFixture, inputFS, overlayFS, run} from '@parcel/test-utils'; - -describe('parcel-v3', function () { - describe('ParcelV3', () => { - it('builds', async () => { - await fsFixture(overlayFS, __dirname)` - index.js: - console.log('hello world'); - - .parcelrc: - { - "extends": "@parcel/config-default", - "transformers": { - "*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": ["@parcel/transformer-js"] - } +import {describe, fsFixture, inputFS, it, overlayFS} from '@parcel/test-utils'; + +describe('ParcelV3', function () { + it('builds', async () => { + await fsFixture(overlayFS, __dirname)` + index.js: + console.log('hello world'); + + .parcelrc: + { + "extends": "@parcel/config-default", + "transformers": { + "*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": ["@parcel/transformer-js"] } + } - yarn.lock: {} - `; - - let parcel = new ParcelV3({ - corePath: '', - entries: [join(__dirname, 'index.js')], - fs: toFileSystemV3(overlayFS), - nodeWorkers: 1, - packageManager: new NodePackageManager(inputFS, __dirname), - }); + yarn.lock: {} + `; - await parcel.build(); + let parcel = new ParcelV3({ + corePath: '', + entries: [join(__dirname, 'index.js')], + fs: toFileSystemV3(overlayFS), + nodeWorkers: 1, + packageManager: new NodePackageManager(inputFS, __dirname), }); - }); - - describe('using a rust asset graph', () => { - it('builds commonjs', async () => { - await fsFixture(overlayFS, __dirname)` - index.js: - var local = require('./main'); - - module.exports = function () { - return local.a + local.b; - }; - main.js: - exports.a = 1; - exports.b = 2; - - .parcelrc: - { - "extends": "@parcel/config-default", - "transformers": { - "*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": ["@parcel/transformer-js"] - } - } - - yarn.lock: {} - `; - - let b = await bundle(join(__dirname, 'index.js'), { - featureFlags: { - parcelV3: true, - }, - inputFS: overlayFS, - }); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); + await parcel.build(); }); }); diff --git a/packages/core/integration-tests/test/parser.js b/packages/core/integration-tests/test/parser.js index c65019bc6cf..9dbee25e51e 100644 --- a/packages/core/integration-tests/test/parser.js +++ b/packages/core/integration-tests/test/parser.js @@ -1,6 +1,12 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundleTree, inputFS as fs} from '@parcel/test-utils'; +import { + assertBundleTree, + bundle, + describe, + inputFS as fs, + it, +} from '@parcel/test-utils'; describe.skip('parser', function () { it('should support case-insensitive file extension', async function () { diff --git a/packages/core/integration-tests/test/plugin.js b/packages/core/integration-tests/test/plugin.js index dfd4f97f737..5c23c12856b 100644 --- a/packages/core/integration-tests/test/plugin.js +++ b/packages/core/integration-tests/test/plugin.js @@ -8,9 +8,11 @@ import { assertBundles, bundle, bundler, + describe, distDir, findAsset, getNextBuild, + it, outputFS as fs, overlayFS, run, @@ -18,7 +20,7 @@ import { import * as wasmmap from 'wasm-sourcemap'; import {relativePath} from '@parcel/utils'; -describe('plugin', function () { +describe.v2('plugin', function () { it("continue transformer pipeline on type change that doesn't change the pipeline", async function () { await bundle( path.join(__dirname, '/integration/pipeline-type-change/index.ini'), diff --git a/packages/core/integration-tests/test/pnp.js b/packages/core/integration-tests/test/pnp.js index e463785ebbd..10b844857fe 100644 --- a/packages/core/integration-tests/test/pnp.js +++ b/packages/core/integration-tests/test/pnp.js @@ -2,11 +2,18 @@ import assert from 'assert'; import Module from 'module'; import path from 'path'; import fs from 'fs'; -import {bundle, run, assertBundles, inputFS} from '@parcel/test-utils'; +import { + bundle, + describe, + it, + run, + assertBundles, + inputFS, +} from '@parcel/test-utils'; const ZIPFS = `${path.sep}zipfs`; -describe('pnp', function () { +describe.v2('pnp', function () { it('should defer to the pnp resolution when needed', async function () { let dir = path.join(__dirname, 'integration/pnp-require'); diff --git a/packages/core/integration-tests/test/postcss.js b/packages/core/integration-tests/test/postcss.js index 322d34ce89c..361bf63cf62 100644 --- a/packages/core/integration-tests/test/postcss.js +++ b/packages/core/integration-tests/test/postcss.js @@ -3,6 +3,8 @@ import path from 'path'; import { bundle, bundler, + describe, + it, run, assertBundles, distDir, @@ -17,7 +19,7 @@ import { MockPackageInstaller, } from '@parcel/package-manager'; -describe('postcss', () => { +describe.v2('postcss', () => { it('should build successfully with only postcss-modules config', async () => { let b = await bundle( path.join(__dirname, '/integration/postcss-modules-config/index.js'), diff --git a/packages/core/integration-tests/test/posthtml.js b/packages/core/integration-tests/test/posthtml.js index 030b858dfec..595e7737ad4 100644 --- a/packages/core/integration-tests/test/posthtml.js +++ b/packages/core/integration-tests/test/posthtml.js @@ -2,6 +2,8 @@ import assert from 'assert'; import { bundle, assertBundles, + describe, + it, removeDistDirectory, distDir, inputFS, @@ -15,7 +17,7 @@ import { MockPackageInstaller, } from '@parcel/package-manager'; -describe('posthtml', function () { +describe.v2('posthtml', function () { afterEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/proxy.js b/packages/core/integration-tests/test/proxy.js index 8e851074aa5..7121f7c5552 100644 --- a/packages/core/integration-tests/test/proxy.js +++ b/packages/core/integration-tests/test/proxy.js @@ -1,7 +1,7 @@ // @flow strict-local import assert from 'assert'; import path from 'path'; -import {bundler, getNextBuild, inputFS} from '@parcel/test-utils'; +import {bundler, describe, getNextBuild, inputFS, it} from '@parcel/test-utils'; import http from 'http'; import getPort from 'get-port'; @@ -47,7 +47,7 @@ function get(file, port, client = http) { }); } -describe('proxy', function () { +describe.v2('proxy', function () { let subscription; let cwd; let server; diff --git a/packages/core/integration-tests/test/pug.js b/packages/core/integration-tests/test/pug.js index ca54d65ffed..4289c03d5b9 100644 --- a/packages/core/integration-tests/test/pug.js +++ b/packages/core/integration-tests/test/pug.js @@ -1,8 +1,15 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundles, outputFS, distDir} from '@parcel/test-utils'; - -describe('pug', function () { +import { + assertBundles, + bundle, + describe, + it, + outputFS, + distDir, +} from '@parcel/test-utils'; + +describe.v2('pug', function () { it('should support bundling HTML', async function () { const b = await bundle(path.join(__dirname, '/integration/pug/index.pug')); diff --git a/packages/core/integration-tests/test/react-refresh.js b/packages/core/integration-tests/test/react-refresh.js index d00f711c03d..953b11f3c3f 100644 --- a/packages/core/integration-tests/test/react-refresh.js +++ b/packages/core/integration-tests/test/react-refresh.js @@ -5,7 +5,9 @@ import path from 'path'; import { bundle, bundler, + describe, getNextBuild, + it, overlayFS as fs, sleep, run, @@ -28,7 +30,7 @@ try { } if (MessageChannel) { - describe('react-refresh', function () { + describe.v2('react-refresh', function () { describe('synchronous (automatic runtime)', () => { const testDir = path.join( __dirname, diff --git a/packages/core/integration-tests/test/registered-plugins.js b/packages/core/integration-tests/test/registered-plugins.js index e3ba7c91b4b..06f0b499c1e 100644 --- a/packages/core/integration-tests/test/registered-plugins.js +++ b/packages/core/integration-tests/test/registered-plugins.js @@ -1,9 +1,16 @@ // @flow strict-local import assert from 'assert'; import path from 'path'; -import {bundle, run, overlayFS, fsFixture} from '@parcel/test-utils'; +import { + bundle, + describe, + it, + run, + overlayFS, + fsFixture, +} from '@parcel/test-utils'; -describe('plugins with "registered" languages', () => { +describe.v2('plugins with "registered" languages', () => { it('should support plugins with esbuild-register', async () => { const dir = path.join(__dirname, 'esbuild-register-plugin'); overlayFS.mkdirp(dir); @@ -16,16 +23,16 @@ describe('plugins with "registered" languages', () => { } yarn.lock: - + index.js: console.log("Hi, mum!"); - + .parcelrc: { extends: "@parcel/config-default", reporters: ["...", "./reporter-plugin.js"], } - + reporter-plugin.js: require('esbuild-register/dist/node').register(); const plugin = require('./reporter-plugin.ts'); @@ -42,7 +49,7 @@ describe('plugins with "registered" languages', () => { } } }); - + some-string.ts: export const someString = 'something'; `; diff --git a/packages/core/integration-tests/test/reporters.js b/packages/core/integration-tests/test/reporters.js index 30cebe31864..f49d85388ab 100644 --- a/packages/core/integration-tests/test/reporters.js +++ b/packages/core/integration-tests/test/reporters.js @@ -4,9 +4,9 @@ import assert from 'assert'; import {execSync} from 'child_process'; import path from 'path'; -import {bundler} from '@parcel/test-utils'; +import {bundler, describe, it} from '@parcel/test-utils'; -describe('reporters', () => { +describe.v2('reporters', () => { let successfulEntry = path.join( __dirname, 'integration', diff --git a/packages/core/integration-tests/test/resolver.js b/packages/core/integration-tests/test/resolver.js index edfdcb6c5f8..f4215df1cb7 100644 --- a/packages/core/integration-tests/test/resolver.js +++ b/packages/core/integration-tests/test/resolver.js @@ -1,9 +1,17 @@ // @flow strict-local import assert from 'assert'; import path from 'path'; -import {bundle, run, ncp, overlayFS, outputFS} from '@parcel/test-utils'; - -describe('resolver', function () { +import { + bundle, + describe, + it, + run, + ncp, + overlayFS, + outputFS, +} from '@parcel/test-utils'; + +describe.v2('resolver', function () { it('should support resolving tilde in monorepo packages', async function () { let b = await bundle( path.join( diff --git a/packages/core/integration-tests/test/sass.js b/packages/core/integration-tests/test/sass.js index c2879c33052..b34586cb232 100644 --- a/packages/core/integration-tests/test/sass.js +++ b/packages/core/integration-tests/test/sass.js @@ -2,6 +2,8 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, assertBundles, distDir, @@ -10,7 +12,7 @@ import { fsFixture, } from '@parcel/test-utils'; -describe('sass', function () { +describe.v2('sass', function () { it('should support requiring sass files', async function () { let b = await bundle(path.join(__dirname, '/integration/sass/index.js')); diff --git a/packages/core/integration-tests/test/schema-jsonld.js b/packages/core/integration-tests/test/schema-jsonld.js index dd56330d082..9399654bb0c 100644 --- a/packages/core/integration-tests/test/schema-jsonld.js +++ b/packages/core/integration-tests/test/schema-jsonld.js @@ -1,8 +1,15 @@ -import {bundle, assertBundles, distDir, outputFS} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + distDir, + it, + outputFS, +} from '@parcel/test-utils'; import path from 'path'; import assert from 'assert'; -describe('jsonld', function () { +describe.v2('jsonld', function () { it('Should parse a LD+JSON schema and collect dependencies', async function () { let b = await bundle( path.join(__dirname, '/integration/schema-jsonld/index.html'), diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index e6c90afc0c8..7dad4dbbaf3 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -8,10 +8,12 @@ import { assertBundles, bundle as _bundle, bundler as _bundler, + describe, distDir, findAsset, findDependency, getNextBuild, + it, mergeParcelOptions, outputFS, overlayFS, @@ -50,7 +52,7 @@ const bundler = (name, opts = {}) => { ); }; -describe('scope hoisting', function () { +describe.v2('scope hoisting', function () { describe('es6', function () { it('supports default imports and exports of expressions', async function () { let b = await bundle( diff --git a/packages/core/integration-tests/test/server.js b/packages/core/integration-tests/test/server.js index 6b31b534e2f..6b337b81f6c 100644 --- a/packages/core/integration-tests/test/server.js +++ b/packages/core/integration-tests/test/server.js @@ -5,8 +5,10 @@ import path from 'path'; import { assertBundles, bundler, + describe, getNextBuild, inputFS, + it, outputFS, overlayFS, ncp, @@ -23,7 +25,7 @@ const config = path.join( './integration/custom-configs/.parcelrc-dev-server', ); -describe('server', function () { +describe.v2('server', function () { let subscription; afterEach(async () => { diff --git a/packages/core/integration-tests/test/sourcemaps.js b/packages/core/integration-tests/test/sourcemaps.js index bfd97ad29b3..a22caf8b57d 100644 --- a/packages/core/integration-tests/test/sourcemaps.js +++ b/packages/core/integration-tests/test/sourcemaps.js @@ -6,7 +6,9 @@ import SourceMap from '@parcel/source-map'; import type {InitialParcelOptions} from '@parcel/types'; import { bundle as _bundle, + describe, inputFS, + it, outputFS, overlayFS, shallowEqual, @@ -148,7 +150,7 @@ function checkSourceMapping({ ); } -describe('sourcemaps', function () { +describe.v2('sourcemaps', function () { it('Should create a basic browser sourcemap', async function () { let sourceFilename = path.join( __dirname, diff --git a/packages/core/integration-tests/test/stylus.js b/packages/core/integration-tests/test/stylus.js index af1455cb85d..8864ea43036 100644 --- a/packages/core/integration-tests/test/stylus.js +++ b/packages/core/integration-tests/test/stylus.js @@ -2,13 +2,15 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, + it, run, assertBundles, distDir, outputFS, } from '@parcel/test-utils'; -describe('stylus', function () { +describe.v2('stylus', function () { it('should support requiring stylus files', async function () { let b = await bundle(path.join(__dirname, '/integration/stylus/index.js')); diff --git a/packages/core/integration-tests/test/sugarss.js b/packages/core/integration-tests/test/sugarss.js index 141e58931c3..b0b444b1111 100644 --- a/packages/core/integration-tests/test/sugarss.js +++ b/packages/core/integration-tests/test/sugarss.js @@ -1,8 +1,15 @@ import assert from 'assert'; -import {bundle, assertBundles, outputFS, distDir} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + distDir, + it, + outputFS, +} from '@parcel/test-utils'; import path from 'path'; -describe('sugarss', function () { +describe.v2('sugarss', function () { it('should correctly parse SugarSS asset', async function () { let b = await bundle( path.join(__dirname, '/integration/sugarss/index.sss'), diff --git a/packages/core/integration-tests/test/svg-react.js b/packages/core/integration-tests/test/svg-react.js index fa4ffff6495..aa7d43992d4 100644 --- a/packages/core/integration-tests/test/svg-react.js +++ b/packages/core/integration-tests/test/svg-react.js @@ -1,8 +1,8 @@ import assert from 'assert'; -import {bundle, outputFS} from '@parcel/test-utils'; +import {bundle, describe, it, outputFS} from '@parcel/test-utils'; import path from 'path'; -describe('svg-react', function () { +describe.v2('svg-react', function () { it('should support transforming SVGs to react components', async function () { let b = await bundle( path.join(__dirname, '/integration/svg-react/react.js'), diff --git a/packages/core/integration-tests/test/svg.js b/packages/core/integration-tests/test/svg.js index 6eebd2c937f..1ac5911b642 100644 --- a/packages/core/integration-tests/test/svg.js +++ b/packages/core/integration-tests/test/svg.js @@ -1,8 +1,15 @@ import assert from 'assert'; -import {assertBundles, bundle, distDir, outputFS} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + distDir, + it, + outputFS, +} from '@parcel/test-utils'; import path from 'path'; -describe('svg', function () { +describe.v2('svg', function () { it('should support bundling SVG', async () => { let b = await bundle(path.join(__dirname, '/integration/svg/circle.svg')); diff --git a/packages/core/integration-tests/test/symbol-propagation.js b/packages/core/integration-tests/test/symbol-propagation.js index 4a5a60aab1f..cadb8b7558f 100644 --- a/packages/core/integration-tests/test/symbol-propagation.js +++ b/packages/core/integration-tests/test/symbol-propagation.js @@ -1,8 +1,15 @@ import assert from 'assert'; import path from 'path'; -import {bundler, run, overlayFS, fsFixture} from '@parcel/test-utils'; +import { + bundler, + describe, + fsFixture, + it, + overlayFS, + run, +} from '@parcel/test-utils'; -describe('symbol propagation', () => { +describe.v2('symbol propagation', () => { it('should handle removed assets from previous failed builds', async () => { await fsFixture(overlayFS, __dirname)` broken.js: diff --git a/packages/core/integration-tests/test/tailwind-tests.js b/packages/core/integration-tests/test/tailwind-tests.js index 56df2d8f53e..387d2f6a611 100644 --- a/packages/core/integration-tests/test/tailwind-tests.js +++ b/packages/core/integration-tests/test/tailwind-tests.js @@ -1,8 +1,8 @@ import assert from 'assert'; import path from 'path'; -import {bundle, outputFS} from '@parcel/test-utils'; +import {bundle, describe, it, outputFS} from '@parcel/test-utils'; -describe('tailwind', function () { +describe.v2('tailwind', function () { it('should support tailwind from SCSS', async function () { let fixture = path.join(__dirname, '/integration/tailwind-scss'); let b = await bundle(path.join(fixture, 'index.html')); diff --git a/packages/core/integration-tests/test/tracing.js b/packages/core/integration-tests/test/tracing.js index 1c9a9b72493..9db088e6f37 100644 --- a/packages/core/integration-tests/test/tracing.js +++ b/packages/core/integration-tests/test/tracing.js @@ -1,9 +1,9 @@ // @flow strict-local import assert from 'assert'; import path from 'path'; -import {distDir, bundle, outputFS} from '@parcel/test-utils'; +import {bundle, describe, distDir, it, outputFS} from '@parcel/test-utils'; -describe('tracing', function () { +describe.v2('tracing', function () { it('should produce a trace', async function () { await bundle( path.join(__dirname, '/integration/typescript-jsx/index.tsx'), diff --git a/packages/core/integration-tests/test/transpilation.js b/packages/core/integration-tests/test/transpilation.js index a09ffe3906b..2b3b44ec7e6 100644 --- a/packages/core/integration-tests/test/transpilation.js +++ b/packages/core/integration-tests/test/transpilation.js @@ -3,8 +3,10 @@ import assert from 'assert'; import path from 'path'; import { bundle, + describe, distDir, inputFS as fs, + it, outputFS, overlayFS, run, @@ -15,7 +17,7 @@ import nullthrows from 'nullthrows'; const inputDir = path.join(__dirname, '/input'); -describe('transpilation', function () { +describe.v2('transpilation', function () { it('should not transpile if no targets are defined', async function () { await bundle(path.join(__dirname, '/integration/babel-default/index.js'), { defaultTargetOptions: { diff --git a/packages/core/integration-tests/test/ts-types.js b/packages/core/integration-tests/test/ts-types.js index 9d26b4cab47..f2a5cdfdd0a 100644 --- a/packages/core/integration-tests/test/ts-types.js +++ b/packages/core/integration-tests/test/ts-types.js @@ -3,7 +3,9 @@ import path from 'path'; import { assertBundles, bundle, + describe, inputFS, + it, overlayFS, outputFS, ncp, @@ -12,7 +14,7 @@ import { import {md} from '@parcel/diagnostic'; import {normalizeSeparators} from '@parcel/utils'; -describe('typescript types', function () { +describe.v2('typescript types', function () { it('should generate a typescript declaration file', async function () { let b = await bundle( path.join(__dirname, '/integration/ts-types/main/index.ts'), @@ -473,7 +475,7 @@ describe('typescript types', function () { export function foo() { return 'foo' + baz(); } - + ErrorBoundaryContext.ts: import { createContext } from "react"; export type ErrorBoundaryContextType = {}; @@ -482,11 +484,11 @@ describe('typescript types', function () { ErrorBoundary.ts: import { Component, createElement, PropsWithChildren } from "react"; import { ErrorBoundaryContext } from "./ErrorBoundaryContext"; - + export class ErrorBoundary extends Component { render() { const { children } = this.props; - + return createElement( ErrorBoundaryContext.Provider, { diff --git a/packages/core/integration-tests/test/ts-validation.js b/packages/core/integration-tests/test/ts-validation.js index 6c568bd8350..1f748052a4d 100644 --- a/packages/core/integration-tests/test/ts-validation.js +++ b/packages/core/integration-tests/test/ts-validation.js @@ -3,7 +3,9 @@ import path from 'path'; import { bundle, bundler, + describe, getNextBuild, + it, normalizeFilePath, outputFS, overlayFS, @@ -15,7 +17,7 @@ const config = path.join( './integration/custom-configs/.parcelrc-typescript-validation', ); -describe('ts-validator', function () { +describe.v2('ts-validator', function () { let subscription; afterEach(async () => { if (subscription) { diff --git a/packages/core/integration-tests/test/typescript-tsc.js b/packages/core/integration-tests/test/typescript-tsc.js index 69a6e571832..24a424bb323 100644 --- a/packages/core/integration-tests/test/typescript-tsc.js +++ b/packages/core/integration-tests/test/typescript-tsc.js @@ -4,14 +4,16 @@ import path from 'path'; import { assertBundles, bundle, - run, + describe, distDir, + it, outputFS, + run, } from '@parcel/test-utils'; const config = path.join(__dirname, '/integration/typescript-config/.parcelrc'); -describe('typescript tsc', function () { +describe.v2('typescript tsc', function () { it('should support loading tsconfig.json', async () => { let b = await bundle( path.join(__dirname, '/integration/typescript-config/index.ts'), diff --git a/packages/core/integration-tests/test/typescript.js b/packages/core/integration-tests/test/typescript.js index e915afaeb52..389d677b37a 100644 --- a/packages/core/integration-tests/test/typescript.js +++ b/packages/core/integration-tests/test/typescript.js @@ -4,11 +4,13 @@ import path from 'path'; import url from 'url'; import nullthrows from 'nullthrows'; import { - bundle, - run, assertBundles, + bundle, + describe, distDir, + it, outputFS, + run, } from '@parcel/test-utils'; const tscConfig = path.join( @@ -16,7 +18,7 @@ const tscConfig = path.join( '/integration/typescript-config/.parcelrc', ); -describe('typescript', function () { +describe.v2('typescript', function () { // This tests both the SWC transformer implementation of typescript (which // powers typescript by default in Parcel) as well as through the Typescript // tsc transformer. Use a `undefined` config to indicate the default config, and the diff --git a/packages/core/integration-tests/test/vue.js b/packages/core/integration-tests/test/vue.js index 03096229731..32fee9fe8e5 100644 --- a/packages/core/integration-tests/test/vue.js +++ b/packages/core/integration-tests/test/vue.js @@ -1,8 +1,8 @@ import assert from 'assert'; import path from 'path'; -import {bundle, run, outputFS, distDir} from '@parcel/test-utils'; +import {bundle, describe, distDir, it, outputFS, run} from '@parcel/test-utils'; -describe('vue', function () { +describe.v2('vue', function () { it('should produce a basic vue bundle', async function () { let b = await bundle( path.join(__dirname, '/integration/vue-basic/Basic.vue'), diff --git a/packages/core/integration-tests/test/wasm.js b/packages/core/integration-tests/test/wasm.js index e105baa87a3..b59a6917117 100644 --- a/packages/core/integration-tests/test/wasm.js +++ b/packages/core/integration-tests/test/wasm.js @@ -1,6 +1,13 @@ import assert from 'assert'; import path from 'path'; -import {bundle, run, assertBundleTree, deferred} from '@parcel/test-utils'; +import { + assertBundleTree, + bundle, + deferred, + describe, + it, + run, +} from '@parcel/test-utils'; describe.skip('wasm', function () { if (typeof WebAssembly === 'undefined') { diff --git a/packages/core/integration-tests/test/watcher.js b/packages/core/integration-tests/test/watcher.js index 2dccb2f24b8..4cf39947c94 100644 --- a/packages/core/integration-tests/test/watcher.js +++ b/packages/core/integration-tests/test/watcher.js @@ -4,7 +4,9 @@ import path from 'path'; import { assertBundles, bundler, + describe, getNextBuild, + it, run, assertBundleTree, nextBundle, @@ -20,7 +22,7 @@ import {symlinkSync} from 'fs'; const inputDir = path.join(__dirname, '/watcher'); const distDir = path.join(inputDir, 'dist'); -describe('watcher', function () { +describe.v2('watcher', function () { let subscription; afterEach(async () => { if (subscription) { diff --git a/packages/core/integration-tests/test/webextension.js b/packages/core/integration-tests/test/webextension.js index 2e2a681fbfc..1ea805665ba 100644 --- a/packages/core/integration-tests/test/webextension.js +++ b/packages/core/integration-tests/test/webextension.js @@ -1,8 +1,15 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundles, outputFS, distDir} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + distDir, + it, + outputFS, +} from '@parcel/test-utils'; -describe('webextension', function () { +describe.v2('webextension', function () { it('should resolve a full webextension bundle', async function () { let b = await bundle( path.join(__dirname, '/integration/webextension/manifest.json'), diff --git a/packages/core/integration-tests/test/webmanifest.js b/packages/core/integration-tests/test/webmanifest.js index 9c6cc091297..b4f0fc81026 100644 --- a/packages/core/integration-tests/test/webmanifest.js +++ b/packages/core/integration-tests/test/webmanifest.js @@ -1,9 +1,16 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundles, inputFS, outputFS} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + inputFS, + it, + outputFS, +} from '@parcel/test-utils'; import {md} from '@parcel/diagnostic'; -describe('webmanifest', function () { +describe.v2('webmanifest', function () { it('should support .webmanifest', async function () { let b = await bundle( path.join(__dirname, '/integration/webmanifest/index.html'), diff --git a/packages/core/integration-tests/test/workers.js b/packages/core/integration-tests/test/workers.js index 0d4da22704d..ed6e3d32d8f 100644 --- a/packages/core/integration-tests/test/workers.js +++ b/packages/core/integration-tests/test/workers.js @@ -1,16 +1,18 @@ import assert from 'assert'; import path from 'path'; import { + assertBundles, bundle, + describe, + inputFS, + it, + outputFS, + removeDistDirectory, run, runBundle, - assertBundles, - removeDistDirectory, - outputFS, - inputFS, } from '@parcel/test-utils'; -describe('parcel', function () { +describe.v2('parcel', function () { beforeEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/worklets.js b/packages/core/integration-tests/test/worklets.js index 97710cd6879..4c5d9740bd8 100644 --- a/packages/core/integration-tests/test/worklets.js +++ b/packages/core/integration-tests/test/worklets.js @@ -1,14 +1,16 @@ import assert from 'assert'; import path from 'path'; import { + assertBundles, bundle, + describe, + it, + removeDistDirectory, run, runBundle, - assertBundles, - removeDistDirectory, } from '@parcel/test-utils'; -describe('parcel', function () { +describe.v2('parcel', function () { beforeEach(async () => { await removeDistDirectory(); }); diff --git a/packages/core/integration-tests/test/xml.js b/packages/core/integration-tests/test/xml.js index 7bc9af4334f..b5f64fa817e 100644 --- a/packages/core/integration-tests/test/xml.js +++ b/packages/core/integration-tests/test/xml.js @@ -1,8 +1,14 @@ import assert from 'assert'; import path from 'path'; -import {bundle, assertBundles, outputFS} from '@parcel/test-utils'; +import { + assertBundles, + bundle, + describe, + it, + outputFS, +} from '@parcel/test-utils'; -describe('xml', function () { +describe.v2('xml', function () { it('should transform an atom feed', async function () { let b = await bundle(path.join(__dirname, '/integration/xml/atom.xml'), { defaultTargetOptions: { diff --git a/packages/core/test-utils/src/utils.js b/packages/core/test-utils/src/utils.js index eeb69654738..8d91e924901 100644 --- a/packages/core/test-utils/src/utils.js +++ b/packages/core/test-utils/src/utils.js @@ -107,6 +107,8 @@ If you don't know how, check here: https://bit.ly/2UmWsbD ); } +export const isParcelV3 = process.env.PARCEL_V3 === 'true'; + export function getParcelOptions( entries: FilePath | Array, opts?: $Shape, @@ -130,6 +132,9 @@ export function getParcelOptions( node: '8', }, }, + featureFlags: { + parcelV3: isParcelV3, + }, }, opts, ); @@ -203,6 +208,12 @@ export function mergeParcelOptions( // $FlowFixMe ...optsTwo?.defaultTargetOptions, }, + featureFlags: { + // $FlowFixMe + ...optsOne?.featureFlags, + // $FlowFixMe + ...optsTwo?.featureFlags, + }, }; } @@ -1254,3 +1265,110 @@ export function request( ); }); } + +// $FlowFixMe +let origDescribe = globalThis.describe; +let parcelVersion: string | void; +export function describe(...args: mixed[]) { + parcelVersion = undefined; + origDescribe.apply(this, args); +} + +describe.only = function (...args: mixed[]) { + parcelVersion = undefined; + origDescribe.only.apply(this, args); +}; + +describe.skip = function (...args: mixed[]) { + parcelVersion = undefined; + origDescribe.skip.apply(this, args); +}; + +describe.v2 = function (...args: mixed[]) { + parcelVersion = 'v2'; + if (isParcelV3) { + origDescribe.skip.apply(this, args); + } else { + origDescribe.apply(this, args); + } +}; + +describe.v2.only = function (...args: mixed[]) { + parcelVersion = 'v2'; + if (isParcelV3) { + origDescribe.skip.apply(this, args); + } else { + origDescribe.only.apply(this, args); + } +}; + +describe.v3 = function (...args: mixed[]) { + parcelVersion = 'v3'; + if (isParcelV3) { + origDescribe.apply(this, args); + } else { + origDescribe.skip.apply(this, args); + } +}; + +describe.v3.only = function (...args: mixed[]) { + parcelVersion = 'v3'; + if (isParcelV3) { + origDescribe.only.apply(this, args); + } else { + origDescribe.skip.apply(this, args); + } +}; + +let origIt = globalThis.it; +export function it(...args: mixed[]) { + if ( + parcelVersion == null || + (parcelVersion == 'v2' && !isParcelV3) || + (parcelVersion == 'v3' && isParcelV3) + ) { + origIt.apply(this, args); + } else { + origIt.skip.apply(this, args); + } +} + +it.only = function (...args: mixed[]) { + origIt.only.apply(this, args); +}; + +it.skip = function (...args: mixed[]) { + origIt.skip.apply(this, args); +}; + +it.v2 = function (...args: mixed[]) { + if (isParcelV3) { + origIt.skip.apply(this, args); + } else { + origIt.apply(this, args); + } +}; + +it.v2.only = function (...args: mixed[]) { + if (isParcelV3) { + origIt.skip.apply(this, args); + } else { + origIt.only.apply(this, args); + } +}; + +it.v3 = function (...args: mixed[]) { + if (isParcelV3) { + origIt.apply(this, args); + } else { + origIt.skip.apply(this, args); + } +}; + +it.v3.only = function (...args: mixed[]) { + if (isParcelV3) { + origIt.only.apply(this, args); + } else { + origIt.skip.apply(this, args); + } +};