Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tools): bootstrap migrate-converged-pkg generator phase 1 #18343

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions tools/generators/migrate-converged-pkg/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import {
Tree,
readProjectConfiguration,
readJson,
stripIndents,
addProjectConfiguration,
readWorkspaceConfiguration,
} from '@nrwl/devkit';

import generator from './index';
import { MigrateConvergedPkgGeneratorSchema } from './schema';

describe('migrate-converged-pkg generator', () => {
let tree: Tree;
const options: MigrateConvergedPkgGeneratorSchema = { name: '@proj/react-dummy' };

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
tree = setupDummyPackage(tree, options);
});

it('should update local tsconfig.json', async () => {
const projectConfig = readProjectConfiguration(tree, options.name);
function getTsConfig() {
return readJson(tree, `${projectConfig.root}/tsconfig.json`);
}
let tsConfig = getTsConfig();

expect(tsConfig).toMatchInlineSnapshot(`
Object {
"compilerOptions": Object {
"baseUrl": ".",
"typeRoots": Array [
"../../node_modules/@types",
"../../typings",
],
},
}
`);

await generator(tree, options);

tsConfig = getTsConfig();

expect(tsConfig).toMatchInlineSnapshot(`
Object {
"compilerOptions": Object {
"declaration": true,
"experimentalDecorators": true,
"importHelpers": true,
"jsx": "react",
"lib": Array [
"es5",
"dom",
],
"module": "commonjs",
"noUnusedLocals": true,
"outDir": "dist",
"preserveConstEnums": true,
"target": "es5",
"types": Array [
"jest",
"custom-global",
"inline-style-expand-shorthand",
],
},
"extends": "../../tsconfig.base.json",
"include": Array [
"src",
],
}
`);
});

it('should update root tsconfig.base.json', async () => {
function getBaseTsConfig() {
return readJson(tree, `/tsconfig.base.json`);
}

let rootTsConfig = getBaseTsConfig();

expect(rootTsConfig).toMatchInlineSnapshot(`
Object {
"compilerOptions": Object {
"paths": Object {},
},
}
`);

await generator(tree, options);

rootTsConfig = getBaseTsConfig();

expect(rootTsConfig).toMatchInlineSnapshot(`
Object {
"compilerOptions": Object {
"paths": Object {
"@proj/react-dummy": Array [
"packages/react-dummy/src/index.ts",
],
},
},
}
`);
});
});

// ==== helpers ====

function serializeJson(value: unknown) {
return JSON.stringify(value, null, 2);
}

function setupDummyPackage(tree: Tree, options: MigrateConvergedPkgGeneratorSchema) {
const workspaceConfig = readWorkspaceConfiguration(tree);
const pkgName = options.name;
const paths = {
root: `packages/${options.name.replace(`@${workspaceConfig.npmScope}/`, '')}`,
};

const dummyPackageJson = {
name: pkgName,
scripts: {
build: 'just-scripts build',
clean: 'just-scripts clean',
'code-style': 'just-scripts code-style',
just: 'just-scripts',
lint: 'just-scripts lint',
start: 'just-scripts dev:storybook',
'start-test': 'just-scripts jest-watch',
test: 'just-scripts test',
'update-snapshots': 'just-scripts jest -u',
},
};

const dummyTsConfig = {
compilerOptions: {
baseUrl: '.',
typeRoots: ['../../node_modules/@types', '../../typings'],
},
};

const dummyJestConfig = stripIndents`
const { createConfig } = require('@fluentui/scripts/jest/jest-resources');
const path = require('path');

const config = createConfig({
setupFiles: [path.resolve(path.join(__dirname, 'config', 'tests.js'))],
snapshotSerializers: ['@fluentui/jest-serializer-make-styles'],
});

module.exports = config;
`;

tree.write(`${paths.root}/package.json`, serializeJson(dummyPackageJson));
tree.write(`${paths.root}/tsconfig.json`, serializeJson(dummyTsConfig));
tree.write(`${paths.root}/jest.config.js`, dummyJestConfig);

addProjectConfiguration(tree, pkgName, {
root: paths.root,
projectType: 'library',
targets: {},
});

return tree;
}
94 changes: 94 additions & 0 deletions tools/generators/migrate-converged-pkg/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
Tree,
formatFiles,
updateJson,
readProjectConfiguration,
readWorkspaceConfiguration,
joinPathFragments,
} from '@nrwl/devkit';

import { MigrateConvergedPkgGeneratorSchema } from './schema';

/**
* TASK:
* 1. migrate to typescript path aliases - #18343 ✅ (partially done)
* 2. migrate to use standard jest powered by TS path aliases
* 3. setup docs task to run api-extractor for local changes verification
* 4. bootstrap new storybook config
* 5. collocate all package stories from `react-examples`
*/

interface NormalizedSchema extends ReturnType<typeof normalizeOptions> {}

export default async function (tree: Tree, schema: MigrateConvergedPkgGeneratorSchema) {
const options = normalizeOptions(tree, schema);

// 1. update TsConfigs
updatedLocalTsConfig(tree, options);
updatedBaseTsConfig(tree, options);

formatFiles(tree);
}

// ==== helpers ====

const templates = {
tsconfig: {
extends: '../../tsconfig.base.json',
compilerOptions: {
target: 'es5',
lib: ['es5', 'dom'],
outDir: 'dist',
jsx: 'react',
declaration: true,
module: 'commonjs',
experimentalDecorators: true,
importHelpers: true,
noUnusedLocals: true,
preserveConstEnums: true,
types: ['jest', 'custom-global', 'inline-style-expand-shorthand'],
},
include: ['src'],
},
jest: {},
};

function normalizeOptions(host: Tree, options: MigrateConvergedPkgGeneratorSchema) {
const defaults = {};
const workspaceConfig = readWorkspaceConfiguration(host);
const projectConfig = readProjectConfiguration(host, options.name);

return {
...defaults,
...options,
projectConfig,
workspaceConfig: workspaceConfig,
paths: {
packageJson: joinPathFragments(projectConfig.root, 'package.json'),
tsconfig: joinPathFragments(projectConfig.root, 'tsconfig.json'),
jestConfig: joinPathFragments(projectConfig.root, 'jest.config.js'),
rootTsconfig: '/tsconfig.base.json',
rootJestPreset: '/jest.preset.js',
rootJestConfig: '/jest.config.js',
},
};
}

function serializeJson(value: unknown) {
return JSON.stringify(value, null, 2);
}

function updatedLocalTsConfig(tree: Tree, options: NormalizedSchema) {
tree.write(options.paths.tsconfig, serializeJson(templates.tsconfig));

return tree;
}

function updatedBaseTsConfig(tree: Tree, options: NormalizedSchema) {
// @TODO: add missing dependencies from migrated package to path aliases
updateJson(tree, options.paths.rootTsconfig, json => {
json.compilerOptions.paths[options.name] = [`${options.projectConfig.root}/src/index.ts`];

return json;
});
}
17 changes: 17 additions & 0 deletions tools/generators/migrate-converged-pkg/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"id": "migrate-converged-pkg",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Library name",
"$default": {
"$source": "argv",
"index": 0
}
}
},
"required": ["name"]
}
6 changes: 6 additions & 0 deletions tools/generators/migrate-converged-pkg/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface MigrateConvergedPkgGeneratorSchema {
/**
* Library name
*/
name: string;
}