This document explains the JavaScript development environment for the Brain 2FA WordPress plugin.
The plugin now uses a modern JavaScript build system with:
- Webpack 5 for bundling
- Babel for ES6+ transpilation
- WordPress i18n for internationalization
- ESLint for code quality
- Modular architecture for maintainability
brain-2fa/
├── src/ # Source files (development)
│ └── js/
│ ├── login.js # Login entry point
│ ├── admin.js # Admin entry point
│ ├── components/ # Reusable components
│ │ └── LoginForm.js # Login form handler
│ └── utils/ # Utility functions
│ ├── ajax.js # AJAX helpers
│ ├── dom.js # DOM manipulation
│ └── notification.js # Notifications
├── assets/ # Compiled files (production)
│ ├── js/
│ │ ├── login.js # Compiled login bundle
│ │ ├── login.asset.php # Auto-generated dependencies
│ │ ├── admin.js # Compiled admin bundle
│ │ └── admin.asset.php # Auto-generated dependencies
│ └── css/
├── webpack.config.js # Webpack configuration
├── package.json # NPM dependencies
├── .babelrc.js # Babel configuration
└── .eslintrc.js # ESLint configuration
npm installWatch for changes and automatically rebuild:
npm run devBuild optimized files for production:
npm run buildCheck code quality:
npm run lintAuto-fix issues:
npm run lint:fixAll text strings use WordPress i18n functions:
import { __ } from '@wordpress/i18n';
const message = __('Verification Code', 'brain2fa');
const formatted = sprintf(__('Welcome, %s!', 'brain2fa'), userName);Webpack automatically generates .asset.php files with dependencies:
// login.asset.php (auto-generated)
return array(
'dependencies' => array('wp-i18n'),
'version' => '1.0.0'
);Components are split into logical modules:
// Import utilities
import { sendAjaxRequest } from '@/utils/ajax';
import { showError } from '@/utils/notification';
// Use in your code
const response = await sendAjaxRequest(data);
showError(message);Write modern ES6+ code:
// Async/await
async function validateCredentials() {
try {
const response = await sendAjaxRequest(data);
// Handle response
} catch (error) {
// Handle error
}
}
// Arrow functions
const handleSubmit = (event) => {
event.preventDefault();
// Handle submit
};
// Destructuring
const { username, password } = formData;
// Template literals
const message = `Welcome, ${userName}!`;Generate POT file for translators:
wp i18n make-pot . languages/brain2fa.pot --domain=brain2faTranslators create .po files from the .pot file.
Compile .po files to .mo:
msgfmt languages/brain2fa-fr_FR.po -o languages/brain2fa-fr_FR.moConvert .po to .json for JavaScript:
wp i18n make-json languages --no-purgeThis creates .json files that WordPress uses for JavaScript translations.
- Create new file in
src/js/:
// src/js/settings.js
import { __ } from '@wordpress/i18n';
console.log(__('Settings loaded', 'brain2fa'));- Add to webpack config:
entry: {
'login': './src/js/login.js',
'admin': './src/js/admin.js',
'settings': './src/js/settings.js', // New entry
},- Enqueue in PHP:
$asset_file = BRAIN_2FA_PLUGIN_DIR . 'assets/js/settings.asset.php';
$asset_data = file_exists( $asset_file ) ? require $asset_file : array(
'dependencies' => array(),
'version' => BRAIN_2FA_VERSION,
);
wp_enqueue_script(
'brain-2fa-settings',
BRAIN_2FA_PLUGIN_URL . 'assets/js/settings.js',
$asset_data['dependencies'],
$asset_data['version'],
true
);
wp_set_script_translations(
'brain-2fa-settings',
'brain2fa',
BRAIN_2FA_PLUGIN_DIR . 'languages'
);Create reusable components in src/js/components/:
// src/js/components/Modal.js
import { __ } from '@wordpress/i18n';
class Modal {
constructor(title, content) {
this.title = title;
this.content = content;
this.render();
}
render() {
// Modal rendering logic
}
show() {
// Show modal
}
hide() {
// Hide modal
}
}
export default Modal;Use in your code:
import Modal from '@/components/Modal';
const modal = new Modal(
__('Confirmation', 'brain2fa'),
__('Are you sure?', 'brain2fa')
);
modal.show();Create utility functions in src/js/utils/:
// src/js/utils/validation.js
import { __ } from '@wordpress/i18n';
export function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
export function validateForm(data) {
const errors = [];
if (!data.email || !isValidEmail(data.email)) {
errors.push(__('Invalid email address', 'brain2fa'));
}
return errors;
}- Always use i18n functions for user-facing text
- Keep components small and focused on a single responsibility
- Use async/await instead of callbacks for cleaner code
- Leverage webpack aliases (
@/) for cleaner imports - Run linting before committing code
- Build for production before releases
- Test translations in multiple languages
- Check Node.js version:
node --version(requires 18+) - Clear
node_modulesand reinstall:rm -rf node_modules && npm install - Check for syntax errors in source files
- Ensure
.jsonfiles are generated:wp i18n make-json languages - Check text domain matches:
'brain2fa' - Verify
wp_set_script_translations()is called in PHP
- Check
.asset.phpfiles are generated - Verify WordPress dependencies are available
- Check browser console for errors