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: Create webpack app #4116

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
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
@@ -0,0 +1 @@
node_modules
25 changes: 25 additions & 0 deletions apps/react/package.json
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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;