Skip to content

Improves boot time #4261

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

Merged
merged 15 commits into from
Mar 26, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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
48 changes: 4 additions & 44 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ describe(`Commands`, () => {
const content = await xfs.readFilePromise(`${path}/yarn.lock` as PortablePath, `utf8`);
const lock = parseSyml(content);

await expect(lock).toMatchObject({
expect(lock).toMatchObject({
[`inject-node-gyp@npm:^1.0.0`]: {
dependencies: {
[`node-gyp`]: `latest`,
Expand Down
11 changes: 4 additions & 7 deletions packages/plugin-compat/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ import {Hooks as CoreHooks, Plugin, structUtils} from '@yarnpkg/core';
import {Hooks as PatchHooks} from '@yarnpkg/plugin-patch';

import {packageExtensions} from './extensions';
import {getPatch as getFseventsPatch} from './patches/fsevents.patch';
import {getPatch as getResolvePatch} from './patches/resolve.patch';
import {getPatch as getTypescriptPatch} from './patches/typescript.patch';

const PATCHES = new Map([
[structUtils.makeIdent(null, `fsevents`).identHash, getFseventsPatch],
[structUtils.makeIdent(null, `resolve`).identHash, getResolvePatch],
[structUtils.makeIdent(null, `typescript`).identHash, getTypescriptPatch],
[structUtils.makeIdent(null, `fsevents`).identHash, () => import(`./patches/fsevents.patch`)],
[structUtils.makeIdent(null, `resolve`).identHash, () => import(`./patches/resolve.patch`)],
[structUtils.makeIdent(null, `typescript`).identHash, () => import(`./patches/typescript.patch`)],
]);

const plugin: Plugin<CoreHooks & PatchHooks> = {
Expand All @@ -26,7 +23,7 @@ const plugin: Plugin<CoreHooks & PatchHooks> = {
return undefined;

const ident = structUtils.parseIdent(name.slice(TAG.length));
const patch = PATCHES.get(ident.identHash)?.();
const patch = (await PATCHES.get(ident.identHash)?.())?.getPatch();

return typeof patch !== `undefined` ? patch : null;
},
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin-nm/sources/PnpLooseLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {VirtualFS, ZipOpenFS, ppath, Filename} from '@yarnpkg/fslib';
import {getLibzipPromise} from '@yarnpkg/libzip';
import {NodeModulesPackageNode, buildNodeModulesTree} from '@yarnpkg/nm';
import {PnpInstaller, PnpLinker} from '@yarnpkg/plugin-pnp';
import {PnpSettings, makeRuntimeApi, DependencyTarget} from '@yarnpkg/pnp';
import {PnpSettings, DependencyTarget} from '@yarnpkg/pnp';

export class PnpLooseLinker extends PnpLinker {
protected mode = `loose`;
Expand All @@ -25,7 +25,9 @@ class PnpLooseInstaller extends PnpInstaller {
}),
});

const {makeRuntimeApi} = await import(`@yarnpkg/pnp`);
const pnp = makeRuntimeApi(pnpSettings, this.opts.project.cwd, defaultFsLayer);

const {tree, errors} = buildNodeModulesTree(pnp, {pnpifyFs: false, project: this.opts.project});
if (!tree) {
for (const {messageName, text} of errors)
Expand Down
8 changes: 7 additions & 1 deletion packages/plugin-pnp/sources/PnpLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {miscUtils, structUtils, formatUtils, Descriptor, LocatorHash, InstallPac
import {FetchResult, Locator, Package} from '@yarnpkg/core';
import {Linker, LinkOptions, MinimalLinkOptions, Manifest, MessageName, DependencyMeta, LinkType, Installer} from '@yarnpkg/core';
import {AliasFS, CwdFS, PortablePath, VirtualFS, npath, ppath, xfs, Filename} from '@yarnpkg/fslib';
import {generateInlinedScript, generateSplitScript, PackageRegistry, PnpApi, PnpSettings, getESMLoaderTemplate} from '@yarnpkg/pnp';
import {PackageRegistry, PnpApi, PnpSettings} from '@yarnpkg/pnp';
import {UsageError} from 'clipanion';

import {getPnpPath} from './index';
Expand Down Expand Up @@ -337,6 +337,12 @@ export class PnpInstaller implements Installer {

await this.transformPnpSettings(pnpSettings);

const {
generateInlinedScript,
generateSplitScript,
getESMLoaderTemplate
} = await import('@yarnpkg/pnp');

if (this.opts.project.configuration.get(`pnpEnableInlining`)) {
const loaderFile = generateInlinedScript(pnpSettings);

Expand Down
122 changes: 89 additions & 33 deletions packages/yarnpkg-builder/sources/commands/build/bundle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {getDynamicLibs} from '@yarnpkg/cli';
import {StreamReport, MessageName, Configuration, formatUtils, structUtils} from '@yarnpkg/core';
import {StreamReport, MessageName, Configuration, formatUtils, structUtils, hashUtils} from '@yarnpkg/core';
import {pnpPlugin} from '@yarnpkg/esbuild-plugin-pnp';
import {npath} from '@yarnpkg/fslib';
import {Filename, npath, PortablePath, ppath, xfs} from '@yarnpkg/fslib';
import chalk from 'chalk';
import cp from 'child_process';
import {Command, Option, Usage} from 'clipanion';
Expand All @@ -11,6 +11,7 @@ import {createRequire} from
import path from 'path';
import semver from 'semver';
import {promisify} from 'util';
import {webpack} from 'webpack';

import {findPlugins} from '../../tools/findPlugins';

Expand Down Expand Up @@ -59,6 +60,10 @@ export default class BuildBundleCommand extends Command {
description: `An array of plugins that should be included besides the ones specified in the profile`,
});

split = Option.Boolean(`--split`, false, {
description: `Build a bundle that splits the application then unifies it into a self-extracting packaged app`,
});

noGitHash = Option.Boolean(`--no-git-hash`, false, {
description: `Don't include the git hash of the current commit in bundle version`,
});
Expand Down Expand Up @@ -114,38 +119,89 @@ export default class BuildBundleCommand extends Command {
},
};

const res = await build({
banner: {
js: `#!/usr/bin/env node\n/* eslint-disable */\n//prettier-ignore`,
},
entryPoints: [path.join(basedir, `sources/cli.ts`)],
bundle: true,
define: {YARN_VERSION: JSON.stringify(version)},
outfile: output,
logLevel: `silent`,
format: `iife`,
platform: `node`,
plugins: [valLoader, pnpPlugin()],
minify: !this.noMinify,
sourcemap: this.sourceMap ? `inline` : false,
target: `node14`,
await xfs.mktempPromise(async p => {
let banner = `/* eslint-disable */\n//prettier-ignore\n`;
if (this.split)
banner += `import {createRequire} from 'module';\nconst require = createRequire(import.meta.url);`;

const res = await build({
banner: {js: banner},
entryPoints: [path.join(basedir, `sources/cli.ts`)],
bundle: true,
splitting: this.split,
define: {YARN_VERSION: JSON.stringify(version)},
logLevel: `silent`,
format: this.split ? `esm` : `iife`,
platform: `node`,
plugins: [valLoader, pnpPlugin()],
minify: !this.noMinify,
sourcemap: this.sourceMap ? `inline` : false,
target: `node14`,
outExtension: {[`.js`]: '.mjs'},
...this.split ? {
outdir: npath.fromPortablePath(p),
} : {
outfile: output,
}
});

if (this.split) {
const chunks = await xfs.readdirPromise(p);

let payload = ``;

const packFiles = async () => {
return await Promise.all(chunks.map(async name => {
return [name, await xfs.readFilePromise(ppath.join(p, name), `base64`)];
}));
};

payload += `const fs = require('fs');\n`;
payload += `const os = require('os');\n`;
payload += `const path = require('path');\n`;
payload += `\n`;
payload += `const unpackDir = path.join(os.homedir(), '.yarn/berry/chunks', hash);\n`;
payload += `const flagFile = path.join(unpackDir, '.ready');\n`;
payload += `const entryFile = path.join(unpackDir, 'cli.mjs');\n`;
payload += `\n`;
payload += `if (!fs.existsSync(flagFile)) {\n`;
payload += ` const files = JSON.parse(${JSON.stringify(JSON.stringify(await packFiles()))});\n`;
payload += `\n`;
payload += ` fs.rmSync(unpackDir, {force: true, recursive: true});\n`;
payload += ` fs.mkdirSync(unpackDir, {recursive: true});\n`;
payload += `\n`;
payload += ` Promise.all(files.map(i => fs.promises.writeFile(path.join(unpackDir, i[0]), i[1], 'base64'))).then(() => {\n`;
payload += ` fs.writeFileSync(flagFile, '');\n`;
payload += ` import(entryFile);\n`;
payload += ` });\n`;
payload += `} else {\n`;
payload += ` import(entryFile);\n`;
payload += `}\n`;

const hash = hashUtils.makeHash(payload);
payload = `const hash = ${JSON.stringify(hash)};\n\n${payload}`;

await xfs.writeFilePromise(output as PortablePath, payload);

report.reportWarning(MessageName.UNNAMED, `Note: The split bundle hash is ${hash}`);
}

for (const warning of res.warnings) {
if (warning.location !== null)
continue;

report.reportWarning(MessageName.UNNAMED, warning.text);
}


for (const warning of res.warnings) {
if (warning.location === null)
continue;

report.reportWarning(MessageName.UNNAMED, `${warning.location.file}:${warning.location.line}:${warning.location.column}`);
report.reportWarning(MessageName.UNNAMED, ` ↳ ${warning.text}`);
}
});

for (const warning of res.warnings) {
if (warning.location !== null)
continue;

report.reportWarning(MessageName.UNNAMED, warning.text);
}


for (const warning of res.warnings) {
if (warning.location === null)
continue;

report.reportWarning(MessageName.UNNAMED, `${warning.location.file}:${warning.location.line}:${warning.location.column}`);
report.reportWarning(MessageName.UNNAMED, ` ↳ ${warning.text}`);
}
});
});

Expand Down

This file was deleted.

3 changes: 0 additions & 3 deletions packages/yarnpkg-cli/sources/tools/getDynamicLibs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as shell from '@yarnpkg/shell';
import * as clipanion from 'clipanion';
import * as semver from 'semver';
import * as typanion from 'typanion';
import * as yup from 'yup';

export const getDynamicLibs = () => new Map<string, any>([
[`@yarnpkg/cli`, cli],
Expand All @@ -21,6 +20,4 @@ export const getDynamicLibs = () => new Map<string, any>([
[`clipanion`, clipanion],
[`semver`, semver],
[`typanion`, typanion],
// TODO: remove in next major
[`yup`, yup],
]);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = ({modules, plugins}) => {
}).join(``);

const moduleSegment = ` modules: new Map([\n${modules.map((request, index) => {
return ` [${JSON.stringify(require(`${request}/package.json`).name)}, ${request === `clipanion` ? `backportClipanionCompatibility` : ``}(_${index})],\n`;
return ` [${JSON.stringify(require(`${request}/package.json`).name)}, _${index}],\n`;
}).join(``)} ]),\n`;

const pluginSegment = ` plugins: new Set([\n${plugins.map(request => {
Expand All @@ -16,8 +16,6 @@ module.exports = ({modules, plugins}) => {

return {
code: [
`import {backportClipanionCompatibility} from './backportClipanionCompatibility';\n`,
`\n`,
importSegment,
`export const getPluginConfiguration = () => ({\n`,
moduleSegment,
Expand Down
2 changes: 1 addition & 1 deletion packages/yarnpkg-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"semver": "^7.1.2",
"strip-ansi": "^6.0.0",
"tar": "^6.0.5",
"tinylogic": "^1.0.3",
"tinylogic": "^2.0.0",
"treeify": "^1.1.0",
"tslib": "^1.13.0",
"tunnel": "^0.0.6"
Expand Down
Loading