Build Process and Development Workflow
Overview
Wikit uses modern build tools to compile assets, ensure code quality, and optimize performance. Understanding the build process is essential for efficient development.
Requirements
System Requirements
- Node.js: >= 18.0.0
- npm: >= 8.0.0
- PHP: >= 8.1
- Composer: >= 2.0
- Docker: >= 20.10 (for local development)
- Git: >= 2.25
Project Setup
Initial Setup
bash
# Clone repository
git clone git@github.com:webdevelopmentgroup/project-name.git
cd project-name
# Install PHP dependencies
composer install
# Install Node dependencies
npm install
# Copy environment config
cp .env.example .env
# Build assets
npm run buildDirectory Structure
project/
├── assets/ # Source assets
│ ├── js/ # JavaScript sources
│ ├── scss/ # SASS/CSS sources
│ └── images/ # Source images
├── dist/ # Compiled assets
│ ├── js/ # Built JavaScript
│ ├── css/ # Built CSS
│ └── images/ # Optimized images
├── block-editor/ # Gutenberg blocks
│ └── blocks/ # Individual blocks
├── vendor/ # Composer packages
├── node_modules/ # npm packages
├── webpack.config.js # Webpack configuration
├── package.json # Node dependencies
└── composer.json # PHP dependenciesBuild Commands
Development
bash
# Start development mode with hot reload
npm start
# Watch for changes (no hot reload)
npm run watch
# Build development version
npm run dev
# Watch specific assets
npm run watch:js # JavaScript only
npm run watch:css # CSS onlyProduction
bash
# Production build with optimization
npm run build
# Build specific assets
npm run build:js # JavaScript only
npm run build:css # CSS only
npm run build:blocks # Blocks only
# Build and analyze bundle
npm run build:analyzeCode Quality
bash
# Run all linters
npm run lint
# JavaScript linting
npm run lint:js
npm run lint:js:fix # Auto-fix issues
# CSS/SCSS linting
npm run lint:css
npm run lint:css:fix # Auto-fix issues
# PHP Code Sniffer
composer run phpcs
composer run phpcbf # Auto-fix issues
# Run all tests
npm testWebpack Configuration
Main Configuration
javascript
// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
return {
entry: {
main: './assets/js/main.js',
admin: './assets/js/admin.js',
blocks: './block-editor/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@wordpress/babel-preset-default'],
},
},
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css',
}),
],
optimization: isProduction ? {
minimizer: [
new TerserPlugin(),
new OptimizeCSSAssetsPlugin(),
],
} : {},
};
};Block Editor Configuration
javascript
// webpack.blocks.config.js
const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const path = require('path');
module.exports = {
...defaultConfig,
entry: {
'accordion': './block-editor/blocks/accordion/index.js',
'hero': './block-editor/blocks/hero/index.js',
'carousel': './block-editor/blocks/carousel/index.js',
// Add all blocks here
},
output: {
path: path.resolve(__dirname, 'dist/blocks'),
filename: '[name]/index.js',
},
};Package Configuration
package.json Scripts
json
{
"name": "wikit-theme",
"version": "1.0.0",
"scripts": {
"start": "webpack serve --mode development --open",
"watch": "webpack --mode development --watch",
"build": "webpack --mode production",
"build:blocks": "wp-scripts build --webpack-src-dir=block-editor/blocks --output-path=dist/blocks",
"lint": "npm run lint:js && npm run lint:css",
"lint:js": "eslint assets/js --ext .js,.jsx",
"lint:js:fix": "eslint assets/js --ext .js,.jsx --fix",
"lint:css": "stylelint 'assets/scss/**/*.scss'",
"lint:css:fix": "stylelint 'assets/scss/**/*.scss' --fix",
"test": "jest",
"test:watch": "jest --watch"
},
"devDependencies": {
"@wordpress/babel-preset-default": "^7.0.0",
"@wordpress/scripts": "^26.0.0",
"babel-loader": "^9.0.0",
"css-loader": "^6.0.0",
"eslint": "^8.0.0",
"mini-css-extract-plugin": "^2.0.0",
"sass": "^1.0.0",
"sass-loader": "^13.0.0",
"stylelint": "^15.0.0",
"webpack": "^5.0.0",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.0.0"
},
"dependencies": {
"@wordpress/block-editor": "^12.0.0",
"@wordpress/blocks": "^12.0.0",
"@wordpress/components": "^25.0.0",
"@wordpress/element": "^5.0.0",
"@wordpress/i18n": "^4.0.0"
}
}composer.json Configuration
json
{
"name": "wdg/wikit-theme",
"description": "Wikit WordPress Theme",
"type": "wordpress-theme",
"require": {
"php": ">=8.1",
"wdg/wikit-core": "^2.0",
"wdg/wikit-app": "^2.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.7",
"wp-coding-standards/wpcs": "^3.0",
"phpunit/phpunit": "^9.0",
"brain/monkey": "^2.0"
},
"scripts": {
"phpcs": "phpcs --standard=phpcs.xml",
"phpcbf": "phpcbf --standard=phpcs.xml",
"test": "phpunit",
"test:coverage": "phpunit --coverage-html coverage"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}Asset Management
JavaScript Entry Points
javascript
// assets/js/main.js - Frontend entry point
import './modules/navigation';
import './modules/search';
import './modules/animations';
document.addEventListener('DOMContentLoaded', () => {
// Initialize frontend features
});
// assets/js/admin.js - Admin entry point
import './admin/settings';
import './admin/metaboxes';
// block-editor/index.js - Blocks entry point
import './blocks/accordion';
import './blocks/hero';
import './blocks/carousel';SCSS Organization
scss
// assets/scss/main.scss
// Settings & Tools
@import 'settings/variables';
@import 'settings/breakpoints';
@import 'tools/mixins';
@import 'tools/functions';
// Generic & Base
@import 'generic/normalize';
@import 'base/typography';
@import 'base/forms';
// Layout
@import 'layout/grid';
@import 'layout/header';
@import 'layout/footer';
// Components
@import 'components/buttons';
@import 'components/cards';
@import 'components/navigation';
// Blocks
@import 'blocks/hero';
@import 'blocks/accordion';
// Utilities
@import 'utilities/spacing';
@import 'utilities/visibility';Environment Configuration
.env File
bash
# Environment
NODE_ENV=development
WP_ENV=development
# API Keys
API_KEY=your_api_key_here
# Build Settings
PUBLIC_PATH=/wp-content/themes/wikit-theme/dist/
BROWSER_SYNC_PROXY=https://project.local
# Feature Flags
ENABLE_HOT_RELOAD=true
ENABLE_SOURCE_MAPS=trueEnvironment-Specific Builds
javascript
// webpack.config.js
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
mode: isDevelopment ? 'development' : 'production',
devtool: isDevelopment ? 'source-map' : false,
// Development server
devServer: isDevelopment ? {
hot: true,
proxy: {
'/': process.env.BROWSER_SYNC_PROXY,
},
} : undefined,
};Version Control
Git Workflow
bash
# Feature branch workflow
git checkout -b feature/new-feature
npm install # Install any new dependencies
npm run build # Build assets
git add .
git commit -m "feat: add new feature"
git push origin feature/new-feature
# Before merging
npm run lint # Check code quality
npm test # Run tests
npm run build # Ensure production build works.gitignore
gitignore
# Dependencies
/node_modules
/vendor
# Build artifacts
/dist
/dist-tmp
# Environment
.env
.env.local
# IDE
.vscode
.idea
*.sublime-*
# OS
.DS_Store
Thumbs.db
# Logs
npm-debug.log*
yarn-error.log*
# Testing
/coverageDocker Development
Docker Compose Setup
yaml
# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
volumes:
- ./:/var/www/html/wp-content/themes/wikit-theme
- ./wikit-core:/var/www/html/wp-content/plugins/wikit-core
- ./wikit-app:/var/www/html/wp-content/plugins/wikit-app
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
node:
image: node:18
working_dir: /app
volumes:
- ./:/app
command: npm run watch
volumes:
db_data:Docker Commands
bash
# Start services
docker-compose up -d
# Run build in container
docker-compose run --rm node npm run build
# Watch for changes
docker-compose run --rm node npm run watch
# Stop services
docker-compose downContinuous Integration
GitHub Actions Workflow
yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: composer
- name: Install dependencies
run: |
composer install
npm ci
- name: Run linters
run: |
npm run lint
composer run phpcs
- name: Run tests
run: |
npm test
composer run test
- name: Build assets
run: npm run build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/Performance Optimization
Build Optimizations
javascript
// webpack.config.js - Production optimizations
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
},
common: {
minChunks: 2,
priority: 5,
reuseExistingChunk: true,
},
},
},
runtimeChunk: 'single',
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
};Asset Loading
php
// functions.php - Conditional asset loading
add_action( 'wp_enqueue_scripts', function() {
$version = filemtime( get_template_directory() . '/dist/css/main.css' );
// Load critical CSS inline
if ( is_front_page() ) {
$critical_css = file_get_contents( get_template_directory() . '/dist/css/critical.css' );
wp_add_inline_style( 'wikit-style', $critical_css );
}
// Defer non-critical JavaScript
wp_script_add_data( 'wikit-script', 'defer', true );
} );Troubleshooting
Common Issues
Node Version Mismatch
bash
# Check Node version
node --version
# Use nvm to switch versions
nvm use 18Build Failures
bash
# Clear caches and rebuild
rm -rf node_modules dist
npm cache clean --force
npm install
npm run buildPermission Issues
bash
# Fix permissions
sudo chown -R $(whoami) .
chmod +x node_modules/.bin/*Port Conflicts
bash
# Find process using port
lsof -i :8080
# Kill process
kill -9 <PID>Best Practices
- Always commit built files for production deployments
- Run linters before committing code
- Test production builds locally before deploying
- Use source maps in development only
- Optimize images during build process
- Version assets for cache busting
- Document build customizations in README
- Keep dependencies updated regularly
- Use lock files (package-lock.json, composer.lock)
- Monitor bundle sizes to prevent bloat
The build process ensures code quality, performance, and consistency across all Wikit projects.