@yarnpkg/plugin-pnp 3.1.0-rc.4 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ export declare class PnpInstaller implements Installer {
16
16
  protected mode: string;
17
17
  private readonly packageRegistry;
18
18
  private readonly virtualTemplates;
19
+ private isESMLoaderRequired;
19
20
  constructor(opts: LinkOptions);
20
21
  getCustomDataKey(): string;
21
22
  private customData;
@@ -32,6 +33,7 @@ export declare class PnpInstaller implements Installer {
32
33
  manifest: {
33
34
  scripts: Map<string, string>;
34
35
  preferUnplugged: boolean | null;
36
+ type: string | null;
35
37
  };
36
38
  misc: {
37
39
  extractHint: boolean;
@@ -41,6 +43,7 @@ export declare class PnpInstaller implements Installer {
41
43
  };
42
44
  } | undefined>;
43
45
  transformPnpSettings(pnpSettings: PnpSettings): Promise<void>;
46
+ private isEsmEnabled;
44
47
  finalizeInstallWithPnp(pnpSettings: PnpSettings): Promise<void>;
45
48
  private locateNodeModules;
46
49
  private readonly unpluggedPaths;
package/lib/PnpLinker.js CHANGED
@@ -67,6 +67,7 @@ class PnpInstaller {
67
67
  this.mode = `strict`;
68
68
  this.packageRegistry = new Map();
69
69
  this.virtualTemplates = new Map();
70
+ this.isESMLoaderRequired = false;
70
71
  this.customData = {
71
72
  store: new Map(),
72
73
  };
@@ -76,7 +77,7 @@ class PnpInstaller {
76
77
  getCustomDataKey() {
77
78
  return JSON.stringify({
78
79
  name: `PnpInstaller`,
79
- version: 1,
80
+ version: 2,
80
81
  });
81
82
  }
82
83
  attachCustomData(customData) {
@@ -113,6 +114,8 @@ class PnpInstaller {
113
114
  this.customData.store.set(devirtualizedLocator.locatorHash, customPackageData);
114
115
  }
115
116
  }
117
+ if (customPackageData.manifest.type === `module`)
118
+ this.isESMLoaderRequired = true;
116
119
  dependencyMeta = this.opts.project.getDependencyMeta(devirtualizedLocator, pkg.version);
117
120
  }
118
121
  const buildScripts = mayNeedToBeBuilt
@@ -179,9 +182,12 @@ class PnpInstaller {
179
182
  this.opts.report.reportWarning(core_2.MessageName.UNNAMED, `Removing the old ${core_1.formatUtils.pretty(this.opts.project.configuration, fslib_1.Filename.pnpJs, core_1.formatUtils.Type.PATH)} file. You might need to manually update existing references to reference the new ${core_1.formatUtils.pretty(this.opts.project.configuration, fslib_1.Filename.pnpCjs, core_1.formatUtils.Type.PATH)} file. If you use Editor SDKs, you'll have to rerun ${core_1.formatUtils.pretty(this.opts.project.configuration, `yarn sdks`, core_1.formatUtils.Type.CODE)}.`);
180
183
  await fslib_1.xfs.removePromise(pnpPath.cjsLegacy);
181
184
  }
185
+ if (!this.isEsmEnabled())
186
+ await fslib_1.xfs.removePromise(pnpPath.esmLoader);
182
187
  if (this.opts.project.configuration.get(`nodeLinker`) !== `pnp`) {
183
188
  await fslib_1.xfs.removePromise(pnpPath.cjs);
184
189
  await fslib_1.xfs.removePromise(this.opts.project.configuration.get(`pnpDataPath`));
190
+ await fslib_1.xfs.removePromise(pnpPath.esmLoader);
185
191
  return undefined;
186
192
  }
187
193
  for (const { locator, location } of this.virtualTemplates.values()) {
@@ -224,6 +230,18 @@ class PnpInstaller {
224
230
  async transformPnpSettings(pnpSettings) {
225
231
  // Nothing to transform
226
232
  }
233
+ isEsmEnabled() {
234
+ if (this.opts.project.configuration.sources.has(`pnpEnableEsmLoader`))
235
+ return this.opts.project.configuration.get(`pnpEnableEsmLoader`);
236
+ if (this.isESMLoaderRequired)
237
+ return true;
238
+ for (const workspace of this.opts.project.workspaces) {
239
+ if (workspace.manifest.type === `module`) {
240
+ return true;
241
+ }
242
+ }
243
+ return false;
244
+ }
227
245
  async finalizeInstallWithPnp(pnpSettings) {
228
246
  const pnpPath = (0, index_1.getPnpPath)(this.opts.project);
229
247
  const pnpDataPath = this.opts.project.configuration.get(`pnpDataPath`);
@@ -255,6 +273,13 @@ class PnpInstaller {
255
273
  mode: 0o644,
256
274
  });
257
275
  }
276
+ if (this.isEsmEnabled()) {
277
+ this.opts.report.reportWarning(core_2.MessageName.UNNAMED, `ESM support for PnP uses the experimental loader API and is therefore experimental`);
278
+ await fslib_1.xfs.changeFilePromise(pnpPath.esmLoader, (0, pnp_1.getESMLoaderTemplate)(), {
279
+ automaticNewlines: true,
280
+ mode: 0o644,
281
+ });
282
+ }
258
283
  const pnpUnpluggedFolder = this.opts.project.configuration.get(`pnpUnpluggedFolder`);
259
284
  if (this.unpluggedPaths.size === 0) {
260
285
  await fslib_1.xfs.removePromise(pnpUnpluggedFolder);
@@ -305,7 +330,7 @@ class PnpInstaller {
305
330
  return dependencyMeta.unplugged;
306
331
  if (FORCED_UNPLUG_PACKAGES.has(pkg.identHash))
307
332
  return true;
308
- if (pkg.conditions !== null)
333
+ if (pkg.conditions != null)
309
334
  return true;
310
335
  if (customPackageData.manifest.preferUnplugged !== null)
311
336
  return customPackageData.manifest.preferUnplugged;
@@ -371,6 +396,7 @@ async function extractCustomPackageData(fetchResult) {
371
396
  manifest: {
372
397
  scripts: manifest.scripts,
373
398
  preferUnplugged: manifest.preferUnplugged,
399
+ type: manifest.type,
374
400
  },
375
401
  misc: {
376
402
  extractHint: jsInstallUtils.getExtractHint(fetchResult),
package/lib/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { pnpUtils };
8
8
  export declare const getPnpPath: (project: Project) => {
9
9
  cjs: PortablePath;
10
10
  cjsLegacy: PortablePath;
11
+ esmLoader: PortablePath;
11
12
  };
12
13
  export declare const quotePathIfNeeded: (path: string) => string;
13
14
  declare module '@yarnpkg/core' {
@@ -16,6 +17,7 @@ declare module '@yarnpkg/core' {
16
17
  pnpMode: string;
17
18
  pnpShebang: string;
18
19
  pnpIgnorePatterns: Array<string>;
20
+ pnpEnableEsmLoader: boolean;
19
21
  pnpEnableInlining: boolean;
20
22
  pnpFallbackMode: string;
21
23
  pnpUnpluggedFolder: PortablePath;
package/lib/index.js CHANGED
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const core_1 = require("@yarnpkg/core");
6
6
  const fslib_1 = require("@yarnpkg/fslib");
7
7
  const semver_1 = (0, tslib_1.__importDefault)(require("semver"));
8
+ const url_1 = require("url");
8
9
  const PnpLinker_1 = require("./PnpLinker");
9
10
  const unplug_1 = (0, tslib_1.__importDefault)(require("./commands/unplug"));
10
11
  const jsInstallUtils = (0, tslib_1.__importStar)(require("./jsInstallUtils"));
@@ -15,6 +16,7 @@ const getPnpPath = (project) => {
15
16
  return {
16
17
  cjs: fslib_1.ppath.join(project.cwd, fslib_1.Filename.pnpCjs),
17
18
  cjsLegacy: fslib_1.ppath.join(project.cwd, fslib_1.Filename.pnpJs),
19
+ esmLoader: fslib_1.ppath.join(project.cwd, `.pnp.loader.mjs`),
18
20
  };
19
21
  };
20
22
  exports.getPnpPath = getPnpPath;
@@ -23,22 +25,27 @@ const quotePathIfNeeded = (path) => {
23
25
  };
24
26
  exports.quotePathIfNeeded = quotePathIfNeeded;
25
27
  async function setupScriptEnvironment(project, env, makePathWrapper) {
26
- const pnpPath = (0, exports.getPnpPath)(project).cjs;
27
- const pnpRequire = `--require ${(0, exports.quotePathIfNeeded)(fslib_1.npath.fromPortablePath(pnpPath))}`;
28
- if (pnpPath.includes(` `) && semver_1.default.lt(process.versions.node, `12.0.0`))
28
+ const pnpPath = (0, exports.getPnpPath)(project);
29
+ let pnpRequire = `--require ${(0, exports.quotePathIfNeeded)(fslib_1.npath.fromPortablePath(pnpPath.cjs))}`;
30
+ if (fslib_1.xfs.existsSync(pnpPath.esmLoader))
31
+ pnpRequire = `${pnpRequire} --experimental-loader ${(0, url_1.pathToFileURL)(fslib_1.npath.fromPortablePath(pnpPath.esmLoader)).href}`;
32
+ if (pnpPath.cjs.includes(` `) && semver_1.default.lt(process.versions.node, `12.0.0`))
29
33
  throw new Error(`Expected the build location to not include spaces when using Node < 12.0.0 (${process.versions.node})`);
30
- if (fslib_1.xfs.existsSync(pnpPath)) {
34
+ if (fslib_1.xfs.existsSync(pnpPath.cjs)) {
31
35
  let nodeOptions = env.NODE_OPTIONS || ``;
32
36
  // We still support .pnp.js files to improve multi-project compatibility.
33
37
  // TODO: Drop the question mark in the RegExp after .pnp.js files stop being used.
34
38
  const pnpRegularExpression = /\s*--require\s+\S*\.pnp\.c?js\s*/g;
35
- nodeOptions = nodeOptions.replace(pnpRegularExpression, ` `).trim();
39
+ const esmLoaderExpression = /\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/;
40
+ nodeOptions = nodeOptions.replace(pnpRegularExpression, ` `).replace(esmLoaderExpression, ` `).trim();
36
41
  nodeOptions = nodeOptions ? `${pnpRequire} ${nodeOptions}` : pnpRequire;
37
42
  env.NODE_OPTIONS = nodeOptions;
38
43
  }
39
44
  }
40
45
  async function populateYarnPaths(project, definePath) {
41
- definePath((0, exports.getPnpPath)(project).cjs);
46
+ const pnpPath = (0, exports.getPnpPath)(project);
47
+ definePath(pnpPath.cjs);
48
+ definePath(pnpPath.esmLoader);
42
49
  definePath(project.configuration.get(`pnpDataPath`));
43
50
  definePath(project.configuration.get(`pnpUnpluggedFolder`));
44
51
  }
@@ -69,6 +76,11 @@ const plugin = {
69
76
  default: [],
70
77
  isArray: true,
71
78
  },
79
+ pnpEnableEsmLoader: {
80
+ description: `If true, Yarn will generate an ESM loader (\`.pnp.loader.mjs\`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.`,
81
+ type: core_1.SettingsType.BOOLEAN,
82
+ default: false,
83
+ },
72
84
  pnpEnableInlining: {
73
85
  description: `If true, the PnP data will be inlined along with the generated loader`,
74
86
  type: core_1.SettingsType.BOOLEAN,
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "name": "@yarnpkg/plugin-pnp",
3
- "version": "3.1.0-rc.4",
3
+ "version": "3.1.1",
4
4
  "license": "BSD-2-Clause",
5
5
  "main": "./lib/index.js",
6
6
  "dependencies": {
7
7
  "@types/semver": "^7.1.0",
8
- "@yarnpkg/fslib": "^2.6.0-rc.11",
9
- "@yarnpkg/plugin-stage": "^3.1.0-rc.1",
10
- "@yarnpkg/pnp": "^3.1.0-rc.8",
8
+ "@yarnpkg/fslib": "^2.6.0",
9
+ "@yarnpkg/plugin-stage": "^3.1.1",
10
+ "@yarnpkg/pnp": "^3.1.0",
11
11
  "clipanion": "^3.0.1",
12
12
  "micromatch": "^4.0.2",
13
13
  "semver": "^7.1.2",
14
14
  "tslib": "^1.13.0"
15
15
  },
16
16
  "peerDependencies": {
17
- "@yarnpkg/cli": "^3.1.0-rc.11",
18
- "@yarnpkg/core": "^3.1.0-rc.12"
17
+ "@yarnpkg/cli": "^3.1.0",
18
+ "@yarnpkg/core": "^3.1.0"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/micromatch": "^4.0.1",
22
- "@yarnpkg/cli": "^3.1.0-rc.11",
23
- "@yarnpkg/core": "^3.1.0-rc.12"
22
+ "@yarnpkg/cli": "^3.1.0",
23
+ "@yarnpkg/core": "^3.1.0"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
@@ -41,6 +41,5 @@
41
41
  "engines": {
42
42
  "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0"
43
43
  },
44
- "stableVersion": "3.0.0",
45
44
  "typings": "./lib/index.d.ts"
46
45
  }