Master modern JavaScript development tools and workflow optimization.
Master modern JavaScript development tools and workflow optimization.
Learn to use module bundlers like Webpack and Vite for efficient JavaScript development
Content by: Kriyansh Khunt
MERN Stack Developer
Webpack is a powerful module bundler that transforms and bundles JavaScript modules for the browser.
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babelloader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
outDir: 'dist',
sourcemap: true
},
server: {
port: 3000,
open: true
}
});// Dynamic imports for code splitting
import { lazy } from 'react';
const loadModule = async () => {
const module = await import('./heavy-module.js');
return module.default;
};
// Webpack code splitting
const HomePage = lazy(() => import('./pages/Home'));
const AboutPage = lazy(() => import('./pages/About'));// webpack.config.js - Asset optimization
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
]
};// Simple build tool
const fs = require('fs');
const path = require('path');
class SimpleBundler {
constructor(config) {
this.config = config;
this.modules = new Map();
}
bundle(entry) {
const module = this.loadModule(entry);
return this.generateBundle(module);
}
loadModule(filePath) {
if (this.modules.has(filePath)) {
return this.modules.get(filePath);
}
const content = fs.readFileSync(filePath, 'utf8');
const module = {
id: filePath,
content: this.transformModule(content),
dependencies: this.extractDependencies(content)
};
this.modules.set(filePath, module);
module.dependencies.forEach(dep => {
this.loadModule(dep);
});
return module;
}
transformModule(content) {
// Simple transformation - replace require with module system
return content.replace(/require\(['"]([^'"]+)['"]\)/g, (match, dep) => {
return `__require__('${dep}')`;
});
}
extractDependencies(content) {
const deps = [];
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
let match;
while ((match = requireRegex.exec(content)) !== null) {
deps.push(match[1]);
}
return deps;
}
generateBundle(entryModule) {
let bundle = `(function(modules) {
function __require__(id) {
const module = { exports: {} };
modules[id](module, module.exports, __require__);
return module.exports;
}
return __require__('${entryModule.id}');
})({`;
this.modules.forEach((module, id) => {
bundle += `'${id}': function(module, exports, require) {
${module.content}
},
`;
});
bundle += '});';
return bundle;
}
}Test your understanding of this topic:
Master package management with npm, yarn, and pnpm for efficient dependency management
Content by: Praveen Kumar
MERN Stack Developer
npm is the default package manager for Node.js and provides powerful dependency management capabilities.
// package.json
{
"name": "my-project",
"version": "1.0.0",
"description": "A sample project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "webpack --mode production",
"test": "jest",
"lint": "eslint src/"
},
"dependencies": {
"express": "^4.18.0",
"lodash": "^4.17.21"
},
"devDependencies": {
"jest": "^29.0.0",
"eslint": "^8.0.0"
}
}// Installing packages
npm install express // Production dependency
npm install -D jest // Development dependency
npm install -g nodemon // Global package
// Version management
npm install express@4.17.1 // Specific version
npm install express@^4.17.0 // Compatible version
npm install express@~4.17.1 // Patch version
// Updating packages
npm update // Update all packages
npm update express // Update specific package
npm outdated // Check outdated packages// Yarn commands
yarn add express // Add dependency
yarn add -D jest // Add dev dependency
yarn install // Install dependencies
yarn upgrade // Update dependencies
// pnpm commands
pnpm add express // Add dependency
pnpm add -D jest // Add dev dependency
pnpm install // Install dependencies
pnpm update // Update dependencies
// Performance comparison
// pnpm > yarn > npm (in terms of speed and disk usage)// Monorepo with workspaces
// package.json (root)
{
"name": "my-monorepo",
"workspaces": [
"packages/*",
"apps/*"
]
}
// packages/shared/package.json
{
"name": "@myorg/shared",
"version": "1.0.0"
}
// apps/web/package.json
{
"name": "@myorg/web",
"dependencies": {
"@myorg/shared": "workspace:*"
}
}// Simple package manager
const fs = require('fs');
const path = require('path');
class SimplePackageManager {
constructor(projectPath) {
this.projectPath = projectPath;
this.packageJsonPath = path.join(projectPath, 'package.json');
this.nodeModulesPath = path.join(projectPath, 'node_modules');
this.packageJson = this.loadPackageJson();
}
loadPackageJson() {
if (fs.existsSync(this.packageJsonPath)) {
return JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf8'));
}
return {
name: path.basename(this.projectPath),
version: '1.0.0',
dependencies: {},
devDependencies: {}
};
}
addDependency(name, version, isDev = false) {
const key = isDev ? 'devDependencies' : 'dependencies';
this.packageJson[key][name] = version;
this.savePackageJson();
console.log(`Added ${name}@${version} to ${key}`);
}
removeDependency(name) {
let removed = false;
if (this.packageJson.dependencies[name]) {
delete this.packageJson.dependencies[name];
removed = true;
}
if (this.packageJson.devDependencies[name]) {
delete this.packageJson.devDependencies[name];
removed = true;
}
if (removed) {
this.savePackageJson();
console.log(`Removed ${name}`);
} else {
console.log(`Package ${name} not found`);
}
}
listDependencies() {
console.log('Dependencies:');
Object.entries(this.packageJson.dependencies).forEach(([name, version]) => {
console.log(` ${name}: ${version}`);
});
console.log('Dev Dependencies:');
Object.entries(this.packageJson.devDependencies).forEach(([name, version]) => {
console.log(` ${name}: ${version}`);
});
}
savePackageJson() {
fs.writeFileSync(
this.packageJsonPath,
JSON.stringify(this.packageJson, null, 2)
);
}
}Test your understanding of this topic:
Learn to use build tools and transpilers for modern JavaScript development
Content by: Sachin Patel
Node.js Developer
Babel is a JavaScript compiler that transforms modern JavaScript code into older versions for better browser compatibility.
// .babelrc
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "ie >= 11"]
}
}],
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime"
]
}// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
require('postcss-preset-env')({
stage: 3
})
]
};// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'umd',
name: 'MyLibrary'
},
plugins: [
resolve(),
commonjs(),
babel({
exclude: 'node_modules/**'
})
]
};// Simple JavaScript transpiler
class SimpleTranspiler {
constructor() {
this.transformations = [
this.transformArrowFunctions,
this.transformTemplateLiterals,
this.transformDestructuring
];
}
transpile(code) {
let result = code;
this.transformations.forEach(transform => {
result = transform(result);
});
return result;
}
transformArrowFunctions(code) {
return code
.replace(/(\w+)\s*=>\s*{([^}]+)}/g, 'function($1) { $2 }')
.replace(/(\w+)\s*=>\s*([^;{\n]+)/g, 'function($1) { return $2; }');
}
transformTemplateLiterals(code) {
return code.replace(/`([sS]*?)`/g, (match, content) => {
return '"' + content.replace(/\${([^}]+)}/g, '" + $1 + "') + '"';
});
}
transformDestructuring(code) {
return code.replace(/const\s*{\s*([\w,\s]+)\s*}\s*=\s*(\w+)/g, (match, vars, obj) => {
const variables = vars.split(',').map(v => v.trim()).filter(v => v);
return variables.map(v => `const ${v} = ${obj}.${v};`).join('\n');
});
}
}
// Usage
const transpiler = new SimpleTranspiler();
const modernCode = `const { name, age } = user;
const greet = (name) => `Hello ${name}!`;
const result = greet('World');
`;
const legacyCode = transpiler.transpile(modernCode);
console.log(legacyCode);Test your understanding of this topic:
Optimize your development workflow with modern tools and practices
Content by: Parth Patel
Node.js Developer
Set up an efficient development environment with the right tools and configurations.
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"emmet.includeLanguages": {
"javascript": "javascriptreact"
},
"files.associations": {
"*.js": "javascript"
}
}// .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint
npm run test
// .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --edit "$1"// .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build// Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
// docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
environment:
- NODE_ENV=development// dev-cli.js
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
class DevCLI {
constructor() {
this.projectRoot = process.cwd();
this.config = this.loadConfig();
}
loadConfig() {
const configPath = path.join(this.projectRoot, 'dev.config.json');
try {
if (fs.existsSync(configPath)) {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
}
} catch (error) {
console.error(`Error reading dev.config.json: ${error.message}`);
}
return {
scripts: {
dev: 'npm run dev',
build: 'npm run build',
test: 'npm test',
lint: 'npm run lint'
},
watch: ['src/**/*.js'],
ignore: ['node_modules/**', 'dist/**']
};
}
start() {
console.log('๐ Starting development environment...');
this.runScript('dev');
}
build() {
console.log('๐จ Building project...');
this.runScript('build');
}
test() {
console.log('๐งช Running tests...');
this.runScript('test');
}
lint() {
console.log('๐ Running linter...');
this.runScript('lint');
}
watch() {
console.log('๐ Watching for changes...');
chokidar.watch(this.config.watch, {
ignored: this.config.ignore
}).on('change', (filePath) => {
console.log(`File "${filePath}" changed, rebuilding...`);
});
}
runScript(scriptName) {
const script = this.config.scripts[scriptName];
if (script) {
try {
execSync(script, { stdio: 'inherit' });
} catch (error) {
console.error(`Error running ${scriptName}: ${error.message}`);
}
} else {
console.error(`Script ${scriptName} not found`);
}
}
}
// CLI interface
const command = process.argv[2];
const cli = new DevCLI();
switch (command) {
case 'start':
cli.start();
break;
case 'build':
cli.build();
break;
case 'test':
cli.test();
break;
case 'lint':
cli.lint();
break;
case 'watch':
cli.watch();
break;
default:
console.log('Available commands: start, build, test, lint, watch');
}Test your understanding of this topic:
Continue your learning journey and master the next set of concepts.
Continue to Module 12