This is my Jam
I heard this one on Cosmic Gate’s WYM Radio episode 589.
I heard this one on Cosmic Gate’s WYM Radio episode 589.
In my previous post, I outlined how I migrated a Create-React-App application with Flow types to Vite. I used bunchtogether’s lovely little vite-plugin-flow to get the job done.
After some discussion over on the Flowtype Discord I thought it might be worth figuring out whether I could use Hermes‘ parser capabilities instead (as recommended by the Flow team). On the surface it looked like it was going to be really difficult: I’ve always used Hermes as a Babel parser plugin, and Babel doesn’t usually fit into the whole Vite ecosystem particularly well. It turns out to work quite nicely for my use case.
Luckily others had done most of the work for me � I just had to put the pieces together. First up was vite-plugin-babel (from the wonderfully named Owls Department), which enables Babel in Vite’s development mode. Then came Flow’s @babel/preset-flow and babel-plugin-syntax-hermes-parser (which I was already using in the old Create-React-App project):
npm install --save-dev vite-plugin-babel @babel/preset-flow babel-plugin-syntax-hermes-parser
npm uninstall @bunchtogether/vite-plugin-flow
Finally I updated my project’s vite.config.js. I swapped out the imports:
import babel from "vite-plugin-babel";import { flowPlugin, esbuildFlowPlugin } from "@bunchtogether/vite-plugin-flow";
Then added babel into the plugins section, and removed the vite-plugin-flow config:
{
plugins: [
babel({
babelConfig: {
babelrc: false,
configFile: false,
plugins: ["babel-plugin-syntax-hermes-parser"],
parserOpts: { flow: "all" },
presets: ["@babel/preset-flow"],
},
}),
flowPlugin(),
],
optimizeDeps: {
esbuildOptions: {
plugins: [esbuildFlowPlugin()],
},
},
}
So far everything in my project works nicely, and performance is largely unchanged from the previous setup (using vite-plugin-flow). Production builds on CircleCI come in around 3m30s faster than the previous Create-React-App builds.
The journey to get here took a couple of detours. The most notable was finding the official @vitejs/plugin-react can also do custom Babel plugins/presets. However, it appears support is limited (they do not enable code transformation), and are only applied during the production build. If that had worked, I wouldn’t have needed vite-plugin-babel.
I had a project based on Create React App, using Flow types, which I wanted to migrate to Vite. These are roughly the steps I had to follow:
.js file extension. I renamed them all to .jsx – Vite is much happier that wayyarn install -D vite vite-jsconfig-paths vite-plugin-svgr @vitejs/plugin-react @vitejs/plugin-react-refresh @bunchtogether/vite-plugin-flow
vite.config.js to the project root:/* eslint-disable flowtype/require-valid-file-annotation */
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgrPlugin from "vite-plugin-svgr";
import { flowPlugin, esbuildFlowPlugin } from "@bunchtogether/vite-plugin-flow";
import jsconfigPaths from "vite-jsconfig-paths";
import * as path from "path";
// https://vitejs.dev/config/
/** @type {import('vite').UserConfig} */
export default defineConfig({
optimizeDeps: {
esbuildOptions: {
plugins: [esbuildFlowPlugin()],
},
},
plugins: [
flowPlugin(), react(), jsconfigPaths(), svgrPlugin()
],
resolve: {
alias: [
{ find: "styles", replacement: path.resolve(__dirname, "src/styles") },
],
},
});
/flow-typed/vite_import_meta.js to handle Vite’s handling of environment variables:// @flow
declare interface Import$Meta extends Import$Meta {
env: {
[key: string]: string,
};
}
{
"compilerOptions": {
"baseUrl": "src",
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"paths": {
"flow-types": ["flow-types.js"],
"polyfills": ["polyfills.js"],
"apis/": ["apis/"],
"App/": ["App/"],
"assets/": ["assets/"],
"constants/": ["constants/"],
"errors/": ["errors/"],
"hoc/": ["hoc/"],
"hooks/": ["hooks/"],
"redux/": ["redux/"],
"styles/": ["styles/"],
"utils/": ["utils/"],
"validators/": ["validators/"]
}
},
"include": ["src"],
"exclude": [
"node_modules",
".storybook",
"Auth0",
"flow-typed",
"dist",
".idea"
]
}
REACT_APP_ to VITE_process.env["REACT_APP_WHATEVER"] to import.meta.env.VITE_WHATEVER%VITE_WHATEVER%.flowconfig:/vite.config.jsnpx madge src/index.jsx --circularThanks to Cathal Mac Donnacha, whose post about migrating a typescript project from CRA to Vite was hugely helpful.
Update: I’ve since migrated the project to use Flow’s Hermes parser.
I have a Google Cloud Function which uses Puppeteer to convert HTML documents to PDF. I recently tried to upgrade Puppeteer to version 19. It worked fine locally, but not when deployed to Google Cloud:
Error: Could not find Chromium (rev. 1069273). This can occur if either
1. you did not perform an installation before running the script (e.g. `npm install`) or
2. your cache path is incorrectly configured (which is: /root/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.
The fix was relatively straightforward:
First, add a new .puppeteerrc.cjs file at the root of the project (documented here):
const { join } = require("path");
/**
* @type {import("puppeteer").Configuration}
*/
module.exports = {
cacheDirectory: join(__dirname, ".cache", "puppeteer"),
};
Second, add .cache to your .gitignore file:
# Puppeteer cache
.cache
This fixed everything for my first deployment, but it broke again on subsequent deployments. This lead to Step 3: Add a new gcp-build item to the scripts object in your project’s package.json (documented here). This re-installs puppeteer after every deployment:
"scripts": {
"gcp-build": "node node_modules/puppeteer/install.js",
/* etc */
}
(Thanks to Justus Blümer for writing up the last part).
United Riders of Cumberland (“UROC”) has reached a landmark land access and management framework in order for the community and visitors to continue to enjoy access to the trails on the private and municipal lands surrounding Cumberland, BC.
https://unitedridersofcumberland.com/uroc-secures-ongoing-land-access-agreements/
A nice bit of news to brighten up a wet and rainy Tuesday morning.
I’ve decided to discontinue most of the web player’s functionality in 2023 and focus exclusively on the Overcast app for iPhone, iPad, Apple Watch, and M1/M2-powered Macs.
Marco Arment – https://overcast.fm/webplayerdiscontinuation
Sigh. I understand Marco’s rationale, but it’s still disappointing – I use the website player quite a lot.
Update: It’s not going away after all! 🙂