From 3af8da49a27aceebb67320f69989fdecf035226e Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 22 Aug 2026 14:12:12 -0500 Subject: [PATCH] feat(create-webpack-app): use webpack's native CSS and HTML support in init templates Replace css-loader, style-loader, vue-style-loader and mini-css-extract-plugin with `experiments.css`, and html-webpack-plugin and html-loader with `experiments.html`, where `index.html` becomes the entry point. Both experiments default to "auto" since webpack 5.109, so the templates only declare them when the auto detection would turn them off: a PostCSS rule for `.css` files, and the Vue template, where VueLoaderPlugin clones every non-vue rule with a catch-all `resource: () => true` matcher before webpack resolves the defaults, which makes the auto detection see a loader for `.css` and `.html`. The Vue template also needs `experimentalInlineMatchResource` in vue-loader, required with `experiments.css`. The "Do you want to extract CSS into separate files?" prompt is gone, native CSS always emits separate files, and the `htmlWebpackPlugin` answer is now `html`. --- .changeset/native-css-templates.md | 5 + .../src/generators/init/default.ts | 22 +- .../src/generators/init/react.ts | 16 +- .../src/generators/init/svelte.ts | 17 +- .../src/generators/init/vue.ts | 17 +- packages/create-webpack-app/src/index.ts | 3 +- .../templates/init/default/index.html.tpl | 3 +- .../templates/init/default/webpack.config.tpl | 46 ++- .../templates/init/react/index.html.tpl | 1 + .../templates/init/react/webpack.config.tpl | 41 ++- .../templates/init/svelte/index.html.tpl | 2 +- .../templates/init/svelte/webpack.config.tpl | 41 ++- .../templates/init/vue/index.html.tpl | 2 +- .../templates/init/vue/webpack.config.tpl | 47 ++- .../__snapshots__/init.test.js.snap.webpack5 | 268 +++++------------- test/create-webpack-app/init/init.test.js | 4 +- 16 files changed, 158 insertions(+), 377 deletions(-) create mode 100644 .changeset/native-css-templates.md diff --git a/.changeset/native-css-templates.md b/.changeset/native-css-templates.md new file mode 100644 index 00000000000..e52cd4059d5 --- /dev/null +++ b/.changeset/native-css-templates.md @@ -0,0 +1,5 @@ +--- +"create-webpack-app": minor +--- + +feat: use webpack's native CSS and HTML support in the `init` templates diff --git a/packages/create-webpack-app/src/generators/init/default.ts b/packages/create-webpack-app/src/generators/init/default.ts index 760e6f16d3c..6175ba86848 100644 --- a/packages/create-webpack-app/src/generators/init/default.ts +++ b/packages/create-webpack-app/src/generators/init/default.ts @@ -35,7 +35,7 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { }, { type: "confirm", - name: "htmlWebpackPlugin", + name: "html", message: "Do you want to simplify the creation of HTML files for your bundle?", default: true, }, @@ -55,7 +55,6 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { if (input === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else if (input === "CSS only") { answers.isCSS = true; } @@ -76,13 +75,6 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { message: "Do you want to use PostCSS in your project?", default: (answers: Answers) => answers.cssType === "CSS only", }, - { - type: "list", - name: "extractPlugin", - message: "Do you want to extract CSS into separate files?", - choices: ["No", "Only for Production", "Yes"], - default: "Only for Production", - }, { type: "list", name: "packageManager", @@ -113,10 +105,6 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { devDependencies.push("webpack-dev-server"); } - if (answers.htmlWebpackPlugin) { - devDependencies.push("html-webpack-plugin", "html-loader"); - } - if (answers.workboxWebpackPlugin) { devDependencies.push("workbox-webpack-plugin"); } @@ -125,12 +113,7 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { devDependencies.push("postcss-loader", "postcss", "autoprefixer"); } - if (answers.extractPlugin !== "No") { - devDependencies.push("mini-css-extract-plugin"); - } - if (answers.cssType !== "none") { - devDependencies.push("style-loader", "css-loader"); switch (answers.cssType) { case "SASS": devDependencies.push("sass-loader", "sass"); @@ -143,9 +126,6 @@ export default async function defaultInitGenerator(plop: NodePlopAPI) { break; } } - if (answers.extractPlugin !== "No") { - devDependencies.push("mini-css-extract-plugin"); - } const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, diff --git a/packages/create-webpack-app/src/generators/init/react.ts b/packages/create-webpack-app/src/generators/init/react.ts index 188139d3270..69e93ae9532 100644 --- a/packages/create-webpack-app/src/generators/init/react.ts +++ b/packages/create-webpack-app/src/generators/init/react.ts @@ -13,7 +13,6 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { "react@18", "react-dom@18", "webpack-dev-server", - "html-webpack-plugin", "react-router-dom", "@types/react-router-dom", ]; @@ -58,7 +57,6 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { if (input === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else if (input === "CSS only") { answers.isCSS = true; } @@ -79,13 +77,6 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { message: "Do you want to use PostCSS in your project?", default: (answers: Answers) => answers.cssType === "CSS only", }, - { - type: "list", - name: "extractPlugin", - message: "Do you want to extract CSS into separate files?", - choices: ["No", "Only for Production", "Yes"], - default: "Only for Production", - }, { type: "list", name: "packageManager", @@ -103,7 +94,7 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { actions: function actions(answers: Answers) { // setting some default values based on the answers const actions: ActionType[] = []; - answers.htmlWebpackPlugin = true; + answers.html = true; answers.devServer = true; switch (answers.langType) { case "ES6": @@ -124,9 +115,7 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { if (answers.cssType === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else { - devDependencies.push("style-loader", "css-loader"); switch (answers.cssType) { case "CSS only": answers.isCSS = true; @@ -142,9 +131,6 @@ export default async function reactInitGenerator(plop: NodePlopAPI) { break; } } - if (answers.extractPlugin !== "No") { - devDependencies.push("mini-css-extract-plugin"); - } if (answers.workboxWebpackPlugin) { devDependencies.push("workbox-webpack-plugin"); } diff --git a/packages/create-webpack-app/src/generators/init/svelte.ts b/packages/create-webpack-app/src/generators/init/svelte.ts index 08c6403efff..947fa9de2a4 100644 --- a/packages/create-webpack-app/src/generators/init/svelte.ts +++ b/packages/create-webpack-app/src/generators/init/svelte.ts @@ -13,7 +13,6 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { "svelte", "svelte-loader", "webpack-dev-server", - "html-webpack-plugin", ]; await plop.load("../../utils/install-dependencies.js", {}, true); @@ -49,7 +48,6 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { if (input === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else if (input === "CSS only") { answers.isCSS = true; } @@ -70,13 +68,6 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { message: "Do you want to use PostCSS in your project?", default: (answers: Answers) => answers.cssType === "CSS only", }, - { - type: "list", - name: "extractPlugin", - message: "Do you want to extract CSS into separate files?", - choices: ["No", "Only for Production", "Yes"], - default: "Only for Production", - }, { type: "list", name: "packageManager", @@ -94,7 +85,7 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { actions: function actions(answers: Answers) { // setting some default values based on the answers const actions: ActionType[] = []; - answers.htmlWebpackPlugin = true; + answers.html = true; answers.devServer = true; switch (answers.langType) { @@ -117,9 +108,7 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { if (answers.cssType === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else { - devDependencies.push("style-loader", "css-loader"); switch (answers.cssType) { case "CSS only": answers.isCSS = true; @@ -136,10 +125,6 @@ export default async function svelteInitGenerator(plop: NodePlopAPI) { } } - if (answers.extractPlugin !== "No") { - devDependencies.push("mini-css-extract-plugin"); - } - const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, { filePath: "./src/assets/webpack.png", fileType: "binary" }, diff --git a/packages/create-webpack-app/src/generators/init/vue.ts b/packages/create-webpack-app/src/generators/init/vue.ts index fe105558cfc..edc3b43a648 100644 --- a/packages/create-webpack-app/src/generators/init/vue.ts +++ b/packages/create-webpack-app/src/generators/init/vue.ts @@ -12,7 +12,6 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { "webpack-cli", "vue@3", "webpack-dev-server", - "html-webpack-plugin", "vue-loader@next", "@vue/compiler-sfc", "vue-router@4", @@ -57,7 +56,6 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { if (input === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else if (input === "CSS only") { answers.isCSS = true; } @@ -78,13 +76,6 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { message: "Do you want to use PostCSS in your project?", default: (answers: Answers) => answers.cssType === "CSS only", }, - { - type: "list", - name: "extractPlugin", - message: "Do you want to extract CSS into separate files?", - choices: ["No", "Only for Production", "Yes"], - default: "Only for Production", - }, { type: "list", name: "packageManager", @@ -102,7 +93,7 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { actions: function actions(answers: Answers) { // setting some default values based on the answers const actions: ActionType[] = []; - answers.htmlWebpackPlugin = true; + answers.html = true; answers.devServer = true; switch (answers.langType) { @@ -129,9 +120,7 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { if (answers.cssType === "none") { answers.isCSS = false; answers.isPostCSS = false; - answers.extractPlugin = "No"; } else { - devDependencies.push("vue-style-loader", "style-loader", "css-loader"); switch (answers.cssType) { case "CSS only": answers.isCSS = true; @@ -148,10 +137,6 @@ export default async function vueInitGenerator(plop: NodePlopAPI) { } } - if (answers.extractPlugin !== "No") { - devDependencies.push("mini-css-extract-plugin"); - } - const files: FileRecord[] = [ { filePath: "./index.html", fileType: "text" }, { filePath: "./src/assets/webpack.png", fileType: "binary" }, diff --git a/packages/create-webpack-app/src/index.ts b/packages/create-webpack-app/src/index.ts index 207b693a090..795cb913f13 100644 --- a/packages/create-webpack-app/src/index.ts +++ b/packages/create-webpack-app/src/index.ts @@ -17,12 +17,11 @@ const baseAnswers: Answers = { projectPath: process.cwd(), langType: "none", devServer: true, - htmlWebpackPlugin: true, + html: true, workboxWebpackPlugin: true, cssType: "none", isCSS: false, isPostCSS: false, - extractPlugin: "No", packageManager: "npm", }; const initValues: Record = { diff --git a/packages/create-webpack-app/templates/init/default/index.html.tpl b/packages/create-webpack-app/templates/init/default/index.html.tpl index d61cf83b04b..4cf8cdb1986 100644 --- a/packages/create-webpack-app/templates/init/default/index.html.tpl +++ b/packages/create-webpack-app/templates/init/default/index.html.tpl @@ -6,7 +6,8 @@

Hello world!

-

Tip: Check your console

+

Tip: Check your console

<% if (html) { %> + <% } %> <% if (workboxWebpackPlugin) { %> diff --git a/packages/create-webpack-app/templates/init/react/webpack.config.tpl b/packages/create-webpack-app/templates/init/react/webpack.config.tpl index 4176f8df107..39c42a54796 100644 --- a/packages/create-webpack-app/templates/init/react/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/react/webpack.config.tpl @@ -3,32 +3,26 @@ import path from "node:path"; 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 "webpack-dev-server";<% } %><% } %><% 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"; /** @type {import("webpack").Configuration} */ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { - entry: "<%= entry %>", + entry: <% if (html) { %>"./index.html"<% } else { %>"<%= entry %>"<% } %>, output: { path: path.resolve(__dirname, "dist"), },<% if (devServer) { %> devServer: { open: true, + },<% } %><% if (isCSS && isPostCSS) { %> + experiments: { + css: true, },<% } %> - plugins: [<% if (htmlWebpackPlugin) { %> - new HtmlWebpackPlugin({ - template: "index.html", - }),<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(),<% } %> + plugins: [ // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -48,26 +42,26 @@ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { test: /\.(ts|tsx)$/i, loader: "ts-loader", exclude: ["/node_modules/"], - },<% } %><% if (isCSS && !isPostCSS) { %> + },<% } %><% if (isCSS && isPostCSS) { %> { test: /\.css$/i, - use: [stylesHandler,"css-loader"], + type: "css/auto", + use: ["postcss-loader"], },<% } %><% if (cssType == "SASS") { %> { test: /\.s[ac]ss$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], },<% } %><% if (cssType == "LESS") { %> { test: /\.less$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], },<% } %><% if (cssType == "Stylus") { %> { test: /\.styl$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], - },<% } %><% if (isPostCSS && isCSS) { %> - { - test: /\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], },<% } %> { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -88,8 +82,7 @@ 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.mode = "production";<% if (workboxWebpackPlugin) { %> config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> } else { config.mode = "development"; diff --git a/packages/create-webpack-app/templates/init/svelte/index.html.tpl b/packages/create-webpack-app/templates/init/svelte/index.html.tpl index a7468d8153c..5c6a00cc798 100644 --- a/packages/create-webpack-app/templates/init/svelte/index.html.tpl +++ b/packages/create-webpack-app/templates/init/svelte/index.html.tpl @@ -7,6 +7,6 @@
- + diff --git a/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl b/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl index cc010d7d97c..ad15067e9be 100644 --- a/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/svelte/webpack.config.tpl @@ -3,32 +3,26 @@ import path from "node:path"; 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 "webpack-dev-server";<% } %><% } %><% 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"; /** @type {import("webpack").Configuration} */ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { - entry: "<%= entry %>", + entry: <% if (html) { %>"./index.html"<% } else { %>"<%= entry %>"<% } %>, output: { path: path.resolve(__dirname, "dist"), },<% if (devServer) { %> devServer: { open: true, + },<% } %><% if (isCSS && isPostCSS) { %> + experiments: { + css: true, },<% } %> - plugins: [<% if (htmlWebpackPlugin) { %> - new HtmlWebpackPlugin({ - template: "./index.html", - }),<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(),<% } %> + plugins: [ // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -61,26 +55,26 @@ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { options: { appendTsSuffixTo: [/\.svelte$/], }, - },<% } %><% if (isCSS && !isPostCSS) { %> + },<% } %><% if (isCSS && isPostCSS) { %> { test: /\.css$/i, - use: [stylesHandler,"css-loader"], + type: "css/auto", + use: ["postcss-loader"], },<% } %><% if (cssType == "SASS") { %> { test: /\.s[ac]ss$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], },<% } %><% if (cssType == "LESS") { %> { test: /\.less$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], },<% } %><% if (cssType == "Stylus") { %> { test: /\.styl$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], - },<% } %><% if (isPostCSS && isCSS) { %> - { - test: /\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], },<% } %> { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -102,8 +96,7 @@ 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.mode = "production";<% if (workboxWebpackPlugin) { %> config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW());<% } %> } else { config.mode = "development"; diff --git a/packages/create-webpack-app/templates/init/vue/index.html.tpl b/packages/create-webpack-app/templates/init/vue/index.html.tpl index 40294bb4c8d..d938a5e5912 100644 --- a/packages/create-webpack-app/templates/init/vue/index.html.tpl +++ b/packages/create-webpack-app/templates/init/vue/index.html.tpl @@ -7,6 +7,6 @@
- + diff --git a/packages/create-webpack-app/templates/init/vue/webpack.config.tpl b/packages/create-webpack-app/templates/init/vue/webpack.config.tpl index 4be7e433154..c7775182e22 100644 --- a/packages/create-webpack-app/templates/init/vue/webpack.config.tpl +++ b/packages/create-webpack-app/templates/init/vue/webpack.config.tpl @@ -4,33 +4,28 @@ import { VueLoaderPlugin } from "vue-loader"; import path from "node:path"; 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 "webpack-dev-server";<% } %><% } %><% 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"; /** @type {import("webpack").Configuration} */ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { - entry: "<%= entry %>", + entry: <% if (html) { %>"./index.html"<% } else { %>"<%= entry %>"<% } %>, output: { path: path.resolve(__dirname, "dist"), },<% if (devServer) { %> devServer: { open: true, },<% } %> + experiments: { + css: true,<% if (html) { %> + html: true,<% } %> + }, plugins: [ - new VueLoaderPlugin(),<% if (htmlWebpackPlugin) { %> - new HtmlWebpackPlugin({ - template: "index.html", - }),<% } %><% if (extractPlugin === "Yes") { %> - new MiniCssExtractPlugin(),<% } %> + new VueLoaderPlugin(), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -38,7 +33,10 @@ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { rules: [ { test: /\.vue$/, - loader: "vue-loader" + loader: "vue-loader", + options: { + experimentalInlineMatchResource: true, + }, },<% if (langType == "ES6") { %> { test: /\.js$/, @@ -58,26 +56,26 @@ const config <% if (langType === "Typescript") { %>: Configuration <% } %>= { transpileOnly: true, }, exclude: ["/node_modules/"], - },<% } %><% if (isCSS && !isPostCSS) { %> + },<% } %><% if (isCSS && isPostCSS) { %> { test: /\.css$/i, - use: [stylesHandler,"css-loader"], + type: "css/auto", + use: ["postcss-loader"], },<% } %><% if (cssType == "SASS") { %> { test: /\.s[ac]ss$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"sass-loader"], },<% } %><% if (cssType == "LESS") { %> { test: /\.less$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"less-loader"], },<% } %><% if (cssType == "Stylus") { %> { test: /\.styl$/i, - use: [stylesHandler, "css-loader", <% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], - },<% } %><% if (isPostCSS && isCSS) { %> - { - test: /\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: [<% if (isPostCSS) { %>"postcss-loader", <% } %>"stylus-loader"], },<% } %> { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -97,8 +95,7 @@ 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.mode = "production";<% 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 94c723a4fac..4fe4ac80233 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 @@ -4,8 +4,6 @@ exports[`create-webpack-app cli recognizes '-t' as an alias for '--template' and { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -27,8 +25,6 @@ exports[`create-webpack-app cli should ask question when wrong template is suppl { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -95,7 +91,6 @@ const config = { 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/ @@ -114,12 +109,10 @@ export default () => { " `; -exports[`create-webpack-app cli should configure html-webpack-plugin as opted 1`] = ` +exports[`create-webpack-app cli should configure native HTML support as opted 1`] = ` { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", }, @@ -134,12 +127,11 @@ exports[`create-webpack-app cli should configure html-webpack-plugin as opted 1` } `; -exports[`create-webpack-app cli should configure html-webpack-plugin as opted 2`] = ` +exports[`create-webpack-app cli should configure native HTML support as opted 2`] = ` "// Generated using webpack-cli https://github.com/webpack/webpack-cli import path from "node:path"; import { fileURLToPath } from "node:url"; -import HtmlWebpackPlugin from "html-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -147,14 +139,11 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -164,11 +153,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -191,8 +175,6 @@ exports[`create-webpack-app cli should configure workbox-webpack-plugin as opted { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "workbox-webpack-plugin": "x.x.x", @@ -213,7 +195,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"; const __filename = fileURLToPath(import.meta.url); @@ -222,14 +203,11 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -239,11 +217,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -314,7 +287,6 @@ const config = { 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/ @@ -337,8 +309,6 @@ exports[`create-webpack-app cli should generate default project when nothing is { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -361,7 +331,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"; const __filename = fileURLToPath(import.meta.url); @@ -370,7 +339,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, @@ -378,9 +347,6 @@ const config = { open: true, }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -390,11 +356,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -418,8 +379,6 @@ exports[`create-webpack-app cli should generate default project when nothing is { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -442,7 +401,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"; const __filename = fileURLToPath(import.meta.url); @@ -451,7 +409,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, @@ -459,9 +417,6 @@ const config = { open: true, }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -471,11 +426,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -521,7 +471,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"; const __filename = fileURLToPath(import.meta.url); @@ -530,7 +479,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, @@ -538,9 +487,6 @@ const config = { open: true, }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -550,11 +496,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -578,8 +519,6 @@ exports[`create-webpack-app cli should generate default project when nothing is { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -602,7 +541,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"; const __filename = fileURLToPath(import.meta.url); @@ -611,7 +549,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, @@ -619,9 +557,6 @@ const config = { open: true, }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -631,11 +566,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -659,8 +589,6 @@ exports[`create-webpack-app cli should generate default project when nothing is { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -683,7 +611,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"; const __filename = fileURLToPath(import.meta.url); @@ -692,7 +619,7 @@ const isProduction = process.env.NODE_ENV === "production"; /** @type {import("webpack").Configuration} */ const config = { - entry: "./src/index.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, @@ -700,9 +627,6 @@ const config = { open: true, }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -712,11 +636,6 @@ const config = { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, - - { - test: /\\.html$/i, - use: ["html-loader"], - }, // Add your rules for custom modules here // Learn more about loaders from https://webpack.js.org/loaders/ @@ -740,8 +659,6 @@ exports[`create-webpack-app cli should generate folders if non existing generati { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -763,8 +680,6 @@ exports[`create-webpack-app cli should generate project when generationPath is s { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -792,15 +707,11 @@ exports[`create-webpack-app cli should generate react template with state and ro "@types/react-router-dom": "x.x.x", "autoprefixer": "x.x.x", "babel-loader": "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", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", @@ -823,28 +734,25 @@ exports[`create-webpack-app cli should generate react template with state and ro import path from "node:path"; import { fileURLToPath } from "node:url"; -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 = { - entry: "./src/index.jsx", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -862,7 +770,8 @@ const config = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -884,7 +793,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -902,15 +810,11 @@ exports[`create-webpack-app cli should generate react template with typescript 1 "@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", @@ -937,28 +841,25 @@ 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", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + }, plugins: [ - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -971,7 +872,8 @@ const config : Configuration = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -993,7 +895,6 @@ const config : Configuration = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1011,12 +912,8 @@ exports[`create-webpack-app cli should generate svelte template with prompt answ "@babel/preset-env": "x.x.x", "autoprefixer": "x.x.x", "babel-loader": "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", "webpack": "x.x.x", @@ -1041,28 +938,25 @@ exports[`create-webpack-app cli should generate svelte template with prompt answ import path from "node:path"; import { fileURLToPath } from "node:url"; -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 = { - entry: "./src/main.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + }, plugins: [ - new HtmlWebpackPlugin({ - template: "./index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1090,7 +984,8 @@ const config = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -1113,7 +1008,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1129,12 +1023,8 @@ exports[`create-webpack-app cli should generate svelte template with typescript "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", @@ -1163,28 +1053,25 @@ 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", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + }, plugins: [ - new HtmlWebpackPlugin({ - template: "./index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1210,7 +1097,8 @@ const config : Configuration = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -1233,7 +1121,6 @@ const config : Configuration = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1295,7 +1182,6 @@ const config : Configuration = { 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/ @@ -1326,17 +1212,12 @@ exports[`create-webpack-app cli should generate vue template with store and rout "@vue/compiler-sfc": "x.x.x", "autoprefixer": "x.x.x", "babel-loader": "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", "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", @@ -1360,29 +1241,27 @@ exports[`create-webpack-app cli should generate vue template with store and rout import { VueLoaderPlugin } from "vue-loader"; import path from "node:path"; import { fileURLToPath } from "node:url"; -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 = { - entry: "./src/main.js", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + html: true, + }, plugins: [ new VueLoaderPlugin(), - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1390,7 +1269,10 @@ const config = { rules: [ { test: /\\.vue$/, - loader: "vue-loader" + loader: "vue-loader", + options: { + experimentalInlineMatchResource: true, + }, }, { test: /\\.js$/, @@ -1404,7 +1286,8 @@ const config = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -1424,7 +1307,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1440,19 +1322,14 @@ exports[`create-webpack-app cli should generate vue template with typescript 1`] "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", @@ -1478,29 +1355,27 @@ 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", + entry: "./index.html", output: { path: path.resolve(__dirname, "dist"), }, devServer: { open: true, }, + experiments: { + css: true, + html: true, + }, plugins: [ new VueLoaderPlugin(), - new HtmlWebpackPlugin({ - template: "index.html", - }), // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -1508,7 +1383,10 @@ const config : Configuration = { rules: [ { test: /\\.vue$/, - loader: "vue-loader" + loader: "vue-loader", + options: { + experimentalInlineMatchResource: true, + }, }, { test: /\\.(ts|tsx)$/i, @@ -1521,7 +1399,8 @@ const config : Configuration = { }, { test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + type: "css/auto", + use: ["postcss-loader"], }, { test: /\\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, @@ -1542,7 +1421,6 @@ const config : Configuration = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); config.plugins?.push(new WorkboxWebpackPlugin.GenerateSW()); } else { config.mode = "development"; @@ -1557,13 +1435,10 @@ exports[`create-webpack-app cli should use css preprocessor and css with postcss "description": "My webpack project", "devDependencies": { "autoprefixer": "x.x.x", - "css-loader": "x.x.x", - "mini-css-extract-plugin": "x.x.x", "postcss": "x.x.x", "postcss-loader": "x.x.x", "sass": "x.x.x", "sass-loader": "x.x.x", - "style-loader": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", }, @@ -1583,12 +1458,10 @@ 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); 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 = { @@ -1596,6 +1469,9 @@ const config = { output: { path: path.resolve(__dirname, "dist"), }, + experiments: { + css: true, + }, plugins: [ // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ @@ -1603,18 +1479,19 @@ const config = { module: { rules: [ { - test: /\\.s[ac]ss$/i, - use: [stylesHandler, "css-loader", "postcss-loader", "sass-loader"], + test: /\\.css$/i, + type: "css/auto", + use: ["postcss-loader"], }, { - test: /\\.css$/i, - use: [stylesHandler, "css-loader", "postcss-loader"], + test: /\\.s[ac]ss$/i, + type: "css/auto", + use: ["postcss-loader", "sass-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/ @@ -1625,7 +1502,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } @@ -1634,18 +1510,15 @@ export default () => { " `; -exports[`create-webpack-app cli should use to use css preprocessor with postcss with mini-css-extract-plugin in project when selected 1`] = ` +exports[`create-webpack-app cli should use css preprocessor with postcss in project when selected 1`] = ` { "description": "My webpack project", "devDependencies": { "autoprefixer": "x.x.x", - "css-loader": "x.x.x", - "mini-css-extract-plugin": "x.x.x", "postcss": "x.x.x", "postcss-loader": "x.x.x", "sass": "x.x.x", "sass-loader": "x.x.x", - "style-loader": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", }, @@ -1660,17 +1533,15 @@ exports[`create-webpack-app cli should use to use css preprocessor with postcss } `; -exports[`create-webpack-app cli should use to use css preprocessor with postcss with mini-css-extract-plugin in project when selected 2`] = ` +exports[`create-webpack-app cli should use css preprocessor with postcss in project when selected 2`] = ` "// Generated using webpack-cli https://github.com/webpack/webpack-cli import path from "node:path"; import { fileURLToPath } from "node:url"; -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 = { @@ -1686,13 +1557,13 @@ const config = { rules: [ { test: /\\.s[ac]ss$/i, - use: [stylesHandler, "css-loader", "postcss-loader", "sass-loader"], + type: "css/auto", + use: ["postcss-loader", "sass-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/ @@ -1703,7 +1574,6 @@ const config = { export default () => { if (isProduction) { config.mode = "production"; - config.plugins?.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } @@ -1716,8 +1586,6 @@ exports[`create-webpack-app cli should work with 'new' alias 1`] = ` { "description": "My webpack project", "devDependencies": { - "html-loader": "x.x.x", - "html-webpack-plugin": "x.x.x", "webpack": "x.x.x", "webpack-cli": "x.x.x", "webpack-dev-server": "x.x.x", diff --git a/test/create-webpack-app/init/init.test.js b/test/create-webpack-app/init/init.test.js index 1a59d4a1e0d..111475090ad 100644 --- a/test/create-webpack-app/init/init.test.js +++ b/test/create-webpack-app/init/init.test.js @@ -352,7 +352,7 @@ describe("create-webpack-app cli", () => { expect(readFromWebpackConfig(dir)).toMatchSnapshot(); }); - it("should use to use css preprocessor with postcss with mini-css-extract-plugin in project when selected", async () => { + it("should use css preprocessor with postcss in project when selected", async () => { const { stdout } = await runPromptWithAnswers( dir, ["init", "."], @@ -441,7 +441,7 @@ describe("create-webpack-app cli", () => { expect(readFromWebpackConfig(dir)).toMatchSnapshot(); }); - it("should configure html-webpack-plugin as opted", async () => { + it("should configure native HTML support as opted", async () => { const { stdout } = await runPromptWithAnswers( dir, ["init", "."],