Skip to content

Commit

Permalink
starting to implement yarn 2 plug-n-play compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
cspotcode committed Dec 6, 2020
1 parent 462af2d commit 5a967d2
Show file tree
Hide file tree
Showing 8 changed files with 554 additions and 368 deletions.
24 changes: 22 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ jobs:
run: yarn deduplicate:check

test:
name: Test on Node ${{ matrix.node }} and ${{ matrix.os }}
name: Test on Node ${{ matrix.node }} and ${{ matrix.os }}, yarn2?:${{ matrix.should_use_yarn2 }}

runs-on: ${{ matrix.os }}
strategy:
matrix:
node: ['10.x', '12.x', '14.x']
os: [ubuntu-latest, windows-latest, macOS-latest]
should_use_yarn2: [false]
include:
- node: '10.x'
os: ubuntu-latest
should_use_yarn2: true

steps:
- name: Checkout repo
Expand All @@ -47,5 +52,20 @@ jobs:
- name: Install deps and build (with cache)
uses: bahmutov/npm-install@v1

- name: Restore yarn2 cache
if: ${{ matrix.should_use_yarn2 }}
uses: actions/cache@v2
with:
path: |
test/yarn2/.yarn/cache
test/yarn2/yarn.lock
key: cache-key

- name: Setup for yarn2
if: ${{ matrix.should_use_yarn2 }}
run: |
echo 'yarnPath: .yarn/releases/yarn-sources.cjs' >> .yarnrc.yml && yarn && yarn node ./test/utils/prepare-for-yarn2.js && yarn && yarn --version
- name: Test package
run: yarn test:post-build
run: |
yarn --version && yarn node -p 'process.versions.pnp' && yarn test:post-build
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ tester-react
package-lock.json
# Local Netlify folder
.netlify

# Files created when running tests under yarn2
/.yarn
!/.yarn/releases
/.yarnrc.yml
/.pnp.js

55 changes: 55 additions & 0 deletions .yarn/releases/yarn-sources.cjs

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"babel-plugin-transform-rename-import": "^2.3.0",
"camelcase": "^6.0.0",
"chalk": "^4.0.0",
"create-require": "^1.0.2",
"enquirer": "^2.3.4",
"eslint": "^6.1.0",
"eslint-config-prettier": "^6.0.0",
Expand All @@ -77,7 +78,7 @@
"eslint-plugin-react-hooks": "^2.2.0",
"execa": "^4.0.3",
"fs-extra": "^9.0.0",
"jest": "^25.3.0",
"jest": "^25.4.0",
"jest-watch-typeahead": "^0.5.0",
"jpjs": "^1.2.1",
"lodash.merge": "^4.6.2",
Expand All @@ -94,11 +95,12 @@
"semver": "^7.1.1",
"shelljs": "^0.8.3",
"tiny-glob": "^0.2.6",
"ts-jest": "^25.3.1",
"ts-jest": "^25.5.1",
"tslib": "^1.9.3",
"typescript": "^3.7.3"
"typescript": "3.7.3"
},
"devDependencies": {
"@jest/types": "^25.4.0",
"@types/eslint": "^6.1.2",
"@types/fs-extra": "^9.0.1",
"@types/lodash": "^4.14.161",
Expand All @@ -114,6 +116,7 @@
"cssnano": "^4.1.10",
"doctoc": "^1.4.0",
"husky": "^4.2.2",
"lodash": "^4.17.20",
"np": "^6.4.0",
"pretty-quick": "^2.0.0",
"react": "^16.8.6",
Expand All @@ -123,6 +126,7 @@
"styled-components": "^5.0.1",
"tiny-invariant": "^1.1.0",
"tiny-warning": "^1.0.3",
"type-fest": "^0.13.1",
"yarn-deduplicate": "^2.1.1"
},
"husky": {
Expand Down
26 changes: 25 additions & 1 deletion src/createJestConfig.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
import { Config } from '@jest/types';
import path from 'path';
import createRequire from 'create-require';

export type JestConfigOptions = Partial<Config.InitialOptions>;

export function createJestConfig(
_: (relativePath: string) => void,
rootDir: string
): JestConfigOptions {
function resolveRelativeTo(file: string, moduleSpecifier: string) {
const req = createRequire(file);
try {
return req.resolve(moduleSpecifier);
} catch {
return null;
}
}
function resolveBabelJest() {
const jestLocation =
resolveRelativeTo(path.join(rootDir, 'file.js'), 'jest') ||
require.resolve('jest');
const jestCoreLocation = resolveRelativeTo(jestLocation, '@jest/core')!;
const jestConfigLocation = resolveRelativeTo(
jestCoreLocation,
'jest-config'
)!;
return (
resolveRelativeTo(path.join(rootDir, 'file.js'), 'babel-jest') ||
resolveRelativeTo(jestConfigLocation, 'babel-jest')!
);
}
const config: JestConfigOptions = {
transform: {
'.(ts|tsx)$': require.resolve('ts-jest/dist'),
'.(js|jsx)$': require.resolve('babel-jest'), // jest's default
'.(js|jsx)$': resolveBabelJest(), // jest's default
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
Expand Down
16 changes: 11 additions & 5 deletions test/utils/fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ export const rootDir = process.cwd();

shell.config.silent = true;

export function isYarn2() {
return !!process.versions.pnp;
}

export function setupStageWithFixture(
testDir: string,
stageName: string,
Expand All @@ -15,11 +19,13 @@ export function setupStageWithFixture(
shell.exec(
`cp -a ${rootDir}/test/${testDir}/fixtures/${fixtureName}/. ${stagePath}/`
);
shell.ln(
'-s',
path.join(rootDir, 'node_modules'),
path.join(stagePath, 'node_modules')
);
if (!isYarn2()) {
shell.ln(
'-s',
path.join(rootDir, 'node_modules'),
path.join(stagePath, 'node_modules')
);
}
shell.cd(stagePath);
}

Expand Down
37 changes: 37 additions & 0 deletions test/utils/prepare-for-yarn2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* yarn 2 requires each package.json to declare the dependencies used by files within its subdirectory.
* tsdx tests are written to use the exact same set of dependencies as the root package.json.
*
* Before running tests under yarn2 PnP, we copy all dependencies and devDependencies from the root
* to each sub-package.json. We also declare these subdirectories as workspaces so `yarn`
* recognizes and resolves them all.
*/

const fs = require('fs-extra');
const shell = require('shelljs');

shell.cd(__dirname);
shell.cd('../..');
const rootPkg = fs.readJSONSync('package.json');
// Declare all stages as workspaces so that a single `yarn` invocation resolves them all.
rootPkg.workspaces = {
workspaces: ['test/e2e/fixtures/*', 'test/integration/fixtures/*', 'stage-*'],
};
fs.writeJSONSync('package.json', rootPkg, { spaces: 2 });

// Copy all root dependencies onto each test package.json
for (const pkgPath of [
shell.ls('test/e2e/fixtures/*/package.json'),
shell.ls('test/integration/fixtures/*/package.json'),
]
.join(',')
.split(',')) {
const pkg = fs.readJSONSync(`./${pkgPath}`);
pkg.dependencies = Object.assign({}, pkg.dependencies, rootPkg.dependencies);
pkg.devDependencies = Object.assign(
{},
pkg.devDependencies,
rootPkg.devDependencies
);
fs.writeJSONSync(pkgPath, pkg, { spaces: 2 });
}
Loading

0 comments on commit 5a967d2

Please sign in to comment.