Skip to content

feat: Create webpack app #4116

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@ test/**/dist
test/**/**/dist
test/**/**/**/dist
test/**/stats.json

# private readme
private_readme.md
1 change: 1 addition & 0 deletions apps/react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
25 changes: 25 additions & 0 deletions apps/react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@babel/preset-react": "^7.23.3",
"babel-loader": "^9.1.3",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.3"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
7 changes: 7 additions & 0 deletions apps/react/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function App() {
return (
<div>
<h1>Your webpack app is working</h1>
</div>
)
}
Empty file added apps/react/src/index.css
Empty file.
13 changes: 13 additions & 0 deletions apps/react/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack React Application</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="app">You need to enable JavaScript to run this app.</div>
</body>
<script src="../dist/main.js"></script>
</html>
6 changes: 6 additions & 0 deletions apps/react/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("app"));

root.render(<App />);
19 changes: 19 additions & 0 deletions apps/react/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: { path: path.resolve(__dirname, "dist") },
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
],
},
};
68 changes: 68 additions & 0 deletions bin/create-app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const { execSync } = require('child_process');
const path = require('path');
const readlineSync = require('readline-sync');
const fs = require('fs');

if (process.argv.length < 3) {
console.log('You have to provide a name to your app.');
console.log('For example :');
console.log(' npx create-my-boilerplate my-app');
process.exit(1);
}

const projectName = process.argv[2];
const currentPath = process.cwd();
const projectPath = path.join(currentPath, projectName);
const git_repo = "https://github.com/info-arnav/webpack-cli.git";

try {
fs.mkdirSync(projectPath);
} catch (err) {
if (err.code === 'EEXIST') {
console.log(`The file ${projectName} already exist in the current directory, please give it another name.`);
} else {
console.log(error);
}
process.exit(1);
}

async function promptForFramework() {
const frameworks = ['react', 'vue'];
const index = readlineSync.keyInSelect(frameworks, 'Choose a framework:');
if (index === -1) {
console.log('You must choose a framework.');
process.exit(1);
}
return frameworks[index];
}

const framework = promptForFramework();

async function main() {
try {
console.log(`Creating webpack-${framework} app.....`)
console.log('Downloading files...');

execSync(`git clone --no-checkout --depth 1 ${git_repo} ${projectPath}`);

process.chdir(projectPath);

execSync('git config core.sparseCheckout true');
execSync(`echo "apps/${framework}" >> .git/info/sparse-checkout`);
execSync('git checkout');

console.log('Installing dependencies...');
execSync('npm install');

console.log('Removing useless files');
execSync('npx rimraf ./.git');
fs.rmdirSync(path.join(projectPath, 'bin'), { recursive: true});

console.log('The installation is done, this is ready to use !');

} catch (error) {
console.log(error);
}
}

main();
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"name": "webpack-cli-monorepo",
"description": "CLI for webpack & friends",
"license": "MIT",
"private": true,
"private": true,
"bin": {
"create-webpack-app": "./create-app.js"
},
"repository": {
"type": "git",
"url": "https://github.com/webpack/webpack-cli.git"
Expand Down
35 changes: 35 additions & 0 deletions plugin/dotenv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const interpolate = (env, vars) => {
const matches = env.match(/\$([a-zA-Z0-9_]+)|\${([a-zA-Z0-9_]+)}/g) || [];

matches.forEach((match) => {
const key = match.replace(/\$|{|}/g, '');
let variable = vars[key] || '';
variable = interpolate(variable, vars);
env = env.replace(match, variable);
});

return env;
};

class DotEnvPlugin {
constructor() {
}

apply(compiler) {
compiler.hooks.emit.tap('DotEnvPlugin', (compilation) => {
const assets = compilation.assets;
Object.keys(assets).forEach((assetName) => {
let asset = assets[assetName];
asset.source = this.replaceProcessEnv(asset.source);
});
});
}

replaceProcessEnv(source) {
const envRegex = /process\.env\.([a-zA-Z0-9_]+)/g;
return interpolate(source, process.env);
}
}

module.exports = DotEnvPlugin;