Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: init create webpack app #4167

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
f910fe3
feat: init new package and installed deps
maverox May 13, 2024
c175c9d
feat: add template directory from prototype
maverox May 13, 2024
12fbc20
build: typescript init
maverox May 15, 2024
92c2f19
build: set type: module in package.json
maverox May 15, 2024
488f3df
feat: change template to align more with generators package
maverox May 16, 2024
a17fa63
feat: add core logic to run generators and also add types
maverox May 16, 2024
bb6ca9f
chore: add scripts in package.json
maverox May 16, 2024
d5e9fc3
build: change module type to esm in package.json
maverox May 16, 2024
667d50d
feat: add entrypoint executable which wraps the generator cli
maverox May 16, 2024
8f89b98
chore: add ejs and @types/ejs as dependencies
maverox May 18, 2024
d2ca7f6
build: change emit module of tsc to esnext
maverox May 18, 2024
acf5fa5
feat: add ejs template rendering support
maverox May 18, 2024
df39698
feat: add entryPoint prompt
maverox May 18, 2024
93c2142
chore: remove unused code
maverox May 18, 2024
85b06bc
chore: change eslint and cspell silencer
maverox May 19, 2024
88acfd2
build: change plopfile.ts on reviews
maverox May 19, 2024
55e13ec
feat: change the templates
maverox May 19, 2024
897e00b
fix: fix missing comma in tsconfig
maverox May 19, 2024
f9cb74a
chore: change package.json on reviews
maverox May 19, 2024
b6baa6a
docs: change readme based on review
maverox May 19, 2024
d9a0856
fix: customACtionConfig support in plopfile.ts setGenerator config pr…
maverox May 27, 2024
d8ec7e1
feat: add npmInstall custom package
maverox Jun 1, 2024
4c59396
chore: remove redundant code
maverox Jun 1, 2024
04b5f90
fix: typo in prompt
maverox Jun 1, 2024
1bdf924
feat: add skip prompt functionality
maverox Jun 5, 2024
5e6a70b
chore: install commander and remove obsolete deps
maverox Jun 7, 2024
bb5e201
refactor: remove dynamic prompt and revert to previous state
maverox Jun 7, 2024
9bf21bf
feat: create commander cli and implement skip feat
maverox Jun 7, 2024
a295914
refactor: change prompt order to have genPath as first
maverox Jun 8, 2024
e6add83
refactor: change console output format for deps installation
maverox Jun 8, 2024
4ac8bf0
feat: change -s flag to -f|--force and make it default
maverox Jun 8, 2024
d1fb3e7
chore: add 'uzair' as a word for cspell
maverox Jun 8, 2024
2928772
test: create test suite for create-webpack-app package
maverox Jun 8, 2024
3f66230
Update packages/create-webpack-app/README.md
maverox Jun 15, 2024
769e095
Update packages/create-webpack-app/README.md
maverox Jun 15, 2024
cb309df
refactor: migrate cli logic to ts from js
maverox Jun 25, 2024
860e5c2
feat: add conditional file generation based on dynamic action function
maverox Jun 25, 2024
de92604
docs: change doc to align with its features
maverox Jun 25, 2024
b150fa8
feat: change dependency installation to be cross-compatible
maverox Jun 25, 2024
f3315f4
refactor: remove unused var
maverox Jun 25, 2024
19f59ea
feat: add types
maverox Jun 25, 2024
02f04cb
chore: enable eslint for package/create-webpack-app
maverox Jun 25, 2024
284ab14
chore: change module type and fix control flow for errors
maverox Jun 25, 2024
b80f340
feat: add logger utility module
maverox Jul 1, 2024
944bb33
refactor: refactor and implement logger
maverox Jul 1, 2024
b82f4be
feat: change stdio settings for pkgInstall action
maverox Jul 1, 2024
b4cca8f
fix: change conditional prompt to align with original logic
maverox Jul 1, 2024
e3ef415
test: implement test according to package
maverox Jul 1, 2024
0a42c64
fix: changed template package.json to improve compatibility with syntax
maverox Jul 1, 2024
f0196bd
chore: add peerDep webpack-cli and dep colorette
maverox Jul 1, 2024
8e9dfb6
feat: remove projectName and use path only
maverox Jul 4, 2024
ff53355
chore: remove "uzair" as word from cspell.json
maverox Jul 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ test/build/config/error-commonjs/syntax-error.js
test/build/config/error-mjs/syntax-error.mjs
test/build/config/error-array/webpack.config.js
test/configtest/with-config-path/syntax-error.config.js

packages/create-webpack-app
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should run ESlint on all packages.


11 changes: 11 additions & 0 deletions packages/create-webpack-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# `create-webpack-app`

> TODO: description
## Usage

