As the title states. Has parcel an option for that? Don't process the file, don't copy it over to the dist folder, just reload the browser if the file changed.
I used to have a build process with browserify/browser-sync/sass all linked together by myself. In watch mode, I used to also watch my php files (WordPress themes/plugins) like this:
browser-sync start -f \"assets/js/*.js, assets/css/*.css, **/*.php, **/*.json, !node_modules/**\" --no-notify
I'd like to achieve the same thing with parcel, but I don't know how. Would be nice to have an option to tell parcel: "Watch this folder and it's subfolders, and if any of the containing .php files changes, just reload the browser, don't do anything else".
...or maybe there is a way to 'hook' browser-sync in the parcel process and let it only look out for changed php files, e.g. trigger parcels browser reloading mechanism somehow?
Just a simple MAMP on a good old Mac π
| Program | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.9.7
| Node | 8.11.3
| Yarn | 1.9.4
| Operating System | OSX
Parcel only triggers hmr if any asset the bundle contains actually changes. So this wouldn't work, even if it would be watching the php.
You could probably use parcel using watch, which would watch your js and whatever else you're using parcel for and use a seperate thing that watches the php.
@DeMoorJasper wow, thanks for your fast answer! π
...is there maybe a way to trigger a full parcel browser reload from the command line, once an instance of it has been started using watch? That way, maybe I could start some watcher on php files and just tell the parcel process to reload as soon as a file has changed? (Total noob question, I know β never even looked into how those magic file-watching scripts work ;))
I found a watcher script that works exactly how I imagined! π
Now I would 'just' need to trigger parcel reloading somehow:
const watch = require('glob-watcher');
const watcher = watch(['./**/*.php']);
// Pseudo code:
const parcel = getParcelInstance();
watcher.on('change', function(path, stat) {
console.log('changed', path, stat);
parcel.fullReload();
});
watcher.on('add', function(path, stat) {
console.log('added', path, stat);
parcel.fullReload();
});
Parcel can cause browser reloads using:
bundlerInstance.hmr.broadcast({
type: 'reload'
});
And for JS and CSS Parcel should already try to hot reload them which is more complex than a simple page reload, however you could turn that into a simple reload if you are using vanilla JS.
For a simple reload in JS put this in your entrypoint:
if (module.hot) {
module.hot.accept(function () {
window.location.reload();
});
}
More info: https://parceljs.org/hmr.html#%F0%9F%94%A5-hot-module-replacement
@DeMoorJasper wow great, I was able to get it to work! Also discovered two not-yet documented features in parcel's source code: Multiple entry files with glob support π―and https custom certificate options π€. I thought maybe it will help someone to post my solution here.
bundler-with-php-reloading.js :
const argv = require('minimist')(process.argv.slice(2));
const Bundler = require('parcel-bundler');
const watch = require('glob-watcher');
/**
* set the ENV variable
*/
process.env.NODE_ENV = argv.env || 'development';
/**
* The options for the parcel bundler
*/
const options = {
outDir: './assets/bundles',
publicUrl: './',
sourceMaps: process.env.NODE_ENV !== 'production',
// custom https cert and key
https: {
cert: './ssl/c.crt',
key: './ssl/k.key',
},
}
/**
* Run parcel-bundler and glob-watcher
* @param {[type]} files [description]
* @return {[type]} [description]
*/
async function runBundle( files ) {
// multiple files possible, e.g. "src/js/*.bundle.js"
const bundler = new Bundler(files, options);
const bundle = await bundler.bundle();
if( process.env.NODE_ENV === 'development' ) {
runWatcher( bundler );
}
}
/**
* Watch out for php file changes - if any, call 'reloadBrowsers'
* @param object bundler β the parcel instance
*/
function runWatcher( bundler ) {
const watcher = watch(['./**/*.php']);
watcher.on('change', function(path, stat) {
reloadBrowsers( bundler );
});
watcher.on('add', function(path, stat) {
reloadBrowsers( bundler );
});
}
/**
* Tell parcel to reload the browser
* @param object bundler the parcel instance
*/
function reloadBrowsers( bundler ) {
bundler.hmr.broadcast({
type: 'reload'
});
}
/**
* Initialize the bundler
*/
runBundle( argv.f );
In my setup, I want all *.bundle.js files to be bundled. Here's the CLI command:
node bundler-with-php-reloading.js -f "assets-src/js/*.bundle.js"
Thanks again for the hint with the parcel reloading, @DeMoorJasper !
@hirasso awesome, the solution actually looks way cleaner than I expected it to be :)
About the missing docs, if you have any time please contribute a little mention of the features back to the docs repository: https://github.com/parcel-bundler/website
@DeMoorJasper oh my, another thing I never did before, contribute to a github repo... π
I hope I'll get some help from a friend next week on how to do that. If so, I'll be happy to fill the docs with my new knowledge :)
While using this technique, a need arose to disable the bundler.hmr.broadcast({type:'reload'}); for certain files (for example an admin.js file. Is there a way to do this?