Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Simply place those dependencies inside the `basePackageValues` object which repr
new `package.json` to be created.

Keep the version number string empty (`""`) to have the plugin resolve the version. To use a version which is
different, set the version string deliberately here.
different, set the version string deliberately here. You can also use version prefixes `"^"` or `"~"` which will resolve the installed version and prepend the prefix.

```
const basePackageValues = {
Expand All @@ -88,16 +88,19 @@ const basePackageValues = {
devDependencies: {
"cross-var": "^1.1.0",
"cross-env": "",
"lodash": "^",
},
peerDependencies: {
"react" : "",
"react" : "~",
}
}
```

In this example, `cross-var` has deliberately been set to version `^1.1.0`, and regardless of what is actually installed
it will use this version.
`cross-env` however will pull its version number from `node_modules`.
In this example:
- `cross-var` has been set to version `^1.1.0` explicitly and will use this exact version
- `cross-env` will pull its version number from `node_modules` (e.g., `8.0.1`)
- `lodash` will resolve the installed version with a caret prefix (e.g., `^4.17.21`)
- `react` will resolve the installed version with a tilde prefix (e.g., `~18.2.0`)

This is mostly useful for adding dependencies which are required at runtime but which are not picked up in your webpack
bundle. Such as `cross-var` in this example which injects environment variables into a run script in a cross-platform
Expand Down
42 changes: 37 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ function logIfDebug(something, object = "") {
}
}

function isVersionPrefix(versionString) {
// Check if the string is a version prefix like "^" or "~"
return /^(\^|~)$/.test(versionString);
}

const nodeModulesPart = "node_modules";

function getNameFromPortableId(raw) {
Expand Down Expand Up @@ -306,11 +311,38 @@ GeneratePackageJsonPlugin.prototype.apply = function (compiler) {
for (let k = 0; k < nonWebpackModuleNames.length; k += 1) {
const moduleName = nonWebpackModuleNames[k];
let useVersionMap = !this.useInstalledVersions;

if (basePackageValues[dependencyType] && basePackageValues[dependencyType][moduleName] && basePackageValues[dependencyType][moduleName].length > 0) {
logIfDebug(`GPJWP: Adding deliberate module in "${dependencyType}" with version set deliberately: ${moduleName} -> ${basePackageValues[dependencyType][moduleName]}`);
if (dependencyType === "dependencies") {
modules[moduleName] = basePackageValues[dependencyType][moduleName];
const versionString = basePackageValues[dependencyType] && basePackageValues[dependencyType][moduleName];
const isPrefix = isVersionPrefix(versionString);

if (versionString && versionString.length > 0) {
if (isPrefix && this.useInstalledVersions) {
// If it's a version prefix, resolve the installed version and apply the prefix
logIfDebug(`GPJWP: Adding module in "${dependencyType}" with version prefix: ${moduleName} -> ${versionString}<installed-version>`);
const installedVersion = getInstalledVersionForModuleName(moduleName);
if (installedVersion != null) {
// "versionString" is only the prefix (e.g. "^") as checked by isPrefix() earlier
// - so we take the installed version and add the prefix to it for the final version string
const prefixedVersion = versionString + installedVersion;

if (dependencyType === "dependencies") {
modules[moduleName] = prefixedVersion;
} else {
if (!basePackageValues[dependencyType]) {
basePackageValues[dependencyType] = {};
}
basePackageValues[dependencyType][moduleName] = prefixedVersion;
delete modules[moduleName];
}
} else {
console.warn(`${pluginPrefix}Couldn't find installed version for module "${moduleName}" with prefix "${versionString}"`);
useVersionMap = true;
}
} else {
// Use the version string as-is (it's an explicit version or prefix but useInstalledVersions is false)
logIfDebug(`GPJWP: Adding deliberate module in "${dependencyType}" with version set deliberately: ${moduleName} -> ${versionString}`);
if (dependencyType === "dependencies") {
modules[moduleName] = versionString;
}
}
} else if (this.useInstalledVersions) {
const version = getInstalledVersionForModuleName(moduleName);
Expand Down