```js
const createWebpackApp = require("create-webpack-app");

// TODO: DEMONSTRATE API
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to promote the API usage? IMO, CWA interaction should be limited to CLI.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking the same thing, will surely work on a better readme.

```
19 changes: 19 additions & 0 deletions packages/create-webpack-app/bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import minimist from "minimist";
import { Plop, run } from "plop";
/* cSpell:disable */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this disable cspell for the whole file or just the next line?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

section of code but I have found a better alternative

Suggested change
/* cSpell:disable */
/* cSpell:words plopfile */

const args = process.argv.slice(2);
const argv = minimist(args);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

Plop.prepare(
{
cwd: argv.cwd,
configPath: path.resolve(__dirname, "../lib/plopfile.js"),
preload: argv.preload || [],
completion: argv.completion,
},
(env) => Plop.execute(env, run),
);
53 changes: 53 additions & 0 deletions packages/create-webpack-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "create-webpack-app",
"version": "1.0.0",
"description": "CLI for scaffolding webpack projects using default config, framework templates, loader or plugins templates",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/webpack/create-webpack-app.git"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is under the webpacki-cli repo

},
"homepage": "https://github.com/webpack/webpack-cli/tree/master/packages/create-webpack-app",
"bugs": "https://github.com/webpack/webpack-cli/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"bin": {
"create-webpack-app": "./bin/index.js"
},
"type": "module",
"main": "./lib/index.js",
"scripts": {
"build": "tsc --build",
"watch": "tsc --watch"
},
"engines": {
"node": ">=14.15.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's support the minimum version as v18, we also have plans to drop support for v14 in other packages too.

Suggested change
"node": ">=14.15.0"
"node": ">=18.12.0"

},
"keywords": [
"webpack",
"cli",
"scaffolding",
"module",
"bundler",
"web",
"frameworks"
],
"files": [
"bin",
"lib",
"!**/*__tests__"
],
"dependencies": {
"ejs": "^3.1.10",
"minimist": "^1.2.8",
"node-plop": "^0.32.0",
"plop": "^4.0.1"
},
"devDependencies": {
"@types/ejs": "^3.1.5"
},
"peerDependencies": {},
"peerDependenciesMeta": {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"peerDependencies": {},
"peerDependenciesMeta": {}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed this in latest commit

}
1 change: 1 addition & 0 deletions packages/create-webpack-app/src/generators/default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// refactored generator will be written here shortly
179 changes: 179 additions & 0 deletions packages/create-webpack-app/src/plopfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { NodePlopAPI } from "./types";
import { resolve } from "path";
import ejs from "ejs";
/* eslint-disable no-unused-vars */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not disable the rule for the whole file, prefer to use //eslint-disable-next-line

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed this in latest commits


