Customizing Changelog
By default, Changesets will use @changesets/cli/changelog
to generate changelog. If the default changelog cannot meet the requirements, you can customize the generation of changelog.
Customizing Changelog Content
Changelog mainly includes the following two types of information:
The custom logic mainly implements two functions, getReleaseLine
and getDependencyReleaseLine
, which are used to define the above two types of information, respectively.
getReleaseLine
Params
export type VersionType = 'major' | 'minor' | 'patch' | 'none';
export type Release = { name: string; type: VersionType };
export type Changeset = {
id: string; // changeset id
commit?: string; // changeset commit id
summary: string; // changeset summary content
releases: Array<Release>; // The name and type information of the current computed changeset upgrade package.
};
The upgraded version type corresponding to the current package, which is of type VersionType
mentioned above.
Returns
Changelog content.
Default Implementation
The default processing logic of @changesets/cli/changelog
is to split the summary
information according to the newline \n
, add -
as the list header before the first line, and organize other content as the supplement of the first line below the list.
async function getReleaseLine(changeset, type) {
const [firstLine, ...futureLines] = changeset.summary
.split('\n')
.map(l => l.trimRight());
let returnVal = `- ${
changeset.commit ? `${changeset.commit}: ` : ''
}${firstLine}`;
if (futureLines.length > 0) {
returnVal += `\n${futureLines.map(l => ` ${l}`).join('\n')}`;
}
return returnVal;
}
getDependencyReleaseLine
Params
All associated changeset information, which is an array of getReleaseLine
changeset types.
type ModCompWithPackage = {
name: string; // Name of the dependent module
type: VersionType; // Upgrade type of the dependent module
oldVersion: string; // Current version of the dependent module
newVersion: string; // New version of the dependent module
changesets: string[]; // List of associated changeset ids
packageJson: PackageJSON; // Complete package.json content of the dependent module
dir: string; // Path (absolute path) of the dependent module
};
type DependenciesUpdated = ModCompWithPackage[];
Returns
Changelog content.
Default Implementation
By default, @changesets/cli/changelog
will display the corresponding Updated dependencies + commit id
information of the changesets as a list. Then, based on the dependenciesUpdated
information, it will display the package name and new version of the corresponding dependency package as a child list item of the list.
async function getDependencyReleaseLine(changesets, dependenciesUpdated) {
console.log('getDependencyReleaseLine', changesets, dependenciesUpdated);
if (dependenciesUpdated.length === 0) return '';
const changesetLinks = changesets.map(
changeset =>
`- Updated dependencies${
changeset.commit ? ` [${changeset.commit}]` : ''
}`,
);
const updatedDepenenciesList = dependenciesUpdated.map(
dependency => ` - ${dependency.name}@${dependency.newVersion}`,
);
return [...changesetLinks, ...updatedDepenenciesList].join('\n');
}
It is displayed as follows:
- Updated dependencies [f0438ab]
- Updated dependencies [f0438ab]
- module-3@2.0.0
- module-1@0.2.0
Configuration
The changelog
field in the changesets configuration file is used to mark the way to get changelog.
This configuration can be a string, directly declaring the module name or path of the changelog module.
This configuration also supports configuring arrays. The first element in the array is the module name or path of the changelog module, and the second element is the parameter value passed to the corresponding function, which will be passed as the third parameter of the getReleaseLine
and getDependencyReleaseLine
functions.
Configuring Relative Paths
If the changelog configuration is a relative path, it is a relative path under the .changesets
directory.
For example, create the .changeset/my-changelog-config.js
file and define the following content:
.changeset/my-changelog-config.js
async function getReleaseLine(changeset, type) {}
async function getDependencyReleaseLine(changesets, dependenciesUpdated) {}
module.exports = {
getReleaseLine,
getDependencyReleaseLine,
};
Configure changlog
as ./my-changelog-config.js
:
.changesets/config.json
{
"changelog": "./my-changelog-config.js",
...
}
Using Modern.js Module
Customizing changelog can also be managed using the Modern.js Module to provide a common solution.
Use npx @modern-js/create@latest
to create a Modern.js Module.
? Please select the type of project you want to create: Npm Module
? Please fill in the project name: custom-changelog
? Please select the programming language: TS
? Please select the package manager: pnpm
Implement Custom Content
src/index.ts
export async function getReleaseLine() {}
export async function getDependencyReleaseLine() {}
Publish the module to NPM
Install the module in the root directory of the target repository, such as custom-changelog
.
Configure the changelog configuration of changesets as the package name.
.changesets/config.json
{
"changelog": "custom-changelog",
...
}
Using Monorepo Sub-Project
If your current repository is Monorepo, you can directly manage it using NPM module sub-projects.
Run pnpm run new
to create a NPM module sub-project
? Please select the type of project you want to create: Npm Module
? Please fill in the sub-project name: custom-changelog
? Please fill in the sub-project directory name: custom-changelog
? Please select the programming language: TS
Implement Custom Content
src/index.ts
export async function getReleaseLine() {}
export async function getDependencyReleaseLine() {}
Add the sub-project module dependency, such as custom-changelog
, to the Monorepo root directory
package.json
{
"devDependencies": {
"custom-changelog": "workspace:*",
...
}
}
Configure the changelog configuration of Changesets as the package name
.changesets/config.json
{
"changelog": "custom-changelog",
...
}
After the module is published to NPM, it can still be used like a module type for other repositories.