mirror of
https://github.com/facebook/lexical.git
synced 2025-05-17 06:59:17 +08:00
209 lines
6.4 KiB
JavaScript
209 lines
6.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const fs = require('fs-extra');
|
|
const glob = require('glob');
|
|
const {packagesManager} = require('./shared/packagesManager');
|
|
const {PackageMetadata} = require('./shared/PackageMetadata');
|
|
|
|
const monorepoPackageJson = require('./shared/readMonorepoPackageJson')();
|
|
// get version from monorepo package.json version
|
|
const version = monorepoPackageJson.version;
|
|
|
|
const publicNpmNames = new Set(
|
|
packagesManager.getPublicPackages().map((pkg) => pkg.getNpmName()),
|
|
);
|
|
|
|
/**
|
|
* - Set the version to the monorepo ./package.json version
|
|
* - Update dependencies, devDependencies, and peerDependencies
|
|
* - Update the exports map and set other required default fields
|
|
* @param {PackageMetadata} pkg
|
|
*/
|
|
function updatePackage(pkg) {
|
|
pkg.packageJson.version = version;
|
|
updateDependencies(pkg);
|
|
if (!pkg.isPrivate()) {
|
|
updatePublicPackage(pkg);
|
|
}
|
|
pkg.writeSync();
|
|
}
|
|
|
|
/**
|
|
* Update every package.json in the packages/ and examples/ directories
|
|
*
|
|
* - Set the version to the monorepo ./package.json version
|
|
* - Update the versions of monorepo dependencies, devDependencies, and peerDependencies
|
|
* - Update the exports map and set other required default fields
|
|
*
|
|
*/
|
|
function updateVersion() {
|
|
packagesManager.getPackages().forEach(updatePackage);
|
|
glob
|
|
.sync([
|
|
'./examples/*/package.json',
|
|
'./scripts/__tests__/integration/fixtures/*/package.json',
|
|
])
|
|
.forEach((packageJsonPath) =>
|
|
updatePackage(new PackageMetadata(packageJsonPath)),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Replace the extension in a .js or .mjs filename with another extension.
|
|
* Used to convert between the two or to add a prefix before the extension.
|
|
*
|
|
* `ext` may contain $1 to use the original extension in the
|
|
* replacement, e.g. replaceExtension('foo.js', '.bar$1') -> 'foo.bar.js'
|
|
*
|
|
* @param {string} fileName
|
|
* @param {string} ext
|
|
* @returns {string} fileName with ext as the new extension
|
|
*/
|
|
function replaceExtension(fileName, ext) {
|
|
return fileName.replace(/(\.m?js)$/, ext);
|
|
}
|
|
|
|
/**
|
|
* webpack can use these conditions to choose a dev or prod
|
|
* build without a fork module, which is especially helpful
|
|
* in the ESM build.
|
|
*
|
|
* @param {string} fileName may have .js or .mjs extension
|
|
* @returns {Record<'development'|'production', string>}
|
|
*/
|
|
function withEnvironments(fileName) {
|
|
return {
|
|
development: replaceExtension(fileName, '.dev$1'),
|
|
production: replaceExtension(fileName, '.prod$1'),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Build an export map for a particular entry point in the package.json
|
|
*
|
|
* @param {string} basename the name of the entry point module without an extension (e.g. 'index')
|
|
* @returns {Record<'import'|'require', Record<string,string>>} The export map for this file
|
|
*/
|
|
function exportEntry(basename, typesBasename = `${basename}.d.ts`) {
|
|
// Bundlers such as webpack require 'types' to be first and 'default' to be
|
|
// last per #5731. Keys are in descending priority order.
|
|
const prefix = `./${basename}`;
|
|
const types = `./${typesBasename}`;
|
|
return {
|
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
import: {
|
|
types,
|
|
...withEnvironments(`${prefix}.mjs`),
|
|
node: `${prefix}.node.mjs`,
|
|
default: `${prefix}.mjs`,
|
|
},
|
|
require: {
|
|
types,
|
|
...withEnvironments(`${prefix}.js`),
|
|
default: `${prefix}.js`,
|
|
},
|
|
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Update the public package's packageJson in-place to add default configurations
|
|
* for `sideEffects` and `module` as well as to maintain the `exports` map.
|
|
*
|
|
* @param {PackageMetadata} pkg
|
|
*/
|
|
function updatePublicPackage(pkg) {
|
|
const {packageJson} = pkg;
|
|
if (packageJson.sideEffects === undefined) {
|
|
packageJson.sideEffects = false;
|
|
}
|
|
// If there's a main we expect a single entry point
|
|
if (packageJson.main) {
|
|
packageJson.module = replaceExtension(packageJson.main, '.mjs');
|
|
packageJson.exports = {
|
|
'.': exportEntry(
|
|
replaceExtension(packageJson.main, ''),
|
|
packageJson.types,
|
|
),
|
|
};
|
|
} else {
|
|
const exports = {};
|
|
// Export all src/*.tsx? files that do not have a prefix extension (e.g. no .d.ts)
|
|
for (const fn of fs.readdirSync(pkg.resolve('src'))) {
|
|
if (/^[^.]+\.tsx?$/.test(fn)) {
|
|
const basename = fn.replace(/\.tsx?$/, '');
|
|
const entry = exportEntry(basename);
|
|
// support for import "@lexical/react/LexicalComposer"
|
|
exports[`./${basename}`] = entry;
|
|
// support for import "@lexical/react/LexicalComposer.js"
|
|
// @mdxeditor/editor uses this at least as of 2.13.1
|
|
exports[`./${basename}.js`] = entry;
|
|
}
|
|
}
|
|
packageJson.exports = exports;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Replace the dependency map at packageJson[key] in-place with
|
|
* deps sorted lexically by key. If deps was empty, it will be removed.
|
|
*
|
|
* @param {Record<string, any>} packageJson
|
|
* @param {'dependencies'|'peerDependencies'} key
|
|
* @param {Record<string, string>} deps
|
|
*/
|
|
function sortDependencies(packageJson, key, deps) {
|
|
const entries = Object.entries(deps);
|
|
if (entries.length === 0) {
|
|
delete packageJson[key];
|
|
} else {
|
|
packageJson[key] = Object.fromEntries(
|
|
entries.sort((a, b) => a[0].localeCompare(b[0])),
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update dependencies and peerDependencies in pkg in-place.
|
|
* All entries for monorepo packages will be updated to version.
|
|
* All peerDependencies for monorepo packages will be moved to dependencies.
|
|
*
|
|
* @param {PackageMetadata} pkg
|
|
*/
|
|
function updateDependencies(pkg) {
|
|
const {packageJson} = pkg;
|
|
const {
|
|
dependencies = {},
|
|
peerDependencies = {},
|
|
devDependencies = {},
|
|
} = packageJson;
|
|
[dependencies, devDependencies].forEach((deps) => {
|
|
Object.keys(deps).forEach((dep) => {
|
|
if (publicNpmNames.has(dep)) {
|
|
deps[dep] = version;
|
|
}
|
|
});
|
|
});
|
|
// Move peerDependencies on lexical monorepo packages to dependencies
|
|
// per #5783
|
|
Object.keys(peerDependencies).forEach((peerDep) => {
|
|
if (publicNpmNames.has(peerDep)) {
|
|
delete peerDependencies[peerDep];
|
|
dependencies[peerDep] = version;
|
|
}
|
|
});
|
|
sortDependencies(packageJson, 'dependencies', dependencies);
|
|
sortDependencies(packageJson, 'devDependencies', devDependencies);
|
|
sortDependencies(packageJson, 'peerDependencies', peerDependencies);
|
|
}
|
|
|
|
updateVersion();
|