export default function (plop: NodePlopAPI) {
const dependencies = ["webpack", "webpack-cli"];
// Define a base generator for the project structure
plop.setGenerator("init", {
description: "Create a basic Webpack project",
prompts: [
{
type: "input",
name: "projectName",
message: "Enter your project name:",
default: "webpack-project",
validate(input, _) {
if (!input) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more strict check, in case the user just passes space.

Suggested change
if (!input) {
if (!input.trim()) {

return "Project name cannot be empty";
}
return true;
},
},
{
type: "input",
name: "configPath",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: "configPath",
name: "projectPath",

message: "Enter the project destination:",
default: ".",
filter: (input, answers) => {
return resolve(input, answers.projectName);
},
},
{
type: "input",
name: "entryPoint",
message: "Enter the entry point of your application:",
default: "src/index.js",
validate(input, _) {
if (!input) {
return "Entry point cannot be empty";
}
return true;
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are the ones generating templates we should have control over the entry point. We should not ask this question for scaffolding, users can refactor templates if they wish to post scaffolding.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense.

},
{
type: "list",
name: "langType",
message: "Which of the following JS solutions do you want to use?",
choices: ["none", "ES6", "Typescript"],
default: "none",
filter: (input, _) => {
switch (input) {
case "ES6":
dependencies.push("babel-loader", "@babel/core", "@babel/preset-env");
break;
case "Typescript":
dependencies.push("typescript", "ts-loader");
break;
}
return input;
},
},
{
type: "confirm",
name: "devServer",
message: "Would you like to use Webpack Dev server?",
default: true,
filter: (input, _) => {
if (input) {
dependencies.push("webpack-dev-server");
}
return input;
},
},
{
type: "confirm",
name: "htmlWebpackPlugin",
message: "Do you want to simplify the creation of HTML files for your bundle?",
default: true,
filter: (input, _) => {
if (input) {
dependencies.push("html-webpack-plugin", "html-loader");
}
return input;
},
},
{
type: "confirm",
name: "workboxWebpackPlugin",
message: "Do you want to add PWA support?",
default: true,
filter: (input, _) => {
if (input) {
dependencies.push("workbox-webpack-plugin");
}
return input;
},
},
{
type: "list",
name: "cssType",
message: "Which of the following CSS solution do you want to use?",
choices: ["none", "CSS only", "SASS", "LESS", "Stylus"],
default: "Css only",
filter: (input, answers) => {
if (input === "none") {
answers.isCSS = false;
answers.isPostCSS = false;
answers.extractPlugin = "No";
} else {
dependencies.push("style-loader", "css-loader");
switch (input) {
case "CSS only":
answers.isCSS = true;
break;
case "SASS":
dependencies.push("sass-loader", "node-sass");
break;
case "LESS":
dependencies.push("less-loader", "less");
break;
case "Stylus":
dependencies.push("stylus-loader", "stylus");
break;
}
}
return input;
},
},
{
type: "confirm",
name: "isCSS",
message: (answers) =>
`Will you be using CSS styles along with ${answers.cssType}in your project?`,
when: (answers) => answers.cssType !== "CSS only",
default: true,
},
{
type: "confirm",
name: "isPostCSS",
message: "Do you want to use PostCSS in your project?",
when: (answers) => answers.isCSS,
filter: (input, _) => {
if (input) {
dependencies.push("postcss-loader", "autoprefixer");
}
return input;
},
default: true,
},
{
type: "list",
name: "extractPlugin",
message: "Do you want to extract CSS into separate files?",
choices: ["No", "Only for Production", "Yes"],
when: (answers) => answers.isCSS,
default: "No",
filter: (input, _) => {
if (input !== "No") {
dependencies.push("mini-css-extract-plugin");
}
return input;
},
},
],
actions: [
{
type: "addMany",
destination: "{{configPath}}",
base: "../templates/init/default",
templateFiles: "../templates/init/default/**/*",
transform: (content, data) => ejs.render(content, data),
stripExtensions: ["tpl"],
force: true,
verbose: true,
},
],
});
}
21 changes: 21 additions & 0 deletions packages/create-webpack-app/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type {
ActionConfig,
ActionType,
AddActionConfig,
AddManyActionConfig,
AppendActionConfig,
CustomActionFunction,
ModifyActionConfig,
PlopCfg,
PlopGenerator,
NodePlopAPI,
PlopGeneratorConfig,
Actions,
} from "node-plop";

export type InitOptions = { template: string; force?: boolean };
export type LoaderOptions = { template: string };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE: slack conv, you should make this generic. You see the pattern

Copy link
Collaborator Author

@maverox maverox May 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I will work on this soon,
I will definitely use the already established types and interfaces in @generators package as inspiration and tweak them.

export type PluginOptions = { template: string };
export type InitGeneratorOptions = { generationPath: string } & InitOptions;
export type LoaderGeneratorOptions = { generationPath: string } & LoaderOptions;
export type PluginGeneratorOptions = { generationPath: string } & PluginOptions;
11 changes: 11 additions & 0 deletions packages/create-webpack-app/templates/init/default/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"plugins": ["@babel/syntax-dynamic-import"],
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
15 changes: 15 additions & 0 deletions packages/create-webpack-app/templates/init/default/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 🚀 Welcome to your new awesome project!

This project has been created using **webpack-cli**, you can now run

```bash
npm run build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what I am supposed to do here I would love if you can be a bit more specific,
all I can infer is you want me to change the run -> --run

Suggested change
npm run build
npm --run build

like this?
also I have read the section in the link provided

```

or

```bash
yarn build
```

to bundle your application
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello World!");
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "1.0.0",

"description": "My webpack project",

"name": <%= projectName %>,
"scripts": {
"build": "webpack --mode=production --node-env=production",

"build:dev": "webpack --mode=development",
"build:prod": "webpack --mode=production --node-env=production",
"watch": "webpack --watch",
<% if (devServer) { %>
"serve": "webpack serve"
<% } %>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
// Add you postcss configuration here
// Learn more about it at https://github.com/webpack-contrib/postcss-loader#config-files
plugins: [["autoprefixer"]],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello, World!");
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Webpack App</title>
</head>
<body>
<h1>Hello world!</h1>
<h2>Tip: Check your console</h2>
</body>
<% if (workboxWebpackPlugin) { %>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("service-worker.js")
.then((registration) => {
console.log("Service Worker registered: ", registration);
})
.catch((registrationError) => {
console.error("Service Worker registration failed: ", registrationError);
});
});
}
</script><% } %>
</html>
10 changes: 10 additions & 0 deletions packages/create-webpack-app/templates/init/default/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"allowJs": true
},
"files": ["src/index.ts"]
}
Loading