Skip to content

Commit

Permalink
feat(tools): use package.json main and module paths as source of trut…
Browse files Browse the repository at this point in the history
…h for export maps
  • Loading branch information
Hotell committed Oct 20, 2022
1 parent 4c695f9 commit e81e50d
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 116 deletions.
154 changes: 99 additions & 55 deletions tools/generators/migrate-converged-pkg/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,73 +941,116 @@ describe('migrate-converged-pkg generator', () => {
});
});

it(`should update exports map`, async () => {
const projectConfig = readProjectConfiguration(tree, options.name);
const pkgJsonPath = `${projectConfig.root}/package.json`;
describe(`export-maps`, () => {
function setup(config: { name: string; createUnstable?: boolean; addModuleField?: boolean }) {
const addModuleField = config.addModuleField ?? true;
const projectConfig = readProjectConfiguration(tree, config.name);
const pkgJsonPath = `${projectConfig.root}/package.json`;
const pkgJsonUnstablePath = `${projectConfig.root}/src/unstable/package.json__tmpl__`;

let getUnstablePackageJson = (): null | object => {
return null;
};

if (addModuleField) {
updateJson(tree, pkgJsonPath, json => {
json.module = './lib/index.js';
return json;
});
}

let pkgJson = readJson(tree, pkgJsonPath);
if (config.createUnstable) {
writeJson(tree, pkgJsonUnstablePath, {
typings: './../dist/unstable.d.ts',
...(addModuleField ? { module: './../lib/index.js' } : null),
});
getUnstablePackageJson = () => readJson(tree, pkgJsonUnstablePath);
}

expect(pkgJson.exports).toBe(undefined);
const getPackageJson = () => readJson(tree, pkgJsonPath);

await generator(tree, options);
return { pkgJsonPath, pkgJsonUnstablePath, getPackageJson, getUnstablePackageJson };
}

pkgJson = readJson(tree, pkgJsonPath);
it(`should update exports map`, async () => {
const { getPackageJson } = setup({ name: options.name });

expect(pkgJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
}
`);
});
let pkgJson = getPackageJson();

it(`should update exports map if unstable API is present`, async () => {
const projectConfig = readProjectConfiguration(tree, options.name);
const pkgJsonPath = `${projectConfig.root}/package.json`;
const pkgJsonUnstablePath = `${projectConfig.root}/src/unstable/package.json__tmpl__`;
writeJson(tree, pkgJsonUnstablePath, {
typings: './../dist/unstable.d.ts',
expect(pkgJson.exports).toBe(undefined);

await generator(tree, options);

pkgJson = getPackageJson();

expect(pkgJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
}
`);
});

let pkgJson = readJson(tree, pkgJsonPath);
let pkgUnstableJson = readJson(tree, pkgJsonUnstablePath);
it(`should update exports map based on main,module fields`, async () => {
const { getPackageJson } = setup({ name: options.name, addModuleField: false });

expect(pkgJson.exports).toBe(undefined);
expect(pkgUnstableJson.exports).toBe(undefined);
await generator(tree, options);

await generator(tree, options);
const pkgJson = getPackageJson();
expect(pkgJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"require": "./lib-commonjs/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
}
`);
});

pkgJson = readJson(tree, pkgJsonPath);
pkgUnstableJson = readJson(tree, pkgJsonUnstablePath);
it(`should update exports map if unstable API is present`, async () => {
const { getPackageJson, getUnstablePackageJson } = setup({ name: options.name, createUnstable: true });

expect(pkgJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
"./unstable": Object {
"import": "./lib/unstable/index.js",
"require": "./lib-commonjs/unstable/index.js",
"types": "./dist/unstable.d.ts",
},
}
`);
expect(pkgUnstableJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./../lib/unstable/index.js",
"require": "./../lib-commonjs/unstable/index.js",
"types": "./../dist/unstable.d.ts",
},
}
`);
let pkgJson = getPackageJson();
let pkgUnstableJson = getUnstablePackageJson() as Record<string, string>;

expect(pkgJson.exports).toBe(undefined);
expect(pkgUnstableJson.exports).toBe(undefined);

await generator(tree, options);

pkgJson = getPackageJson();
pkgUnstableJson = getUnstablePackageJson() as Record<string, string>;

expect(pkgJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
"./unstable": Object {
"import": "./lib/unstable/index.js",
"require": "./lib-commonjs/unstable/index.js",
"types": "./dist/unstable.d.ts",
},
}
`);
expect(pkgUnstableJson.exports).toMatchInlineSnapshot(`
Object {
".": Object {
"import": "./../lib/unstable/index.js",
"require": "./../lib-commonjs/unstable/index.js",
"types": "./../dist/unstable.d.ts",
},
}
`);
});
});

