diff --git a/packages/create-webpack-app/src/generators/init/react.ts b/packages/create-webpack-app/src/generators/init/react.ts index 8b7db38a606..188139d3270 100644 --- a/packages/create-webpack-app/src/generators/init/react.ts +++ b/packages/create-webpack-app/src/generators/init/react.ts @@ -151,7 +151,10 @@ export default async function reactInitGenerator(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" }, { filePath: "./src/assets/webpack.png", fileType: "binary" }, @@ -206,7 +209,9 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { templateFile: join( plop.getPlopfilePath(), "../templates/init/react", - `${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/src/generators/init/svelte.ts b/packages/create-webpack-app/src/generators/init/svelte.ts index f81ff031329..08c6403efff 100644 --- a/packages/create-webpack-app/src/generators/init/svelte.ts +++ b/packages/create-webpack-app/src/generators/init/svelte.ts @@ -143,7 +143,10 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, { filePath: "./src/assets/webpack.png", fileType: "binary" }, - { 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" }, { filePath: "./src/components/HelloWorld.svelte", fileType: "text" }, @@ -193,7 +196,9 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { templateFile: join( plop.getPlopfilePath(), "../templates/init/svelte", - `${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/src/generators/init/vue.ts b/packages/create-webpack-app/src/generators/init/vue.ts index 793e5889a82..fe105558cfc 100644 --- a/packages/create-webpack-app/src/generators/init/vue.ts +++ b/packages/create-webpack-app/src/generators/init/vue.ts @@ -155,7 +155,10 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, { filePath: "./src/assets/webpack.png", fileType: "binary" }, - { 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" }, { filePath: "./src/App.vue", fileType: "text" }, @@ -215,7 +218,9 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { templateFile: join( plop.getPlopfilePath(), "../templates/init/vue", - `${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/webpack.config.tpl b/packages/create-webpack-app/templates/init/default/webpack.config.tpl index 7eaed3b1263..a4da1add247 100644 --- a/packages/create-webpack-app/templates/init/default/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/default/webpack.config.tpl @@ -10,13 +10,9 @@ import WorkboxWebpackPlugin from "workbox-webpack-plugin";<% } %> const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const isProduction = process.env.NODE_ENV === "production"; -<% if (cssType !== "none") { %> -<% if (extractPlugin === "Yes") { %> -const stylesHandler = MiniCssExtractPlugin.loader; -<% } else if (extractPlugin === "Only for Production") { %> -const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; -<% } else { %> +const isProduction = process.env.NODE_ENV === "production";<% if (cssType !== "none") { %><% if (extractPlugin === "Yes") { %> +const stylesHandler = MiniCssExtractPlugin.loader;<% } else if (extractPlugin === "Only for Production") { %> +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader";<% } else { %> const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ @@ -31,10 +27,8 @@ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { plugins: [<% if (htmlWebpackPlugin) { %> new HtmlWebpackPlugin({ template: "index.html", - }), -<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(), -<% } %> + }),<% } %><% if (extractPlugin === "Yes") { %> + new MiniCssExtractPlugin(),<% } %> // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -91,8 +85,8 @@ 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.plugins?.push(new MiniCssExtractPlugin());<% } %><% if (workboxWebpackPlugin) { %> + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> } else { config.mode = "development"; } diff --git a/packages/create-webpack-app/templates/init/react/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/react/tsconfig.json.tpl index 37b8169e222..9972c80205c 100644 --- a/packages/create-webpack-app/templates/init/react/tsconfig.json.tpl +++ b/packages/create-webpack-app/templates/init/react/tsconfig.json.tpl @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "esnext", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, @@ -10,11 +10,14 @@ "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, + "rewriteRelativeImportExtensions": true, }, "include": ["src/**/*", "index.d.ts"], "exclude": ["node_modules", "dist"] -} +} \ No newline at end of file diff --git a/packages/create-webpack-app/templates/init/react/webpack.config.js.tpl b/packages/create-webpack-app/templates/init/react/webpack.config.tpl similarity index 76% rename from packages/create-webpack-app/templates/init/react/webpack.config.js.tpl rename to packages/create-webpack-app/templates/init/react/webpack.config.tpl index cf6ce755bf9..4176f8df107 100644 --- a/packages/create-webpack-app/templates/init/react/webpack.config.js.tpl +++ b/packages/create-webpack-app/templates/init/react/webpack.config.tpl @@ -1,26 +1,22 @@ // 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";<% } %> const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const isProduction = process.env.NODE_ENV === "production"; -<% if (cssType !== "none") { %> -<% if (extractPlugin === "Yes") { %> -const stylesHandler = MiniCssExtractPlugin.loader; -<% } else if (extractPlugin === "Only for Production") { %> -const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; -<% } else { %> -const stylesHandler = "style-loader"; -<% } %> -<% } %> +const isProduction = process.env.NODE_ENV === "production";<% if (cssType !== "none") { %><% if (extractPlugin === "Yes") { %> +const stylesHandler = MiniCssExtractPlugin.loader;<% } else if (extractPlugin === "Only for Production") { %> +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader";<% } else { %> +const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config = { +const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { entry: "<%= entry %>", output: { path: path.resolve(__dirname, "dist"), @@ -31,10 +27,8 @@ const config = { plugins: [<% if (htmlWebpackPlugin) { %> new HtmlWebpackPlugin({ template: "index.html", - }), -<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(), -<% } %> + }),<% } %><% if (extractPlugin === "Yes") { %> + new MiniCssExtractPlugin(),<% } %> // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -94,13 +88,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/packages/create-webpack-app/templates/init/svelte/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/svelte/tsconfig.json.tpl index 40932dd52a0..4570ccf6e5d 100644 --- a/packages/create-webpack-app/templates/init/svelte/tsconfig.json.tpl +++ b/packages/create-webpack-app/templates/init/svelte/tsconfig.json.tpl @@ -1,14 +1,19 @@ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { - "target": "es5", - "module": "es6", + "target": "esnext", + "module": "esnext", "strict": true, - "moduleResolution": "node", + "moduleResolution": "bundler", + "jsx": "preserve", "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, + "isolatedModules": true, + "rewriteRelativeImportExtensions": true, }, "include": [ "src/**/*.ts", diff --git a/packages/create-webpack-app/templates/init/svelte/webpack.config.js.tpl b/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl similarity index 78% rename from packages/create-webpack-app/templates/init/svelte/webpack.config.js.tpl rename to packages/create-webpack-app/templates/init/svelte/webpack.config.tpl index 86bd7bdecbe..cc010d7d97c 100644 --- a/packages/create-webpack-app/templates/init/svelte/webpack.config.js.tpl +++ b/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl @@ -1,26 +1,22 @@ // 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";<% } %> const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const isProduction = process.env.NODE_ENV === "production"; -<% if (cssType !== "none") { %> -<% if (extractPlugin === "Yes") { %> -const stylesHandler = MiniCssExtractPlugin.loader; -<% } else if (extractPlugin === "Only for Production") { %> -const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; -<% } else { %> -const stylesHandler = "style-loader"; -<% } %> -<% } %> +const isProduction = process.env.NODE_ENV === "production";<% if (cssType !== "none") { %><% if (extractPlugin === "Yes") { %> +const stylesHandler = MiniCssExtractPlugin.loader;<% } else if (extractPlugin === "Only for Production") { %> +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader";<% } else { %> +const stylesHandler = "style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config = { +const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { entry: "<%= entry %>", output: { path: path.resolve(__dirname, "dist"), @@ -31,10 +27,8 @@ const config = { plugins: [<% if (htmlWebpackPlugin) { %> new HtmlWebpackPlugin({ template: "./index.html", - }), -<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(), -<% } %> + }),<% } %><% if (extractPlugin === "Yes") { %> + new MiniCssExtractPlugin(),<% } %> // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -108,13 +102,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/packages/create-webpack-app/templates/init/vue/tsconfig.json.tpl b/packages/create-webpack-app/templates/init/vue/tsconfig.json.tpl index 5a61545c28b..7730063adac 100644 --- a/packages/create-webpack-app/templates/init/vue/tsconfig.json.tpl +++ b/packages/create-webpack-app/templates/init/vue/tsconfig.json.tpl @@ -1,15 +1,19 @@ { "compilerOptions": { - "target": "es5", - "module": "es6", + "target": "esnext", + "module": "esnext", "strict": true, "jsx": "preserve", - "moduleResolution": "node", + "jsxImportSource": "vue", + "moduleResolution": "bundler", "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, - "baseUrl": ".", + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, + "isolatedModules": true, + "rewriteRelativeImportExtensions": true, "types": [ "webpack-env", "vue-router" @@ -22,6 +26,7 @@ "lib": [ "esnext", "dom", + "dom.iterable", ] }, "include": [ diff --git a/packages/create-webpack-app/templates/init/vue/webpack.config.js.tpl b/packages/create-webpack-app/templates/init/vue/webpack.config.tpl similarity index 77% rename from packages/create-webpack-app/templates/init/vue/webpack.config.js.tpl rename to packages/create-webpack-app/templates/init/vue/webpack.config.tpl index d4cdf176634..4be7e433154 100644 --- a/packages/create-webpack-app/templates/init/vue/webpack.config.js.tpl +++ b/packages/create-webpack-app/templates/init/vue/webpack.config.tpl @@ -2,26 +2,22 @@ import { VueLoaderPlugin } from "vue-loader"; 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";<% } %> const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const isProduction = process.env.NODE_ENV === "production"; -<% if (cssType !== "none") { %> -<% if (extractPlugin === "Yes") { %> -const stylesHandler = MiniCssExtractPlugin.loader; -<% } else if (extractPlugin === "Only for Production") { %> -const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader"; -<% } else { %> -const stylesHandler = "vue-style-loader"; -<% } %> -<% } %> +const isProduction = process.env.NODE_ENV === "production";<% if (cssType !== "none") { %><% if (extractPlugin === "Yes") { %> +const stylesHandler = MiniCssExtractPlugin.loader;<% } else if (extractPlugin === "Only for Production") { %> +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader";<% } else { %> +const stylesHandler = "vue-style-loader";<% } %><% } %> /** @type {import("webpack").Configuration} */ -const config = { +const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { entry: "<%= entry %>", output: { path: path.resolve(__dirname, "dist"), @@ -33,10 +29,8 @@ const config = { new VueLoaderPlugin(),<% if (htmlWebpackPlugin) { %> new HtmlWebpackPlugin({ template: "index.html", - }), -<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(), -<% } %> + }),<% } %><% if (extractPlugin === "Yes") { %> + new MiniCssExtractPlugin(),<% } %> // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -103,13 +97,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 82dc02fa6f7..94c723a4fac 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 @@ -76,7 +76,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -146,7 +145,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -157,7 +155,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -223,7 +220,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -234,7 +230,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -259,7 +254,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"; } @@ -299,7 +294,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -374,7 +368,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -388,7 +381,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -413,7 +405,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"; } @@ -457,7 +449,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -471,7 +462,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -496,7 +486,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"; } @@ -538,7 +528,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -552,7 +541,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -577,7 +565,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"; } @@ -621,7 +609,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -635,7 +622,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -660,7 +646,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"; } @@ -704,7 +690,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -718,7 +703,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -743,7 +727,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"; } @@ -846,12 +830,8 @@ import WorkboxWebpackPlugin from "workbox-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - - const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.jsx", @@ -865,7 +845,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -905,12 +884,117 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); + } else { + config.mode = "development"; + } + return config; +}; +" +`; + +exports[`create-webpack-app cli should generate react template with typescript 1`] = ` +{ + "description": "My webpack project", + "devDependencies": { + "@types/react": "x.x.x", + "@types/react-dom": "x.x.x", + "@types/react-router-dom": "x.x.x", + "autoprefixer": "x.x.x", + "css-loader": "x.x.x", + "html-webpack-plugin": "x.x.x", + "mini-css-extract-plugin": "x.x.x", + "postcss": "x.x.x", + "postcss-loader": "x.x.x", + "react": "x.x.x", + "react-dom": "x.x.x", + "react-router-dom": "x.x.x", + "style-loader": "x.x.x", + "ts-loader": "x.x.x", + "typescript": "x.x.x", + "webpack": "x.x.x", + "webpack-cli": "x.x.x", + "webpack-dev-server": "x.x.x", + "workbox-webpack-plugin": "x.x.x", + }, + "name": "my-webpack-project", + "scripts": { + "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", +} +`; + +exports[`create-webpack-app cli should generate react template with typescript 2`] = ` +"// Generated using webpack-cli https://github.com/webpack/webpack-cli + +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { type Configuration } from "webpack"; +import "webpack-dev-server"; +import HtmlWebpackPlugin from "html-webpack-plugin"; +import MiniCssExtractPlugin from "mini-css-extract-plugin"; +import WorkboxWebpackPlugin from "workbox-webpack-plugin"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const isProduction = process.env.NODE_ENV === "production"; +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; + +/** @type {import("webpack").Configuration} */ +const config : Configuration = { + entry: "./src/index.tsx", + output: { + path: path.resolve(__dirname, "dist"), + }, + devServer: { + open: true, + }, + plugins: [ + new HtmlWebpackPlugin({ + template: "index.html", + }), + // Add your plugins here + // Learn more about plugins from https://webpack.js.org/configuration/plugins/ + ], + module: { + rules: [ + { + test: /\\.(ts|tsx)$/i, + loader: "ts-loader", + exclude: ["/node_modules/"], + }, + { + test: /\\.css$/i, + use: [stylesHandler, "css-loader", "postcss-loader"], + }, + { + test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, + type: "asset", + }, + + // Add your rules for custom modules here + // Learn more about loaders from https://webpack.js.org/loaders/ + ], + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "./src/"), + }, + extensions: [".jsx", ".js", ".tsx", ".ts"], + }, +}; + +export default () => { + if (isProduction) { + config.mode = "production"; + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -964,12 +1048,8 @@ import WorkboxWebpackPlugin from "workbox-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - - const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/main.js", @@ -983,7 +1063,6 @@ const config = { new HtmlWebpackPlugin({ template: "./index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1034,12 +1113,128 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); + } else { + config.mode = "development"; + } + return config; +}; +" +`; + +exports[`create-webpack-app cli should generate svelte template with typescript 1`] = ` +{ + "description": "My webpack project", + "devDependencies": { + "@tsconfig/svelte": "x.x.x", + "autoprefixer": "x.x.x", + "css-loader": "x.x.x", + "html-webpack-plugin": "x.x.x", + "mini-css-extract-plugin": "x.x.x", + "postcss": "x.x.x", + "postcss-loader": "x.x.x", + "style-loader": "x.x.x", + "svelte": "x.x.x", + "svelte-loader": "x.x.x", + "ts-loader": "x.x.x", + "typescript": "x.x.x", + "webpack": "x.x.x", + "webpack-cli": "x.x.x", + "webpack-dev-server": "x.x.x", + "workbox-webpack-plugin": "x.x.x", + }, + "name": "my-webpack-project", + "scripts": { + "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", +} +`; + +exports[`create-webpack-app cli should generate svelte template with typescript 2`] = ` +"// Generated using webpack-cli https://github.com/webpack/webpack-cli + +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { type Configuration } from "webpack"; +import "webpack-dev-server"; +import HtmlWebpackPlugin from "html-webpack-plugin"; +import MiniCssExtractPlugin from "mini-css-extract-plugin"; +import WorkboxWebpackPlugin from "workbox-webpack-plugin"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const isProduction = process.env.NODE_ENV === "production"; +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; + +/** @type {import("webpack").Configuration} */ +const config : Configuration = { + entry: "./src/main.ts", + output: { + path: path.resolve(__dirname, "dist"), + }, + devServer: { + open: true, + }, + plugins: [ + new HtmlWebpackPlugin({ + template: "./index.html", + }), + // Add your plugins here + // Learn more about plugins from https://webpack.js.org/configuration/plugins/ + ], + module: { + rules: [ + { + test: /\\.svelte$/, + use: { + loader: "svelte-loader", + options: { + emitCss: true, + hotReload: true + } + } + }, + { + test: /\\.ts$/, + loader: "ts-loader", + exclude: /node_modules/, + options: { + appendTsSuffixTo: [/\\.svelte$/], + }, + }, + { + test: /\\.css$/i, + use: [stylesHandler, "css-loader", "postcss-loader"], + }, + { + test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, + type: "asset", + }, + // Add your rules for custom modules here + // Learn more about loaders from https://webpack.js.org/loaders/ + ], + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "./src/"), + }, + extensions: [".mjs", ".js", ".svelte", ".ts"], + mainFields: ["svelte", "browser", "module", "main"], + conditionNames: ["svelte", "module", "browser", "main", "default"] + }, +}; + +export default () => { + if (isProduction) { + config.mode = "production"; + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -1079,7 +1274,6 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - /** @type {import("webpack").Configuration} */ const config : Configuration = { entry: "./src/index.ts", @@ -1173,12 +1367,8 @@ import WorkboxWebpackPlugin from "workbox-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - - const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader"; - - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/main.js", @@ -1193,7 +1383,6 @@ const config = { new HtmlWebpackPlugin({ template: "index.html", }), - // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1235,12 +1424,126 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - - config.plugins.push(new MiniCssExtractPlugin()); - - - config.plugins.push(new WorkboxWebpackPlugin.GenerateSW()); - + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); + } else { + config.mode = "development"; + } + return config; +}; +" +`; + +exports[`create-webpack-app cli should generate vue template with typescript 1`] = ` +{ + "description": "My webpack project", + "devDependencies": { + "@vue/compiler-sfc": "x.x.x", + "autoprefixer": "x.x.x", + "css-loader": "x.x.x", + "html-webpack-plugin": "x.x.x", + "mini-css-extract-plugin": "x.x.x", + "pinia": "x.x.x", + "postcss": "x.x.x", + "postcss-loader": "x.x.x", + "style-loader": "x.x.x", + "ts-loader": "x.x.x", + "typescript": "x.x.x", + "vue": "x.x.x", + "vue-loader": "x.x.x", + "vue-router": "x.x.x", + "vue-style-loader": "x.x.x", + "webpack": "x.x.x", + "webpack-cli": "x.x.x", + "webpack-dev-server": "x.x.x", + "workbox-webpack-plugin": "x.x.x", + }, + "name": "my-webpack-project", + "scripts": { + "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", +} +`; + +exports[`create-webpack-app cli should generate vue template with typescript 2`] = ` +"// Generated using webpack-cli https://github.com/webpack/webpack-cli + +import { VueLoaderPlugin } from "vue-loader"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { type Configuration } from "webpack"; +import "webpack-dev-server"; +import HtmlWebpackPlugin from "html-webpack-plugin"; +import MiniCssExtractPlugin from "mini-css-extract-plugin"; +import WorkboxWebpackPlugin from "workbox-webpack-plugin"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const isProduction = process.env.NODE_ENV === "production"; +const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader"; + +/** @type {import("webpack").Configuration} */ +const config : Configuration = { + entry: "./src/main.ts", + output: { + path: path.resolve(__dirname, "dist"), + }, + devServer: { + open: true, + }, + plugins: [ + new VueLoaderPlugin(), + new HtmlWebpackPlugin({ + template: "index.html", + }), + // Add your plugins here + // Learn more about plugins from https://webpack.js.org/configuration/plugins/ + ], + module: { + rules: [ + { + test: /\\.vue$/, + loader: "vue-loader" + }, + { + test: /\\.(ts|tsx)$/i, + loader: "ts-loader", + options: { + appendTsSuffixTo: [/\\.vue$/], + transpileOnly: true, + }, + exclude: ["/node_modules/"], + }, + { + test: /\\.css$/i, + use: [stylesHandler, "css-loader", "postcss-loader"], + }, + { + test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, + type: "asset", + }, + // Add your rules for custom modules here + // Learn more about loaders from https://webpack.js.org/loaders/ + ], + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "./src/") + }, + extensions: [".tsx", ".ts", ".js", ".vue", ".json"], + }, +}; + +export default () => { + if (isProduction) { + config.mode = "production"; + config.plugins?.push(new MiniCssExtractPlugin()); + config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; } @@ -1285,11 +1588,8 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - - const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -1325,7 +1625,7 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins!.push(new MiniCssExtractPlugin()); + config.plugins?.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } @@ -1370,11 +1670,8 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const isProduction = process.env.NODE_ENV === "production"; - - const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; - /** @type {import("webpack").Configuration} */ const config = { entry: "./src/index.js", @@ -1406,7 +1703,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 c8b946ca5dd..1a59d4a1e0d 100644 --- a/test/create-webpack-app/init/init.test.js +++ b/test/create-webpack-app/init/init.test.js @@ -40,6 +40,31 @@ const svelteTemplateFiles = [ "src/store/index.js", ]; +const reactTypescriptTemplateFiles = [ + ...defaultTemplateFiles.slice(0, 3), + "src/index.tsx", + ...defaultTemplateFiles.slice(4).filter((file) => file !== "webpack.config.js"), + "webpack.config.ts", + "tsconfig.json", +]; + +const vueTypescriptTemplateFiles = [ + ...defaultTemplateFiles.slice(0, 3), + "src/main.ts", + ...defaultTemplateFiles.slice(4).filter((file) => file !== "webpack.config.js"), + "webpack.config.ts", + "tsconfig.json", +]; + +const svelteTypescriptTemplateFiles = [ + ...defaultTemplateFiles.slice(0, 3), + "src/main.ts", + ...defaultTemplateFiles.slice(4).filter((file) => file !== "webpack.config.js"), + "webpack.config.ts", + "tsconfig.json", + "src/store/index.ts", +]; + // helper function to resolve the path from the test directory to actual assets // Helper to read from package.json in a given path const readFromPkgJSON = (path) => { @@ -508,6 +533,24 @@ describe("create-webpack-app cli", () => { expect(readFromWebpackConfig(dir)).toMatchSnapshot(); }); + it("should generate react template with typescript", async () => { + const { stdout } = await runPromptWithAnswers( + dir, + ["init", ".", "--template=react"], + [`${DOWN}${ENTER}`, `y${ENTER}`, `y${ENTER}`, ENTER, `y${ENTER}`, ENTER, ENTER, ENTER], + ); + + expect(stdout).toContain("Project has been initialised with webpack!"); + expect(stdout).toContain("webpack.config.ts"); + + for (const file of reactTypescriptTemplateFiles) { + expect(existsSync(resolve(dir, file))).toBeTruthy(); + } + + expect(readFromPkgJSON(dir)).toMatchSnapshot(); + expect(readFromWebpackConfig(dir, "webpack.config.ts")).toMatchSnapshot(); + }); + it("should generate vue template with store and router support on prompt answers", async () => { const { stdout } = await runPromptWithAnswers( dir, @@ -532,6 +575,24 @@ describe("create-webpack-app cli", () => { expect(readFromWebpackConfig(dir)).toMatchSnapshot(); }); + it("should generate vue template with typescript", async () => { + const { stdout } = await runPromptWithAnswers( + dir, + ["init", ".", "--template=vue"], + [`${DOWN}${ENTER}`, `y${ENTER}`, `y${ENTER}`, `${ENTER}`, `y${ENTER}`, ENTER, ENTER], + ); + + expect(stdout).toContain("Project has been initialised with webpack!"); + expect(stdout).toContain("webpack.config.ts"); + + for (const file of vueTypescriptTemplateFiles) { + expect(existsSync(resolve(dir, file))).toBeTruthy(); + } + + expect(readFromPkgJSON(dir)).toMatchSnapshot(); + expect(readFromWebpackConfig(dir, "webpack.config.ts")).toMatchSnapshot(); + }); + it("should generate svelte template with prompt answers", async () => { const { stdout } = await runPromptWithAnswers( dir, @@ -553,4 +614,22 @@ describe("create-webpack-app cli", () => { // Check if the generated webpack configuration matches the snapshot expect(readFromWebpackConfig(dir)).toMatchSnapshot(); }); + + it("should generate svelte template with typescript", async () => { + const { stdout } = await runPromptWithAnswers( + dir, + ["init", ".", "--template=svelte"], + [`${DOWN}${ENTER}`, `y${ENTER}`, ENTER, `y${ENTER}`, ENTER, ENTER], + ); + + expect(stdout).toContain("Project has been initialised with webpack!"); + expect(stdout).toContain("webpack.config.ts"); + + for (const file of svelteTypescriptTemplateFiles) { + expect(existsSync(resolve(dir, file))).toBeTruthy(); + } + + expect(readFromPkgJSON(dir)).toMatchSnapshot(); + expect(readFromWebpackConfig(dir, "webpack.config.ts")).toMatchSnapshot(); + }); });