DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Using Parcel v2 and Transcrypt to create web applications with Python
JennaSys
JennaSys

Posted on

Using Parcel v2 and Transcrypt to create web applications with Python

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"]
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
Enter fullscreen mode Exit fullscreen mode

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"
  }
Enter fullscreen mode Exit fullscreen mode

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"
    ]
  }
Enter fullscreen mode Exit fullscreen mode

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__"  
    ]
Enter fullscreen mode Exit fullscreen mode

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:
Screenshot of parcel-transformer-transcrypt processing files

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": ""
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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 to parcel
      • Change parcel-plugin-transcrypt to parcel-transformer-transcrypt
      • Change parcel-plugin-bundle-visualiser to @parcel/reporter-bundle-analyzer
      • Remove express
      • Remove http-proxy-middleware
  • If using a proxy server:
    • Add a .proxyrc file with the backend server configuration
    • Delete dev-server.js and use npm start instead of npm 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

Top comments (0)

Here is a post you might want to check out:

Regex for lazy developers

regex for lazy devs

Sorry for the callout πŸ˜†