From 65ce966f10523c88fa86d86a0a395e77fbe3c15d Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Mon, 30 Mar 2026 19:13:33 +0300 Subject: [PATCH 01/10] fix(generator): generate a ts confi file -Add ts-node to load the configuration file --- packages/create-webpack-app/src/generators/init/default.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/create-webpack-app/src/generators/init/default.ts b/packages/create-webpack-app/src/generators/init/default.ts index 15d019bbff3..914a472bacd 100644 --- a/packages/create-webpack-app/src/generators/init/default.ts +++ b/packages/create-webpack-app/src/generators/init/default.ts @@ -105,7 +105,7 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { devDependencies.push("babel-loader", "@babel/core", "@babel/preset-env"); break; case "Typescript": - devDependencies.push("typescript", "ts-loader"); + devDependencies.push("typescript", "ts-loader", "ts-node"); break; } @@ -149,7 +149,10 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, - { filePath: "webpack.config.js", fileType: "text" }, + { + filePath: answers.langType === "Typescript" ? "webpack.config.ts" : "webpack.config.js", + fileType: "text", + }, { filePath: "package.json", fileType: "text" }, { filePath: "README.md", fileType: "text" }, ]; From 018effa3998ff02683681682836773e251825e0d Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 31 Mar 2026 14:51:55 +0300 Subject: [PATCH 02/10] fix(init): generate webpack.config.ts when TypeScript is selected - Replace `webpack.config.js.tpl` with a unified `webpack.config.tpl` based on `langType` - Add conditional `import "webpack-dev-server"` when devServer is selected - Add `ts-node` to devDependencies when TypeScript is selected - Update tests to assert `webpack.config.ts` is generated for TypeScript projects --- .../src/generators/init/default.ts | 4 +- .../templates/init/default/package.json.tpl | 10 +- .../templates/init/default/tsconfig.json.tpl | 14 +- ...bpack.config.js.tpl => webpack.config.tpl} | 20 +- .../__snapshots__/init.test.js.snap.webpack5 | 205 +++++++++--------- test/create-webpack-app/init/init.test.js | 14 +- 6 files changed, 138 insertions(+), 129 deletions(-) rename packages/create-webpack-app/templates/init/default/{webpack.config.js.tpl => webpack.config.tpl} (83%) diff --git a/packages/create-webpack-app/src/generators/init/default.ts b/packages/create-webpack-app/src/generators/init/default.ts index 914a472bacd..5b11838be7d 100644 --- a/packages/create-webpack-app/src/generators/init/default.ts +++ b/packages/create-webpack-app/src/generators/init/default.ts @@ -189,7 +189,9 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { templateFile: join( plop.getPlopfilePath(), "../templates/init/default", - `${file.filePath}.tpl`, + file.filePath.startsWith("webpack.config") + ? "webpack.config.tpl" + : `${file.filePath}.tpl`, ), fileType: file.fileType, data: answers, diff --git a/packages/create-webpack-app/templates/init/default/package.json.tpl b/packages/create-webpack-app/templates/init/default/package.json.tpl index 625b0b17ccf..3e96af85ad4 100644 --- a/packages/create-webpack-app/templates/init/default/package.json.tpl +++ b/packages/create-webpack-app/templates/init/default/package.json.tpl @@ -1,14 +1,14 @@ -{ +<% const nodeOptions = langType === "Typescript" ? "NODE_OPTIONS='--loader ts-node/esm --no-warnings' " : ""; %>{ "version": "1.0.0", "description": "My webpack project", "name": "webpack-project", "type": "module", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", + "build": "<%- nodeOptions %>webpack --mode=production --config-node-env=production <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", + "build:dev": "<%- nodeOptions %>webpack --mode=development <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", <% if (devServer) { %> - "serve": "webpack serve", + "serve": "<%- nodeOptions %>webpack serve <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", <% } %> - "watch": "webpack --watch" + "watch": "<%- nodeOptions %>webpack --watch <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>" } } diff --git a/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl index 31176e658c2..a024736bfe4 100644 --- a/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl +++ b/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl @@ -2,9 +2,15 @@ "compilerOptions": { "allowSyntheticDefaultImports": true, "noImplicitAny": true, - "module": "es6", - "target": "es5", - "allowJs": true + "module": "esnext", + "moduleResolution": "bundler", + "target": "esnext", + "allowJs": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "rewriteRelativeImportExtensions": true }, - "files": ["src/index.ts"] + "include": ["src/**/*"], + "exclude": ["node_modules"] } diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.js.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl similarity index 83% rename from packages/create-webpack-app/templates/init/default/webpack.config.js.tpl rename to packages/create-webpack-app/templates/init/default/webpack.config.tpl index e9620d86333..8a36a6783f3 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.js.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -1,8 +1,10 @@ // Generated using webpack-cli https://github.com/webpack/webpack-cli import path from "node:path"; -import { fileURLToPath } from "node:url";<% if (htmlWebpackPlugin) { %> -import HtmlWebpackPlugin from "html-webpack-plugin";<% } %><% if (extractPlugin !== "No") { %> +import { fileURLToPath } from "node:url"; +<% if (langType === "Typescript") { %>import { Configuration } from "webpack"; +<% if (devServer) { %>import "webpack-dev-server";<% } %><% } %> +<% if (htmlWebpackPlugin) { %>import HtmlWebpackPlugin from "html-webpack-plugin";<% } %><% if (extractPlugin !== "No") { %> import MiniCssExtractPlugin from "mini-css-extract-plugin";<% } %><% if (workboxWebpackPlugin) { %> import WorkboxWebpackPlugin from "workbox-webpack-plugin";<% } %> @@ -15,12 +17,10 @@ const stylesHandler = MiniCssExtractPlugin.loader; <% } else if (extractPlugin === "Only for Production") { %> const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; <% } else { %> -const stylesHandler = "style-loader"; -<% } %> -<% } %> +const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config = { +const config <% if (langType === "Typescript") { %>: Configuration<% } %> = { entry: "<%= entryPoint %>", output: { path: path.resolve(__dirname, "dist"), @@ -91,12 +91,8 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - <% if (extractPlugin === "Only for Production") { %> - config.plugins.push(new MiniCssExtractPlugin()); - <% } %> - <% if (workboxWebpackPlugin) { %> - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - <% } %> + <% if (extractPlugin === "Only for Production") { %>config.plugins!.push(new MiniCssExtractPlugin());<% } %> + <% if (workboxWebpackPlugin) { %>config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> } else { config.mode = "development"; } diff --git a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 index e931c415a9a..4a6b3c02774 100644 --- a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 +++ b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 @@ -13,10 +13,10 @@ exports[`create-webpack-app cli recognizes '-t' as an alias for '--template' and }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -36,10 +36,10 @@ exports[`create-webpack-app cli should ask question when wrong template is suppl }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -56,10 +56,10 @@ exports[`create-webpack-app cli should configure WDS as opted 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -72,13 +72,15 @@ exports[`create-webpack-app cli should configure WDS as opted 2`] = ` import path from "node:path"; import { fileURLToPath } from "node:url"; + + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -128,9 +130,9 @@ exports[`create-webpack-app cli should configure html-webpack-plugin as opted 1` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -142,6 +144,7 @@ exports[`create-webpack-app cli should configure html-webpack-plugin as opted 2` import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -150,7 +153,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -206,9 +209,9 @@ exports[`create-webpack-app cli should configure workbox-webpack-plugin as opted }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -220,6 +223,7 @@ exports[`create-webpack-app cli should configure workbox-webpack-plugin as opted import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -229,7 +233,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -264,9 +268,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -287,9 +289,9 @@ exports[`create-webpack-app cli should generate ES6 project correctly 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -302,13 +304,15 @@ exports[`create-webpack-app cli should generate ES6 project correctly 2`] = ` import path from "node:path"; import { fileURLToPath } from "node:url"; + + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -361,10 +365,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -376,6 +380,7 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -385,7 +390,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -423,9 +428,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -447,10 +450,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -462,6 +465,7 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -471,7 +475,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -509,9 +513,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -532,9 +534,9 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -546,6 +548,7 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -555,7 +558,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -593,9 +596,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -617,10 +618,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -632,6 +633,7 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -641,7 +643,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -679,9 +681,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -703,10 +703,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -718,6 +718,7 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; + import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -727,7 +728,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -765,9 +766,7 @@ export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -789,10 +788,10 @@ exports[`create-webpack-app cli should generate folders if non existing generati }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -812,10 +811,10 @@ exports[`create-webpack-app cli should generate project when generationPath is s }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -1077,15 +1076,16 @@ exports[`create-webpack-app cli should generate typescript project correctly 1`] "description": "My webpack project", "devDependencies": { "ts-loader": "x.x.x", + "ts-node": "x.x.x", "typescript": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --mode=production --config-node-env=production -c ./webpack.config.ts", + "build:dev": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --mode=development -c ./webpack.config.ts", + "watch": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --watch -c ./webpack.config.ts", }, "type": "module", "version": "1.0.0", @@ -1097,6 +1097,9 @@ exports[`create-webpack-app cli should generate typescript project correctly 2`] import path from "node:path"; import { fileURLToPath } from "node:url"; +import { Configuration } from "webpack"; + + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -1104,7 +1107,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config : Configuration = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "dist"), @@ -1291,9 +1294,9 @@ exports[`create-webpack-app cli should use css preprocessor and css with postcss }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -1305,6 +1308,8 @@ exports[`create-webpack-app cli should use css preprocessor and css with postcss import path from "node:path"; import { fileURLToPath } from "node:url"; + + import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -1315,9 +1320,8 @@ const isProduction = process.env.NODE_ENV === "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -1351,9 +1355,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - + config.plugins!.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; @@ -1380,9 +1382,9 @@ exports[`create-webpack-app cli should use to use css preprocessor with postcss }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -1394,6 +1396,8 @@ exports[`create-webpack-app cli should use to use css preprocessor with postcss import path from "node:path"; import { fileURLToPath } from "node:url"; + + import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -1404,9 +1408,8 @@ const isProduction = process.env.NODE_ENV === "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -1436,9 +1439,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - + config.plugins!.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; @@ -1461,10 +1462,10 @@ exports[`create-webpack-app cli should work with 'new' alias 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "serve": "webpack serve", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "serve": "webpack serve ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", @@ -1480,9 +1481,9 @@ exports[`create-webpack-app cli uses yarn as the package manager when opted 1`] }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production", - "build:dev": "webpack --mode=development", - "watch": "webpack --watch", + "build": "webpack --mode=production --config-node-env=production ", + "build:dev": "webpack --mode=development ", + "watch": "webpack --watch ", }, "type": "module", "version": "1.0.0", diff --git a/test/create-webpack-app/init/init.test.js b/test/create-webpack-app/init/init.test.js index 77711bcbfa1..c8b946ca5dd 100644 --- a/test/create-webpack-app/init/init.test.js +++ b/test/create-webpack-app/init/init.test.js @@ -58,8 +58,9 @@ const readFromPkgJSON = (path) => { return { ...pkgJSON, devDependencies: devDeps }; }; -// Helper to read from webpack.config.js in a given path -const readFromWebpackConfig = (path) => readFileSync(join(path, "webpack.config.js"), "utf8"); +// Helper to read from webpack.config.js or webpack.config.ts in a given path +const readFromWebpackConfig = (path, filename = "webpack.config.js") => + readFileSync(join(path, filename), "utf8"); describe("create-webpack-app cli", () => { let dir; @@ -277,14 +278,17 @@ describe("create-webpack-app cli", () => { ); expect(stdout).toContain("Project has been initialised with webpack!"); - expect(stdout).toContain("webpack.config.js"); + expect(stdout).toContain("webpack.config.ts"); expect(stdout).toContain("tsconfig.json"); // Test files const files = [ - ...defaultTemplateFiles.filter((file) => file !== "src/index.js"), + ...defaultTemplateFiles.filter( + (file) => file !== "src/index.js" && file !== "webpack.config.js", + ), "src/index.ts", "tsconfig.json", + "webpack.config.ts", ]; for (const file of files) { @@ -295,7 +299,7 @@ describe("create-webpack-app cli", () => { expect(readFromPkgJSON(dir)).toMatchSnapshot(); // Check if the generated webpack configuration matches the snapshot - expect(readFromWebpackConfig(dir)).toMatchSnapshot(); + expect(readFromWebpackConfig(dir, "webpack.config.ts")).toMatchSnapshot(); }); it("should generate ES6 project correctly", async () => { From 0fc6e9d2c1ad5918eee94e5f5320fae13a08f2ee Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 18:57:36 +0300 Subject: [PATCH 03/10] feat(typescript): delete unecessary loader & deps \n Node22 natively support typescript --- .../create-webpack-app/src/generators/init/default.ts | 2 +- .../templates/init/default/package.json.tpl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/create-webpack-app/src/generators/init/default.ts b/packages/create-webpack-app/src/generators/init/default.ts index 5b11838be7d..760e6f16d3c 100644 --- a/packages/create-webpack-app/src/generators/init/default.ts +++ b/packages/create-webpack-app/src/generators/init/default.ts @@ -105,7 +105,7 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { devDependencies.push("babel-loader", "@babel/core", "@babel/preset-env"); break; case "Typescript": - devDependencies.push("typescript", "ts-loader", "ts-node"); + devDependencies.push("typescript", "ts-loader"); break; } diff --git a/packages/create-webpack-app/templates/init/default/package.json.tpl b/packages/create-webpack-app/templates/init/default/package.json.tpl index 3e96af85ad4..625b0b17ccf 100644 --- a/packages/create-webpack-app/templates/init/default/package.json.tpl +++ b/packages/create-webpack-app/templates/init/default/package.json.tpl @@ -1,14 +1,14 @@ -<% const nodeOptions = langType === "Typescript" ? "NODE_OPTIONS='--loader ts-node/esm --no-warnings' " : ""; %>{ +{ "version": "1.0.0", "description": "My webpack project", "name": "webpack-project", "type": "module", "scripts": { - "build": "<%- nodeOptions %>webpack --mode=production --config-node-env=production <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", - "build:dev": "<%- nodeOptions %>webpack --mode=development <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", <% if (devServer) { %> - "serve": "<%- nodeOptions %>webpack serve <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>", + "serve": "webpack serve", <% } %> - "watch": "<%- nodeOptions %>webpack --watch <%- langType === 'Typescript' ? ' -c ./webpack.config.ts' : '' %>" + "watch": "webpack --watch" } } From 35458fb0e06f9d95b42d01fc24d32140f41981af Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 19:04:46 +0300 Subject: [PATCH 04/10] refactor: removed extra space & unecessary loaders --- .../templates/init/default/webpack.config.tpl | 2 +- .../__snapshots__/init.test.js.snap.webpack5 | 152 +++++++++--------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 8a36a6783f3..001cbef6fd3 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -20,7 +20,7 @@ const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config <% if (langType === "Typescript") { %>: Configuration<% } %> = { +const config <% if (langType === "Typescript") { %>: Configuration<% } %>= { entry: "<%= entryPoint %>", output: { path: path.resolve(__dirname, "dist"), diff --git a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 index 4a6b3c02774..0c1425375ca 100644 --- a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 +++ b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 @@ -13,10 +13,10 @@ exports[`create-webpack-app cli recognizes '-t' as an alias for '--template' and }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -36,10 +36,10 @@ exports[`create-webpack-app cli should ask question when wrong template is suppl }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -56,10 +56,10 @@ exports[`create-webpack-app cli should configure WDS as opted 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -80,7 +80,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -130,9 +130,9 @@ exports[`create-webpack-app cli should configure html-webpack-plugin as opted 1` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -153,7 +153,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -209,9 +209,9 @@ exports[`create-webpack-app cli should configure workbox-webpack-plugin as opted }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -233,7 +233,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -289,9 +289,9 @@ exports[`create-webpack-app cli should generate ES6 project correctly 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -312,7 +312,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -365,10 +365,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -390,7 +390,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -450,10 +450,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -475,7 +475,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -534,9 +534,9 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -558,7 +558,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -618,10 +618,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -643,7 +643,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -703,10 +703,10 @@ exports[`create-webpack-app cli should generate default project when nothing is }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -728,7 +728,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -788,10 +788,10 @@ exports[`create-webpack-app cli should generate folders if non existing generati }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -811,10 +811,10 @@ exports[`create-webpack-app cli should generate project when generationPath is s }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -1083,9 +1083,9 @@ exports[`create-webpack-app cli should generate typescript project correctly 1`] }, "name": "webpack-project", "scripts": { - "build": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --mode=production --config-node-env=production -c ./webpack.config.ts", - "build:dev": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --mode=development -c ./webpack.config.ts", - "watch": "NODE_OPTIONS='--loader ts-node/esm --no-warnings' webpack --watch -c ./webpack.config.ts", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -1107,7 +1107,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config : Configuration = { +const config : Configuration= { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "dist"), @@ -1294,9 +1294,9 @@ exports[`create-webpack-app cli should use css preprocessor and css with postcss }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -1321,7 +1321,7 @@ const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -1382,9 +1382,9 @@ exports[`create-webpack-app cli should use to use css preprocessor with postcss }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -1409,7 +1409,7 @@ const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader /** @type {import("webpack").Configuration} */ -const config = { +const config = { entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), @@ -1462,10 +1462,10 @@ exports[`create-webpack-app cli should work with 'new' alias 1`] = ` }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "serve": "webpack serve ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "serve": "webpack serve", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", @@ -1481,9 +1481,9 @@ exports[`create-webpack-app cli uses yarn as the package manager when opted 1`] }, "name": "webpack-project", "scripts": { - "build": "webpack --mode=production --config-node-env=production ", - "build:dev": "webpack --mode=development ", - "watch": "webpack --watch ", + "build": "webpack --mode=production --config-node-env=production", + "build:dev": "webpack --mode=development", + "watch": "webpack --watch", }, "type": "module", "version": "1.0.0", From 418f434e12f53a1f2a765f88689d99fb6c7bbf42 Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 21:39:38 +0300 Subject: [PATCH 05/10] refactor(init): update tests and format the template to remove extra line --- .../templates/init/default/webpack.config.tpl | 14 ++++---- .../__snapshots__/init.test.js.snap.webpack5 | 36 +------------------ 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 001cbef6fd3..10af26bc064 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -1,10 +1,10 @@ // Generated using webpack-cli https://github.com/webpack/webpack-cli import path from "node:path"; -import { fileURLToPath } from "node:url"; -<% if (langType === "Typescript") { %>import { Configuration } from "webpack"; -<% if (devServer) { %>import "webpack-dev-server";<% } %><% } %> -<% if (htmlWebpackPlugin) { %>import HtmlWebpackPlugin from "html-webpack-plugin";<% } %><% if (extractPlugin !== "No") { %> +import { fileURLToPath } from "node:url";<% if (langType === "Typescript") { %> +import { Configuration } from "webpack";<% if (devServer) { %> +import "webpack-dev-server";<% } %><% } %><% if (htmlWebpackPlugin) { %> +import HtmlWebpackPlugin from "html-webpack-plugin";<% } %><% if (extractPlugin !== "No") { %> import MiniCssExtractPlugin from "mini-css-extract-plugin";<% } %><% if (workboxWebpackPlugin) { %> import WorkboxWebpackPlugin from "workbox-webpack-plugin";<% } %> @@ -90,9 +90,9 @@ const config <% if (langType === "Typescript") { %>: Configuration<% } %>= { export default () => { if (isProduction) { - config.mode = "production"; - <% if (extractPlugin === "Only for Production") { %>config.plugins!.push(new MiniCssExtractPlugin());<% } %> - <% if (workboxWebpackPlugin) { %>config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> + config.mode = "production";<% if (extractPlugin === "Only for Production") { %> + config.plugins!.push(new MiniCssExtractPlugin());<% } %><% if (workboxWebpackPlugin) { %> + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> } else { config.mode = "development"; } diff --git a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 index 0c1425375ca..baa2f45c665 100644 --- a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 +++ b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 @@ -72,8 +72,6 @@ exports[`create-webpack-app cli should configure WDS as opted 2`] = ` import path from "node:path"; import { fileURLToPath } from "node:url"; - - const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; @@ -109,8 +107,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -144,7 +140,6 @@ exports[`create-webpack-app cli should configure html-webpack-plugin as opted 2` import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -187,8 +182,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -223,7 +216,6 @@ exports[`create-webpack-app cli should configure workbox-webpack-plugin as opted import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -267,7 +259,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -304,8 +295,6 @@ exports[`create-webpack-app cli should generate ES6 project correctly 2`] = ` import path from "node:path"; import { fileURLToPath } from "node:url"; - - const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; @@ -342,8 +331,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -380,7 +367,6 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -427,7 +413,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -465,7 +450,6 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -512,7 +496,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -548,7 +531,6 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -595,7 +577,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -633,7 +614,6 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -680,7 +660,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -718,7 +697,6 @@ exports[`create-webpack-app cli should generate default project when nothing is import path from "node:path"; import { fileURLToPath } from "node:url"; - import HtmlWebpackPlugin from "html-webpack-plugin"; import WorkboxWebpackPlugin from "workbox-webpack-plugin"; @@ -765,7 +743,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1076,7 +1053,6 @@ exports[`create-webpack-app cli should generate typescript project correctly 1`] "description": "My webpack project", "devDependencies": { "ts-loader": "x.x.x", - "ts-node": "x.x.x", "typescript": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", @@ -1097,9 +1073,7 @@ exports[`create-webpack-app cli should generate typescript project correctly 2`] import path from "node:path"; import { fileURLToPath } from "node:url"; -import { Configuration } from "webpack"; - - +import { Configuration } from "webpack"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -1141,8 +1115,6 @@ const config : Configuration= { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -1308,8 +1280,6 @@ exports[`create-webpack-app cli should use css preprocessor and css with postcss import path from "node:path"; import { fileURLToPath } from "node:url"; - - import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -1356,7 +1326,6 @@ export default () => { if (isProduction) { config.mode = "production"; config.plugins!.push(new MiniCssExtractPlugin()); - } else { config.mode = "development"; } @@ -1396,8 +1365,6 @@ exports[`create-webpack-app cli should use to use css preprocessor with postcss import path from "node:path"; import { fileURLToPath } from "node:url"; - - import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); @@ -1440,7 +1407,6 @@ export default () => { if (isProduction) { config.mode = "production"; config.plugins!.push(new MiniCssExtractPlugin()); - } else { config.mode = "development"; } From 76d1ea91b6ae8fd89290226d941a8082ed42a9af Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 22:35:52 +0300 Subject: [PATCH 06/10] refactor: update typescript config --- .../templates/init/default/tsconfig.json.tpl | 8 +++++--- .../templates/init/default/webpack.config.tpl | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl index a024736bfe4..b7eb3211621 100644 --- a/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl +++ b/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl @@ -1,16 +1,18 @@ { "compilerOptions": { "allowSyntheticDefaultImports": true, - "noImplicitAny": true, + "strict": true, "module": "esnext", "moduleResolution": "bundler", "target": "esnext", "allowJs": true, "esModuleInterop": true, "resolveJsonModule": true, + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, "isolatedModules": true, "rewriteRelativeImportExtensions": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["./src/**/*"], + "exclude": ["./node_modules"] } diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 10af26bc064..3c5d8b2003b 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -2,7 +2,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url";<% if (langType === "Typescript") { %> -import { Configuration } from "webpack";<% if (devServer) { %> +import { type Configuration } from "webpack";<% if (devServer) { %> import "webpack-dev-server";<% } %><% } %><% if (htmlWebpackPlugin) { %> import HtmlWebpackPlugin from "html-webpack-plugin";<% } %><% if (extractPlugin !== "No") { %> import MiniCssExtractPlugin from "mini-css-extract-plugin";<% } %><% if (workboxWebpackPlugin) { %> From 2d340e43cafd97bcd1b55b4de4511de58efe18ae Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 23:13:59 +0300 Subject: [PATCH 07/10] test(init): updated snapshsot --- .../init/__snapshots__/init.test.js.snap.webpack5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 index baa2f45c665..302abfa52d3 100644 --- a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 +++ b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 @@ -1073,7 +1073,7 @@ exports[`create-webpack-app cli should generate typescript project correctly 2`] import path from "node:path"; import { fileURLToPath } from "node:url"; -import { Configuration } from "webpack"; +import { type Configuration } from "webpack"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); From 72edc3d9b0aac6cbd49a7bdd8ab20cd54205f0f4 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:33:11 +0300 Subject: [PATCH 08/10] Create rude-ads-raise.md --- .changeset/rude-ads-raise.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-ads-raise.md diff --git a/.changeset/rude-ads-raise.md b/.changeset/rude-ads-raise.md new file mode 100644 index 00000000000..906977e805a --- /dev/null +++ b/.changeset/rude-ads-raise.md @@ -0,0 +1,5 @@ +--- +"create-webpack-app": patch +--- + +Generate `webpack.config.ts` instead of `webpack.config.js` when TypeScript is selected. From 215cd4fcf13a62f13f5697bd71757e5cba0d8a1c Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Tue, 7 Apr 2026 23:54:34 +0300 Subject: [PATCH 09/10] style: add a single space --- .../templates/init/default/webpack.config.tpl | 2 +- .../init/__snapshots__/init.test.js.snap.webpack5 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 3c5d8b2003b..5df1604949a 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -20,7 +20,7 @@ const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config <% if (langType === "Typescript") { %>: Configuration<% } %>= { +const config <% if (langType === "Typescript") { %>: Configuration<% } %> = { entry: "<%= entryPoint %>", output: { path: path.resolve(__dirname, "dist"), diff --git a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 index 302abfa52d3..82dc02fa6f7 100644 --- a/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 +++ b/test/create-webpack-app/init/__snapshots__/init.test.js.snap.webpack5 @@ -1081,7 +1081,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ -const config : Configuration= { +const config : Configuration = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "dist"), From 57f8de264a3b8835d438399b22752aa3e3c4e3d5 Mon Sep 17 00:00:00 2001 From: ThierryRakotomanana Date: Wed, 8 Apr 2026 01:07:16 +0300 Subject: [PATCH 10/10] test: update snapshot --- .../templates/init/default/webpack.config.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-webpack-app/templates/init/default/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 5df1604949a..7eaed3b1263 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -20,7 +20,7 @@ const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config <% if (langType === "Typescript") { %>: Configuration<% } %> = { +const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { entry: "<%= entryPoint %>", output: { path: path.resolve(__dirname, "dist"),