jihchi / vite-plugin-rescript

Seamlessly integrate ReScript with Vite
MIT License
102 stars 10 forks source link
rescript rescript-react rollup-plugin vite-plugin

@jihchi/vite-plugin-rescript

Workflows - CI npm package npm download per month npm license

Integrate ReScript with Vite by:

Getting Started

If you are looking for a template to quickly start a project using Vite, ReScript and React, take a look at vitejs-template-react-rescript, the template depends on this plugin.

# npm
npm i -D @jihchi/vite-plugin-rescript

# yarn
yarn add -D @jihchi/vite-plugin-rescript

# pnpm
pnpm i -D @jihchi/vite-plugin-rescript

Configure your vite plugin in vite.config.ts:

import { defineConfig } from 'vite';
import createReScriptPlugin from '@jihchi/vite-plugin-rescript';

export default defineConfig({
  plugins: [createReScriptPlugin()],
});

If you're using require syntax:

const {
  default: createReScriptPlugin,
} = require('@jihchi/vite-plugin-rescript');

Using Loader

The plugin comes with support for loading .res files directly. This is optional and in most cases not necessary, but can be useful in combination with "in-source": false. When using "in-source": false (without the loader), importing local files using relative paths is troublesome. Take for example the following code:

%%raw(`import "./local.css"`)
@module("./local.js") external runSomeJs: unit => unit = "default"

The bundler will fail when reaching this file, since the imports are resolved relative to the generated JS file (which resides in lib), but the .css and .js files are not copied into this directory. By utilizing the loader it no longer fails since the bundler will resolve the files relative to the .res file instead.

Configuration

The loader is configured to support lib/es6 output with .bs.js suffix by default. This can be changed by providing an options object to the plugin:

export default defineConfig({
  plugins: [
    createReScriptPlugin({
      loader: {
        output: './lib/js',
        suffix: '.mjs',
      },
      silent: false,
    }),
  ],
});

Note: It is recommended to use .bs.js suffix since the loader cannot otherwise distinguish between imports of regular JS files and those that were generated by the ReScript compiler.

_Note: Using es6-global module format may cause issues with imports of ReScript node modules, since the paths to the nodemodules will be generated as relative to the lib folder.

Setup

For HTML entry points, it must be imported using inline JS:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="https://github.com/jihchi/vite-plugin-rescript/blob/main/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module">
      import '/src/Main.res';
    </script>
  </body>
</html>

If using Vite with library mode, just use the .res as entry point:

import { defineConfig } from 'vite';
import createReScriptPlugin from '@jihchi/vite-plugin-rescript';

export default defineConfig({
  plugins: [createReScriptPlugin()],
  build: {
    lib: {
      entry: 'src/Main.res',
    },
  },
});

Contributors

Many thanks for your help!

The image of contributors is made with contrib.rocks.