JennaSys
Posted on March 7, 2022
When the React to Python book was published, Parcel version 2 was just about to go into Beta. Because of that, it was still a bit too volatile to include in the book. But now that it is officially released, I thought I'd give those of you using Parcel as part of the toolchain I outlined in the book, a guide to using the newer version of Parcel.
There are definitely some new features available in the latest version of Parcel that makes switching to it worthwhile. To start with, the Parcel development server now supports server proxies, so you don't have to use an external proxy server to serve up your back-end REST services during the development process. On top of that, the tree shaking algorithm is much more efficient at eliminating unused code from the generated JavaScript bundle, making the deployment bundle smaller. Oh, and the builds are faster too! Running a production build on the project in Part III of the React to Python book resulted in a JavaScript bundle that was 30% smaller, and it took 15% less time to build.
The general steps to modify an application to move from using the original version of Parcel to Parcel v2 are covered in the Parcel v2 documentation. Here, we'll go through the migration requirements in a little more detail from the perspective of a Python web application that utilizes the Transcrypt Python-to-JavaScript transpiler.
Installation
The name of the NPM library for Parcel v2 has changed from parcel-bundler
to parcel
. So to install the Parcel v2 JavaScript library, use the following to install it as a development dependency:
$ npm install parcel --save-dev
A new recently released Parcel plugin for Transcrypt that works with Parcel v2 can be installed with:
$ npm install parcel-transformer-transcrypt --save-dev
Configuration
For Parcel to know about the Transcrypt plugin, we need to add a .parcelrc file in the same folder that the package.json file resides in:
Listing 1: .parcelrc
{
"extends": ["@parcel/config-default"],
"transformers": {
"*.py": ["parcel-transformer-transcrypt"]
}
}
This file tells Parcel that anytime it has a file with a .py
extension, that it should pass the file on to the Transcrypt plugin for processing.
The Parcel CLI parameters have changed slightly compared to the previous version. So upgrading an existing project to Parcel v2 may require you to update your NPM scripts in the package.json file.
Most notably, the --log-level
parameter now uses keywords instead of numbers, and the keyword for the output folder has changed from --out-dir
to --dist-dir
. New scripts may look something more like this:
"scripts": {
"start": "NODE_ENV=development parcel --log-level info src/index.html --dist-dir dist/dev --port 8080",
"build": "NODE_ENV=production parcel build --log-level info src/index.html --no-source-maps --dist-dir dist/prod --no-cache"
}
If you are using the Node.js require()
function in your source code to load static resources like images, you may also need to let Parcel know where to find those resource files at bundling time. If the path to the transpiled JavaScript files are no longer located relative to the source file folder after building, add an "alias"
entry to package.json:
"alias": {
"./static/**": "./src/static/$1"
}
This entry will tell Parcel that for any files that are supposed to be in a static/
folder in the current directory, to look for them in the src/static/
folder instead (relative to the root project folder).
Plugin Options
The new Parcel plugin for Transcrypt works pretty much just like the one for the original version of Parcel, with a few additions. The key new features include:
- A configurable output folder (when using Transcrypt 3.9)
- The Parcel file watch works on all transpiled Python files in development mode and not just the entry point
- It checks to make sure that the Python version matches the version of Transcrypt being used
- It doesn’t need patching before using it :-)
Like the previous version, it has a default configuration that can be overridden with an entry in the package.json file for a project:
"parcel-transformer-transcrypt": {
"transcryptVersion": "3.9",
"watchAllFiles": true,
"command": "python -m transcrypt",
"arguments": [
"--nomin",
"--map",
"--verbose"
]
}
The above configuration shows the default values that the Parcel Transcrypt plugin uses. The "transcryptVersion"
, "watchAllFiles"
, "command"
, and "arguments"
keys are all optional. Default values are used for any keys that are not supplied.
If the watchAllFiles
key is missing or set to true
, all Python files that Transcrypt processes will be added to Parcel’s file watch. If this key is set to false
, only the initial entry point file will be watched.
Transcrypt normally puts the files it generates in a folder called __target__
, which is created in the same folder as the source files you are processing. This behavior may not be desirable if you prefer to keep your source code tree free of generated files.
By default, if you are using Transcrypt 3.9, the Parcel transformer will instead put Transcrypt's generated files in a folder named .build
that is created in the project's root folder (where the package.json file resides and where you run npm
commands from). You can override the location of this build folder by adding an argument to the above configuration as shown here:
"arguments": [
"--nomin",
"--map",
"--verbose",
"--outdir src/__target__"
]
The output folder you specify in the arguments should be relative to the project's root folder.
Note that the --outdir
directive is not valid for Transcrypt version 3.7 and is ignored in that case.
Building a Python React demo application with Parcel v2 and the new Python plugin yields the following console output:
Proxy Server
One of the new features of Parcel v2 is the ability of its development server to act as a proxy for back-end data services like a REST API. So now, instead of having to roll your own proxy server with Express.js
and the http-proxy-middleware
packages, you can configure Parcel to provide the same capability with no additional plugins required.
To do so does require creating a simple .proxyrc JSON configuration file:
Listing 2: .proxyrc
{
"/api": {
"target": "http://localhost:8000/",
"pathRewrite": {
"^/api": ""
}
}
}
This configuration would forward any requests having a URL starting with /api
to a backend server listening on port 8000, stripping off the /api
prefix in the process. For example, a request to http://localhost:1234/api/getusers
would be proxied to http://localhost:8000/getusers
Additional Details
The new version of Parcel does not automatically treat <script>
tags as modules, so you must now explicitly specify them as such in order for imports to work correctly in a web browser. You can accomplish this by including a type="module"
attribute in the <script>
tag that loads the application entry point in the index.html file as shown below:
Listing 3: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="app.py"></script>
<title>React to Python</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Most of the changes that need to be made when upgrading from Parcel v1 to Parcel v2 happen in the package.json file. In addition to what was mentioned above, you may have a line like this in your package.json file that was added by default when you ran npm init
:
“main”: “index.js”
While that key was previously ignored in the older version of Parcel, the new version of Parcel will try and treat your web application as a library if it finds it there. To keep Parcel v2 from complaining, that line will need to be removed.
tl;dr
In summary, here are the basic changes needed when moving from Parcel v1 to Parcel v2 for Python web applications:
- Add
type="module"
to entry point script tag in index.html - Add .parcelrc file to let Parcel know how to process
.py
files - Update package.json:
- Remove key entry for
"main": "index.js"
if it exists - Update NPM scripts with new Parcel CLI parameters
- Add
"alias"
key for relative static imports if necessary - Update
"devDependencies"
:-
Change
parcel-bundler
toparcel
-
Change
parcel-plugin-transcrypt
toparcel-transformer-transcrypt
-
Change
parcel-plugin-bundle-visualiser
to@parcel/reporter-bundle-analyzer
-
Remove
express
-
Remove
http-proxy-middleware
-
Change
- Remove key entry for
- If using a proxy server:
- Add a .proxyrc file with the backend server configuration
- Delete dev-server.js and use
npm start
instead ofnpm run dev
for development
Conclusion
One of the admittedly annoying pain points of using the toolchain I outlined in the React to Python book, was the fact that the Transcrypt plugin for Parcel was broken. And because the plugin was not being actively maintained, it had to be patched after installing it. With Parcel v2 and the new Transcrypt plugin developed for it, this is no longer the case. Developing web applications with Python is now even more seamless and productive than it was before.
Resources
Source Code:
https://github.com/JennaSys/rtp_demo/tree/parcel-v2Parcel Website:
https://parceljs.org/Parcel v2 Migration Documentation:
https://parceljs.org/getting-started/migration/Parcel Plugin for Transcrypt:
https://www.npmjs.com/package/parcel-transformer-transcryptCreating React Applications with Python tutorial:
https://leanpub.com/rtptutorialReact to Python Book:
https://pyreact.comTranscrypt Site:
https://www.transcrypt.org
Posted on March 7, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.