Lets say you want to transpile Javascript with injected PHP in it, to be preprocessed by the PHP module of your server. This way, PHP can process the JS with context from the backend, before being delivered as a response.
function component() {
const element = document.createElement('div');
<?php if(isset($_GET["id"])): ?>
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
<?php else: ?>
element.innerHTML = _.join(['Hello', 'PHP injected', ' webpack'], ' ');
<?php endif; ?>
element.classList.add('hello');
return element;
}
document.body.appendChild(component());
When trying to transpile the JS with the babel-loader in Webpack, the PHP tokens are creating errors. How would you transpile such a JS File?
I created a custom babel-php-injected-loader, which uses babel.
const babel = require('@babel/core');
module.exports = function (source) {
const callback = this.async(); // Mark the loader as asynchronous
// Find all PHP blocks in the source
const phpBlocks = [];
const phpRegex = /<?php[sS]*??>/g;
let i = 0;
// Replace each PHP block with a unique placeholder
const processedSource = source.replace(phpRegex, (m) => {
const placeholder = `__PHP_PLACEHOLDER_${i++}__`;
phpBlocks.push({ placeholder, code: m });
return placeholder; // Directly replace PHP blocks with placeholders
});
// Process the modified JavaScript (without PHP blocks) using Babel
babel.transform(processedSource, {
presets: ['@babel/preset-env'], // Same options as you'd pass to babel-loader
}, (err, result) => {
if (err) return callback(err); // If Babel fails, return an error
let finalSource = result.code;
// Re-inject the raw PHP code into the final source, replacing the placeholders
phpBlocks.forEach(({ placeholder, code }) => {
finalSource = finalSource.replace(placeholder, code); // Insert raw PHP directly
});
// Return the final source with raw PHP reinserted
callback(null, finalSource);
});
};
It looks like webpack’s parser from the bundler does not like PHP injections when transpiling.
How would you transpile PHP injected JS with Webpack?
Kind Regards
2
Answers
You need to run that on Server and don’t forget that it should be .php extension and it is better to include the script tag or place these in echo "here"
Since a PHP script that outputs JS is not valid JS code, you can’t directly parse it with a JS parser.
You may find ways to work around it, but even if you manage to minify the file correctly, the real problem is the source map.
A source map, as the name suggests, maps locations in the generated file to the corresponding locations in the original file.
Let’s consider your sample code:
In case the PHP condition evaluates to true, the output is:
If the condition evaluates to false:
In the first case, line 4 of the JS file maps to line 5 of the PHP file.
In the second case, line 4 of the JS file maps to line 7 of the PHP file.
So the mapping depends on the result of the PHP execution; it means it’s impossible to create a source map.
If you really want to minify the JS code, the correct approach is to separate the static and dynamic parts.
Your code can be rewritten to:
and:
The static part can be put in a static JS file and processed by Webpack like any other.