Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/slick-files-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@webpack/migrate-library-target-to-library-object": major
---

Introduce the codemod, by copy pasting it here from `codemod/webpack-codemods`
78 changes: 78 additions & 0 deletions codemods/migrate-library-target-to-library-object/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# migrate-library-target-to-library-object

This codemod migrates the `output.library` and `output.libraryTarget` properties in Webpack configurations to the new format required by Webpack 5. It changes `output.library` to `output.library.name` and `output.libraryTarget` to `output.library.type`.

## Example

```diff
- module.exports = {
- output: {
- library: "MyLibrary",
- libraryTarget: "commonjs2",
- },
- };
+ module.exports = {
+ output: {
+ library: {
+ name: "MyLibrary",
+ type: "commonjs2",
+ },
+ },
+ };
```

```diff
- module.exports = {
- output: {
- library: "MyLibrary",
- libraryTarget: "commonjs2",
- filename: "bundle.js",
- },
- };
+ module.exports = {
+ output: {
+ library: {
+ name: "MyLibrary",
+ type: "commonjs2",
+ },
+
+ filename: "bundle.js",
+ },
+ };
```

```diff
- module.exports = {
- output: {
- library: "MyLibrary",
- },
- };
+ module.exports = {
+ output: {
+ library: {
+ name: "MyLibrary",
+ type: undefined,
+ },
+ },
+ };
```

```diff
- module.exports = {
- output: {
- library: "MyLibrary",
- libraryTarget: "umd",
- path: "./dist",
- },
- };
+ module.exports = {
+ output: {
+ library: {
+ name: "MyLibrary",
+ type: "umd",
+ },
+
+ path: "./dist",
+ },
+ };
```
21 changes: 21 additions & 0 deletions codemods/migrate-library-target-to-library-object/codemod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
schema_version: "1.0"
name: "@webpack/migrate-library-target-to-library-object"
version: 1.0.0
description: Transform Webpack 'library' and 'libraryTarget' to the new object format.
author: akash-kumar-dev
license: MIT
workflow: workflow.yaml
repository: "https://github.com/webpack/codemods/tree/HEAD/codemods/migrate-library-target-to-library-object"
category: migration

targets:
languages:
- javascript
- typescript

keywords:
- webpack

registry:
access: public
visibility: public
13 changes: 13 additions & 0 deletions codemods/migrate-library-target-to-library-object/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@webpack/migrate-library-target-to-library-object",
"private": true,
"version": "1.0.0",
"description": "Transform Webpack 'library' and 'libraryTarget' to the new object format.",
"type": "module",
"scripts": {
"test": "npx codemod jssg test -l typescript ./src/workflow.ts"
},
"devDependencies": {
"@codemod.com/jssg-types": "^1.6.3"
}
}
151 changes: 151 additions & 0 deletions codemods/migrate-library-target-to-library-object/src/workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import type { Codemod, Edit } from "codemod:ast-grep";
import type Js from "@codemod.com/jssg-types/langs/javascript";

const transform: Codemod<Js> = async (root) => {
const rootNode = root.root();
const edits: Edit[] = [];

// Find all module.exports assignments
const moduleExports = rootNode.findAll({
rule: {
kind: "assignment_expression",
has: {
kind: "member_expression",
has: {
field: "object",
kind: "identifier",
regex: "^module$",
},
},
},
});

for (const moduleExport of moduleExports) {
// Find the right side of the assignment (the configuration object)
const rightSide = moduleExport.find({
rule: {
kind: "object",
},
});

if (!rightSide) continue;

// Find the output property
const outputProperty = rightSide.find({
rule: {
kind: "pair",
has: {
field: "key",
kind: "property_identifier",
regex: "^output$",
},
},
});

if (!outputProperty) continue;

// Find the output object value
const outputObject = outputProperty.find({
rule: {
kind: "object",
},
});

if (!outputObject) continue;

// Find library and libraryTarget properties
const libraryProperty = outputObject.find({
rule: {
kind: "pair",
has: {
field: "key",
kind: "property_identifier",
regex: "^library$",
},
},
});

const libraryTargetProperty = outputObject.find({
rule: {
kind: "pair",
has: {
field: "key",
kind: "property_identifier",
regex: "^libraryTarget$",
},
},
});

if (!libraryProperty) continue;

// Get the library value
const libraryValue = libraryProperty.find({
rule: {
kind: "string",
},
});

if (!libraryValue) continue;

const libraryName = libraryValue.text();

// Get the libraryTarget value if it exists
let libraryType = "undefined";
if (libraryTargetProperty) {
const libraryTargetValue = libraryTargetProperty.find({
rule: {
kind: "string",
},
});
if (libraryTargetValue) {
libraryType = libraryTargetValue.text();
}
}

// Get all properties in the output object to reconstruct it properly
const allProperties = outputObject.findAll({
rule: {
kind: "pair",
},
});

// Build new output object content with preserved tabs and trailing commas per property
const newProperties: string[] = [];

for (const property of allProperties) {
const keyNode = property.find({
rule: {
kind: "property_identifier",
},
});

if (!keyNode) continue;

const keyName = keyNode.text();

if (keyName === "library") {
// Replace with new library object, keep trailing comma
newProperties.push(
`library: {\n\t\t\tname: ${libraryName},\n\t\t\ttype: ${libraryType === "undefined" ? "undefined" : libraryType},\n\t\t},`,
);
} else if (keyName === "libraryTarget") {
// Skip libraryTarget property - it's being moved into library.type
// (no-op)
} else {
// Keep other properties and add trailing comma
newProperties.push(`${property.text()},`);
}
}

// Replace the entire output object with tab-indented content to match source style
const newOutputObject = `{\n\t\t${newProperties.join("\n\t\t")}\n\t}`;

edits.push(outputObject.replace(newOutputObject));
}

if (!edits.length) return null;

return rootNode.commitEdits(edits);
}

export default transform;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
output: {
library: {
name: "MyLibrary",
type: "commonjs2",
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
output: {
library: "MyLibrary",
libraryTarget: "commonjs2",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
output: {
library: {
name: "MyLibrary",
type: "commonjs2",
},
filename: "bundle.js",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
output: {
library: "MyLibrary",
libraryTarget: "commonjs2",
filename: "bundle.js",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
output: {
library: {
name: "MyLibrary",
type: undefined,
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
output: {
library: "MyLibrary",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
output: {
library: {
name: "MyLibrary",
type: "umd",
},
path: "./dist",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
output: {
library: "MyLibrary",
libraryTarget: "umd",
path: "./dist",
},
};
23 changes: 23 additions & 0 deletions codemods/migrate-library-target-to-library-object/workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json

version: "1"

nodes:
- id: apply-transforms
name: Apply AST Transformations
type: automatic
steps:
- name: Transform Webpack 'library' and 'libraryTarget' to the new object format.
js-ast-grep:
js_file: src/workflow.ts
base_path: .
include:
- "**/*.tsx"
- "**/*.ts"
- "**/*.jsx"
- "**/*.js"
- "**/*.cts"
- "**/*.mts"
exclude:
- "**/node_modules/**"
language: typescript
13 changes: 12 additions & 1 deletion package-lock.json

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