1 |
|
2 | import semver from 'semver';
|
3 |
|
4 | import logger from '@parcel/logger';
|
5 | import {CONFIG} from '@parcel/plugin';
|
6 | import type {FilePath, PackageName} from '@parcel/types';
|
7 | import type {PackageManager} from '@parcel/package-manager';
|
8 |
|
9 | const PARCEL_VERSION = require('../package.json').version;
|
10 |
|
11 | export default async function loadPlugin(
|
12 | packageManager: PackageManager,
|
13 | pluginName: PackageName,
|
14 | resolveFrom: FilePath,
|
15 | ) {
|
16 | let {resolved, pkg} = await packageManager.resolve(
|
17 | pluginName,
|
18 | `${resolveFrom}/index`,
|
19 | );
|
20 |
|
21 |
|
22 | let parcelVersionRange = pkg && pkg.engines && pkg.engines.parcel;
|
23 | if (!parcelVersionRange) {
|
24 | logger.warn({
|
25 | origin: '@parcel/core',
|
26 | message: `The plugin "${pluginName}" needs to specify a \`package.json#engines.parcel\` field with the supported Parcel version range.`,
|
27 | });
|
28 | }
|
29 |
|
30 | if (
|
31 | parcelVersionRange &&
|
32 | !semver.satisfies(PARCEL_VERSION, parcelVersionRange)
|
33 | ) {
|
34 | throw new Error(
|
35 | `The plugin "${pluginName}" is not compatible with the current version of Parcel. Requires "${parcelVersionRange}" but the current version is "${PARCEL_VERSION}".`,
|
36 | );
|
37 | }
|
38 |
|
39 | let plugin = await packageManager.require(resolved, `${resolveFrom}/index`);
|
40 | plugin = plugin.default ? plugin.default : plugin;
|
41 | if (!plugin) {
|
42 | throw new Error(`Plugin ${pluginName} has no exports.`);
|
43 | }
|
44 | plugin = plugin[CONFIG];
|
45 | if (!plugin) {
|
46 | throw new Error(
|
47 | `Plugin ${pluginName} is not a valid Parcel plugin, should export an instance of a Parcel plugin ex. "export default new Reporter({ ... })".`,
|
48 | );
|
49 | }
|
50 | return plugin;
|
51 | }
|