it(`should not add start scripts to node packages`, async () => {
Expand Down Expand Up @@ -1457,6 +1500,7 @@ function setupDummyPackage(
name: pkgName,
version: normalizedOptions.version,
typings: 'lib/index.d.ts',
main: 'lib-commonjs/index.js',
scripts: {
build: 'just-scripts build',
clean: 'just-scripts clean',
Expand Down
140 changes: 79 additions & 61 deletions tools/generators/migrate-converged-pkg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,83 +554,101 @@ interface NormalizedSchemaWithTsConfigs extends NormalizedSchema {
}

function updatePackageJson(tree: Tree, options: NormalizedSchemaWithTsConfigs) {
const scripts = {
'generate-api': 'tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor',
test: 'jest --passWithNoTests',
'type-check': 'tsc -b tsconfig.json',
};
updateJson(tree, options.paths.packageJson, (json: PackageJson) => {
json.typings = './dist/index.d.ts';
return json;
});

const unstableApiDefinitions = processUnstableApiDefinitions();
setupScripts();
setupExportMaps();

if (unstableApiDefinitions) {
updateJson(tree, unstableApiDefinitions.unstablePackageJsonPath, (json: PackageJson) => {
json.exports = unstableApiDefinitions.unstableExportMap;
return json;
});
}
return tree;

updateJson(tree, options.paths.packageJson, (json: PackageJson) => {
json.typings = './dist/index.d.ts';
json.exports = {
'.': {
types: json.typings,
import: './lib/index.js',
require: './lib-commonjs/index.js',
},
...(unstableApiDefinitions ? unstableApiDefinitions.rootExportMap : null),
'./package.json': './package.json',
function setupScripts() {
const scripts = {
'generate-api': 'tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor',
test: 'jest --passWithNoTests',
'type-check': 'tsc -b tsconfig.json',
};

json.scripts = json.scripts || {};
delete json.scripts['update-snapshots'];
delete json.scripts['start-test'];
delete json.scripts['test:watch'];
delete json.scripts['build:local'];
delete json.scripts.docs;
updateJson(tree, options.paths.packageJson, (json: PackageJson) => {
json.scripts = json.scripts || {};
delete json.scripts['update-snapshots'];
delete json.scripts['start-test'];
delete json.scripts['test:watch'];
delete json.scripts['build:local'];
delete json.scripts.docs;

Object.assign(json.scripts, scripts);
Object.assign(json.scripts, scripts);

if (getPackageType(tree, options) === 'node') {
delete json.scripts.start;
delete json.scripts.storybook;
}
if (getPackageType(tree, options) === 'node') {
delete json.scripts.start;
delete json.scripts.storybook;
}

return json;
});
return json;
});
}

return tree;
function setupExportMaps() {
const unstableApiDefinitions = processUnstableApiDefinitions();

function processUnstableApiDefinitions() {
const unstablePackageJsonPath = joinPathFragments(options.paths.unstable.rootPackageJson);
const hasUnstableApi = tree.exists(unstablePackageJsonPath);
if (unstableApiDefinitions) {
updateJson(tree, unstableApiDefinitions.unstablePackageJsonPath, (json: PackageJson) => {
json.exports = unstableApiDefinitions.unstableExportMap;
return json;
});
}

if (!hasUnstableApi) {
return;
updateJson(tree, options.paths.packageJson, (json: PackageJson) => {
json.typings = './dist/index.d.ts';
json.exports = {
'.': {
types: json.typings,
...(json.module ? { import: normalizePackageEntryPointPaths(json.module) } : null),
...(json.main ? { require: normalizePackageEntryPointPaths(json.main) } : null),
},
...(unstableApiDefinitions ? unstableApiDefinitions.rootExportMap : null),
'./package.json': './package.json',
};
return json;
});

function normalizePackageEntryPointPaths(entryPath: string) {
return './' + path.normalize(entryPath);
}
function processUnstableApiDefinitions() {
const unstablePackageJsonPath = joinPathFragments(options.paths.unstable.rootPackageJson);
const hasUnstableApi = tree.exists(unstablePackageJsonPath);

const unstablePackageJson = readJson<PackageJson>(tree, unstablePackageJsonPath);
const typePaths = {
rootExports: unstablePackageJson.typings?.replace(/\.\.\//g, ''),
unstableExports: unstablePackageJson.typings,
};
if (!hasUnstableApi) {
return;
}

return {
unstablePackageJsonPath,
rootExportMap: {
'./unstable': {
types: typePaths.rootExports,
import: './lib/unstable/index.js',
require: './lib-commonjs/unstable/index.js',
const unstablePackageJson = readJson<PackageJson>(tree, unstablePackageJsonPath);
const typePaths = {
rootExports: unstablePackageJson.typings?.replace(/\.\.\//g, ''),
unstableExports: unstablePackageJson.typings,
};

return {
unstablePackageJsonPath,
rootExportMap: {
'./unstable': {
types: typePaths.rootExports,
import: './lib/unstable/index.js',
require: './lib-commonjs/unstable/index.js',
},
},
},
unstableExportMap: {
'.': {
types: typePaths.unstableExports,
import: './../lib/unstable/index.js',
require: './../lib-commonjs/unstable/index.js',
unstableExportMap: {
'.': {
types: typePaths.unstableExports,
import: './../lib/unstable/index.js',
require: './../lib-commonjs/unstable/index.js',
},
},
},
};
};
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions tools/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export interface PackageJson {
typings?: string;
private?: boolean;
name: string;
main: string;
module?: string;
version: string;
scripts?: Record<string, string>;
dependencies?: Record<string, string>;
Expand Down

0 comments on commit e81e50d

Please sign in to comment.