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. diff --git a/packages/create-webpack-app/src/generators/init/default.ts b/packages/create-webpack-app/src/generators/init/default.ts index 15d019bbff3..760e6f16d3c 100644 --- a/packages/create-webpack-app/src/generators/init/default.ts +++ b/packages/create-webpack-app/src/generators/init/default.ts @@ -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" }, ]; @@ -186,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/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/default/tsconfig.json.tpl index 31176e658c2..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,10 +1,18 @@ { "compilerOptions": { "allowSyntheticDefaultImports": true, - "noImplicitAny": true, - "module": "es6", - "target": "es5", - "allowJs": true + "strict": true, + "module": "esnext", + "moduleResolution": "bundler", + "target": "esnext", + "allowJs": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": 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 84% 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..7eaed3b1263 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,7 +1,9 @@ // Generated using webpack-cli https://github.com/webpack/webpack-cli import path from "node:path"; -import { fileURLToPath } from "node:url";<% if (htmlWebpackPlugin) { %> +import { fileURLToPath } from "node:url";<% if (langType === "Typescript") { %> +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) { %> 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"), @@ -90,13 +90,9 @@ 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()); - <% } %> + 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 e931c415a9a..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 @@ -107,8 +107,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -184,8 +182,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -263,10 +259,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -338,8 +331,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -422,10 +413,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -508,10 +496,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -592,10 +577,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -678,10 +660,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -764,10 +743,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins!.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -1097,6 +1073,7 @@ exports[`create-webpack-app cli should generate typescript project correctly 2`] import path from "node:path"; import { fileURLToPath } from "node:url"; +import { type Configuration } from "webpack"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -1104,7 +1081,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"), @@ -1138,8 +1115,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - } else { config.mode = "development"; } @@ -1315,7 +1290,6 @@ const isProduction = process.env.NODE_ENV === "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -1351,10 +1325,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - - + config.plugins!.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } @@ -1404,7 +1375,6 @@ const isProduction = process.env.NODE_ENV === "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -1436,10 +1406,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - - + config.plugins!.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } 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 () => {