Transpile Webpack Plugin: transpiling files with webpack without bundling
Tags: javascript, node, webdev, opensource
Published: 2023-02-04 08:18:39

Did you ever think about transpiling files with webpack without bundling? We use webpack a lot today for web development. It’s so loved because it bundles everything into bundles with limited steps. And the bundles work perfectly on browser. But, in NodeJS, the situation becomes trivial.

In NodeJS, it’s more natural to run separately organized JS files. Source file path related logics are sometimes not avoidable, such as event registering in AWS Lambda, or migrations managing with Sequelize CLI. When this happens and SSR(server side rendering) is requested at the same time, to stick to webpack for its powerful features will look to be the only choice. Though, it also means we have to tackle with the bundles to fit into source file path related logics, which is quite a bit of work.

To ease the situation, Transpile Webpack Plugin([transpile-webpack-plugin](https://github.com/licg9999/transpile-webpack-plugin)) is built. The plugin transpiles input files into output files individually. Let’s check it out.

## Base case

Assuming there are 2 files in dir `src`, one exports a string constant, and the other imports then prints it. A minimal setup is like:

```sh
.
├── src/
│   ├── constants.js
│   └── index.js
├── package.json
└── webpack.config.js
```

Now, we are to transpile files with webpack from dir src into dir dist in a way like:

```sh
.
├── dist/
│   ├── constants.js
│   └── index.js
...
```

First, we need to make sure `webpack`(v5) and `webpack-cli`(v4) installed:

```sh
$ npm i -D webpack webpack-cli
```

Then, install `transpile-webpack-plugin`(v1):

```sh
$ npm i -D transpile-webpack-plugin
```

After that, adjust `webpack.config.js`:

```js
const TranspilePlugin = require('transpile-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
  },
  plugins: [new TranspilePlugin()],
};
```

At last, run `npx webpack`. As a result, input files are collected from files directly or indirectly imported by the entry, then get compiled and ouputted keeping the same directory structure in the output directory. We may verify the output by `node dist/index.js` or exploring the generated code.

## Handling SSR

Supposing the frontend part has been built with webpack and involves transforming or emitting kinds of files or assets like `.tsx` `.css` `.png` `.jpg`, and now want to do server side rendering in the backend part (which is a NodeJS server) but preserve the directory structure of source files at runtime.

We just need to reuse the frontend part webpack config for the backend part, but disable all the asset emitting and add `new TranspilePlugin()` in plugins. The plugin has been [tested](https://github.com/licg9999/transpile-webpack-plugin/tree/master/e2e) to be as much as workable with webpack settings like resolve aliasing, externals, source map, and so on.

## More cases

Several [options](https://github.com/licg9999/transpile-webpack-plugin#options) are available in the plugin. Among them, the most useful ones might be [longestCommonDir](https://github.com/licg9999/transpile-webpack-plugin#longestcommondir) and [extentionMapping](https://github.com/licg9999/transpile-webpack-plugin#extentionmapping).

By default, the plugin uses the common dir of input files as the base dir to evaluate the relative paths of output files in output dir. In case input files might live in some deeply embedded dir and we want to preserve more of the dir in the output, we use longestCommonDir. Given input files `src/server/index.js` `src/server/constants/greeting.js` and output dir `dist`, with this option `undefined`, output files will be `dist/index.js` `dist/constants/greeting.js`. But with this option `'./src'`, output files will be `dist/server/index.js` `dist/server/constants/greeting.js`.

By default, the plugin generates output files with the same extensions as input files. (Btw, NodeJS regards any file with extension that it can’t recognize as a JS file.) In case we want to change the extensions like from `.ts` to `.js`, extentionMapping with `{ '.ts': '.js' }` makes it.

## Issue?

Hoping Transpile Webpack Plugin([transpile-webpack-plugin](https://github.com/licg9999/transpile-webpack-plugin)) makes the development with webpack in NodeJS easier. If any question or any comments, just open them in [transpile-webpack-plugin/issues](https://github.com/licg9999/transpile-webpack-plugin/issues). Discussions are welcomed!