diff --git a/test/e2e/tree-shaking-flow/fixture/.fusionrc.js b/test/e2e/tree-shaking-flow/fixture/.fusionrc.js new file mode 100644 index 00000000..dabf00db --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/.fusionrc.js @@ -0,0 +1,3 @@ +module.exports = { + assumeNoImportSideEffects: true +}; diff --git a/test/e2e/tree-shaking-flow/fixture/.gitignore b/test/e2e/tree-shaking-flow/fixture/.gitignore new file mode 100644 index 00000000..59085114 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/.gitignore @@ -0,0 +1,2 @@ +!node_modules +.fusion_babel_cache/ diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js new file mode 100644 index 00000000..919d27d6 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js @@ -0,0 +1,11 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const usedDependencyValue = '__FIXTURE_DEPENDENCY_USED__'; + +const unusedDependencyValue = '__FIXTURE_DEPENDENCY_UNUSED__'; + +exports.usedDependencyValue = usedDependencyValue; +exports.unusedDependencyValue = unusedDependencyValue; +//# sourceMappingURL=index.js.map diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.flow b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.flow new file mode 100644 index 00000000..a1b699a4 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.flow @@ -0,0 +1,3 @@ +// @flow + +export * from "../src/index.js"; diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.map b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.map new file mode 100644 index 00000000..618669b9 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/used.js","../src/unused.js"],"sourcesContent":["// @flow\nexport type UsedDependencyType = {|shouldBeUsed: string|};\nexport type UsedDependencyOtherType = {|alsoShouldBeUsed: string|};\n\nexport const usedDependencyValue = '__FIXTURE_DEPENDENCY_USED__';\n","// @flow\nexport type UnusedDependencyType = {|shouldBeUnused: string|};\nexport type UnusedDependencyOtherType = {|alsoShouldBeUnused: string|};\n\nexport const unusedDependencyValue = '__FIXTURE_DEPENDENCY_UNUSED__';\n"],"names":["usedDependencyValue","unusedDependencyValue"],"mappings":";;;;AAIO,MAAMA,mBAAmB,GAAG,6BAA5B;;ACAA,MAAMC,qBAAqB,GAAG,+BAA9B;;;;;"} diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/package.json b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/package.json new file mode 100644 index 00000000..b52f4cf0 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/package.json @@ -0,0 +1,5 @@ +{ + "name": "fixture-es2017-pkg", + "version": "1.0.0", + "main": "./dist/index.js" +} diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/index.js b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/index.js new file mode 100644 index 00000000..3afcba44 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/index.js @@ -0,0 +1,3 @@ +// @flow +export * from './used.js'; +export * from './unused.js'; diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/unused.js b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/unused.js new file mode 100644 index 00000000..ae104fe7 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/unused.js @@ -0,0 +1,5 @@ +// @flow +export type UnusedDependencyType = {|shouldBeUnused: string|}; +export type UnusedDependencyOtherType = {|alsoShouldBeUnused: string|}; + +export const unusedDependencyValue = '__FIXTURE_DEPENDENCY_UNUSED__'; diff --git a/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/used.js b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/used.js new file mode 100644 index 00000000..22185bc9 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/node_modules/fixture-pkg/src/used.js @@ -0,0 +1,5 @@ +// @flow +export type UsedDependencyType = {|shouldBeUsed: string|}; +export type UsedDependencyOtherType = {|alsoShouldBeUsed: string|}; + +export const usedDependencyValue = '__FIXTURE_DEPENDENCY_USED__'; diff --git a/test/e2e/tree-shaking-flow/fixture/src/main.js b/test/e2e/tree-shaking-flow/fixture/src/main.js new file mode 100644 index 00000000..d2ace9e1 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/src/main.js @@ -0,0 +1,59 @@ +// @flow + +/* Includes type imports from both node_modules and userland but as + * standalone type imports and mixed imports: + * import type {AType, BType} from ... + * import {type AType, type BType, C, D} from ... + */ + +// Import only types from dependency +import type { + UnusedDependencyType, + UsedDependencyType, +} from 'fixture-pkg'; + +// Import mixed types and values from dependency +import { + type UnusedDependencyOtherType, + type UsedDependencyOtherType, + unusedDependencyValue, + usedDependencyValue +} from 'fixture-pkg'; + +// Import only types from userland +import type { + UnusedUserlandType, + UsedUserlandType +} from './user-code.js'; + +// Import mixed types and values from userland +import { + type UnusedUserlandOtherType, + type UsedUserlandOtherType, + unusedUserlandValue, + usedUserlandValue +} from './user-code.js'; + +if (__NODE__) { + // unused in the browser + // - node modules + const unusedDepVal: UnusedDependencyType = { shouldBeUnused: unusedDependencyValue }; + const unusedDepVal2: UnusedDependencyOtherType = { alsoShouldBeUnused: unusedDependencyValue }; + // - userland + const unustedUserlandVal: UnusedUserlandType = { shouldBeUnused: unusedUserlandValue }; + const unustedUserlandVal2: UnusedUserlandOtherType = { alsoShouldBeUnused: unusedUserlandValue }; + + console.log(unusedDepVal, unusedDepVal2, unustedUserlandVal, unustedUserlandVal2); +} + +// used in the browser +// - node modules +const usedDepVal: UsedDependencyType = { shouldBeUsed: usedDependencyValue}; +const usedDepVal2: UsedDependencyOtherType = { alsoShouldBeUsed: usedDependencyValue};; +// - userland +const usedUserlandVal: UsedUserlandType = { shouldBeUsed: usedUserlandValue}; +const usedUserlandVal2: UsedUserlandOtherType = { alsoShouldBeUsed: usedUserlandValue};; + +console.log(usedDepVal, usedDepVal2, usedUserlandVal, usedUserlandVal2); + +export default () => {}; diff --git a/test/e2e/tree-shaking-flow/fixture/src/unused2.js b/test/e2e/tree-shaking-flow/fixture/src/unused2.js new file mode 100644 index 00000000..d51def8c --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/src/unused2.js @@ -0,0 +1,5 @@ +// @flow +export type UnusedUserlandType = {| shouldBeUnused: string |}; +export type UnusedUserlandOtherType = {| alsoShouldBeUnused: string |}; + +export const unusedUserlandValue = '__FIXTURE_USERLAND_UNUSED__'; diff --git a/test/e2e/tree-shaking-flow/fixture/src/used2.js b/test/e2e/tree-shaking-flow/fixture/src/used2.js new file mode 100644 index 00000000..c04bac52 --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/src/used2.js @@ -0,0 +1,5 @@ +// @flow +export type UsedUserlandType = {| shouldBeUsed: string |}; +export type UsedUserlandOtherType = {| alsoShouldBeUsed: string |}; + +export const usedUserlandValue = '__FIXTURE_USERLAND_USED__'; diff --git a/test/e2e/tree-shaking-flow/fixture/src/user-code.js b/test/e2e/tree-shaking-flow/fixture/src/user-code.js new file mode 100644 index 00000000..ad2cf29a --- /dev/null +++ b/test/e2e/tree-shaking-flow/fixture/src/user-code.js @@ -0,0 +1,3 @@ +// @flow +export * from './used2.js'; +export * from './unused2.js'; diff --git a/test/e2e/tree-shaking-flow/test.js b/test/e2e/tree-shaking-flow/test.js new file mode 100644 index 00000000..a14c31e1 --- /dev/null +++ b/test/e2e/tree-shaking-flow/test.js @@ -0,0 +1,43 @@ +// @flow +/* eslint-env node */ + +const t = require('assert'); +const path = require('path'); +const fs = require('fs'); +const {promisify} = require('util'); + +const readdir = promisify(fs.readdir); + +const dir = path.resolve(__dirname, './fixture'); + +const {cmd} = require('../utils.js'); + +test('`fusion build` strips unused types in dev and correctly tree shakes remaining imports w/ assumeNoImportSideEffects: true', async () => { + await cmd(`build --dir=${dir}`); + + const distFolder = path.resolve(dir, '.fusion/dist/development/client'); + const clientFiles = await readdir(distFolder); + + clientFiles + .filter(file => path.extname(file) === '.js') + .map(file => path.join(distFolder, file)) + .forEach(file => { + const unusedChecks = [ + // userland + 'UnusedUserlandType', + 'UnusedUserlandOtherType', + '__FIXTURE_USERLAND_UNUSED__', + // node modules + 'UnusedDependencyType', + 'UnusedDependencyOtherType', + '__FIXTURE_DEPENDENCY_UNUSED__', + ]; + + unusedChecks.forEach(name => { + t.ok( + !fs.readFileSync(file, 'utf-8').includes(name), + `should not include unused export in browser: ${name}` + ); + }); + }); +}, 100000);